File: parser2.c

package info (click to toggle)
abcmidi 20060422-1
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 1,336 kB
  • ctags: 2,230
  • sloc: ansic: 24,857; makefile: 106
file content (151 lines) | stat: -rw-r--r-- 3,364 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/* parser2.c - further parsing */
/* part of abc2midi and yaps */
/* implements event_info, event_instruction, event_gchord and event_slur */
/* also implements event_reserved */
/* parser2 requires parseabc, but parseabc does not need parser2 */

#include <stdio.h>
#include "abc.h"
#include "parseabc.h"
#include "parser2.h"

void event_info(s)
char* s;
/* An I: field has been encountered. This routine scans the following */
/* text to extract items of the form key=value  */
{
  char* key = NULL;
  char* endkey = NULL;
  char* value = NULL;
  char* endvalue =  NULL;
  char* lastendvalue;
  char* newword = NULL;
  char* lastnewword;
  char* ptr;
  int doval;

  ptr = s;
  doval = 0;
  while (*ptr != '\0') {
    if (doval == 0) {
      /* look for key */
      skipspace(&ptr);
      key = ptr;
      while ((*ptr != '\0') && (*ptr != ' ') && (*ptr != '=')) {
        ptr = ptr + 1;
      };
      endkey = ptr;
      skipspace(&ptr);
      if (*ptr == '=') {
        doval = 1;
        ptr = ptr + 1;
        skipspace(&ptr);
        value = ptr;
        newword = ptr;
        endvalue = NULL;
        lastendvalue = NULL;
      } else {
        key = ptr;
      };
    } else {
      /* look for value */
      skipspace(&ptr);
      while ((*ptr != '\0') && (*ptr != ' ') && (*ptr != '=')) {
        ptr = ptr + 1;
      };
      lastendvalue = endvalue;
      endvalue = ptr;
      skipspace(&ptr);
      lastnewword = newword;
      newword = ptr;
      if (*ptr == '\0') {
        *endkey = '\0';
        *endvalue = '\0';
        event_info_key(key, value);
      } else {
        if (*ptr == '=') {
          *endkey = '\0';
          if (lastendvalue == NULL) {
            event_error("missing key or value in I: field");
          } else {
            *lastendvalue = '\0';
            event_info_key(key, value);
          };
          key = lastnewword;
          endkey = endvalue; 
          doval = 1;
          ptr = ptr + 1;
          skipspace(&ptr);
          value = ptr;
          endvalue = NULL;
          lastendvalue = NULL;
        };
      };
    };
  };
}


static void splitstring(s, sep, handler)
/* breaks up string into fields with sep as the field separator */
/* and calls handler() for each sub-string */
char* s;
char sep;
void (*handler)();
{
  char* out;
  char* p;
  int fieldcoming;

  p = s;
  fieldcoming = 1;
  while (fieldcoming) {
    out = p;
    while ((*p != '\0') && (*p != sep)) p = p + 1;
    if (*p == sep) {
      *p = '\0';
      p = p + 1;
    } else {
      fieldcoming = 0;
    };
    (*handler)(out);
  };
}

void event_gchord(s)
/* handles guitar chords " ... " */
char* s;
{
  splitstring(s, ';', event_handle_gchord);
}

void event_instruction(s)
/* handles a ! ... ! event in the abc */
char* s;
{
  splitstring(s, ';', event_handle_instruction);
}

void event_slur(t)
int t;
/* handles old 's' notation for slur on/slur off */
{
  if (t) {
    event_sluron(1);
  } else {
    event_sluroff(0);
  };
}

void event_reserved(char s)
/* handles H - Z encountered in abc */
{
  char *expansion;

  expansion = lookup_abbreviation(s);
  if (expansion != NULL) {
    event_handle_instruction(expansion);
  } else {
    event_x_reserved(s);
  };
}