File: parser2.c

package info (click to toggle)
abcmidi 20190705-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye, sid
  • size: 2,128 kB
  • sloc: ansic: 30,529; sh: 427; makefile: 104
file content (161 lines) | stat: -rw-r--r-- 3,793 bytes parent folder | download | duplicates (2)
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);
  };
}