-
Notifications
You must be signed in to change notification settings - Fork 15
/
parser2.c
161 lines (150 loc) · 3.7 KB
/
parser2.c
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
152
153
154
155
156
157
158
159
160
161
/* 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. The equal sign is optional
if only one key (eg MIDI, octave, vol, etc.) occurs in the I: field.
Otherwise we need to follow each key with an equal sign so that we
know that the preceding item was a key.
*/
{
char* key;
char* endkey;
char* value;
char* endvalue;
char* lastendvalue;
char* newword;
char* lastnewword;
char* ptr;
char errmsg[80];
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 {
/* [SS] 2015-09-08 */
/* assume only one I: key occurs; grab the rest in value */
*endkey = '\0'; /* end the key ptr */
value = ptr; /* start the value ptr here */
event_info_key(key,value);
return;
};
} 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);
};
}