mirror of
https://github.com/sshlien/abcmidi.git
synced 2025-12-06 06:55:06 +00:00
161 lines
3.5 KiB
C
161 lines
3.5 KiB
C
/* 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;
|
|
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);
|
|
};
|
|
}
|