1 /*
2 * Generic ABC parser.
3 *
4 * Copyright (C) 1998-2018 Jean-François Moine
5 * Adapted from abc2ps, Copyright (C) 1996, 1997 Michael Methfessel
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12
13 #include "config.h"
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include <ctype.h>
18
19 #include "abcm2ps.h"
20
21 /* global values */
22 int severity; /* error severity */
23
24 static short ulen; /* unit note length set by M: or L: */
25 static short meter; /* upper value of time sig for n-plets */
26 static unsigned char microscale; /* current microtone scale */
27 static signed char vover; /* voice overlay (1: single bar, -1: multi-bar */
28 static char lyric_started; /* lyric started */
29 static char *gchord; /* guitar chord */
30 static struct decos dc; /* decorations */
31 static struct SYMBOL *deco_start; /* 1st note of the line for d: / s: */
32 static struct SYMBOL *deco_cont; /* current symbol when d: / s: continuation */
33
34 static int g_abc_vers, g_ulen, g_microscale;
35 static char g_char_tb[128];
36 static char *g_deco_tb[128]; /* global decoration names */
37 static unsigned short g_micro_tb[MAXMICRO]; /* global microtone values */
38
39 static char *abc_fn; /* current source file name */
40 static int linenum; /* current source line number */
41 static int colnum; /* current source column number */
42 static char *abc_line; /* line being parsed */
43 static struct SYMBOL *last_sym; /* last symbol for errors */
44
45 static short nvoice; /* number of voices (0..n-1) */
46 struct VOICE_S *curvoice; /* current voice while parsing */
47
48 struct parse parse;
49
50 /* char table for note line parsing */
51 #define CHAR_BAD 0
52 #define CHAR_IGN 1
53 #define CHAR_NOTE 2
54 #define CHAR_GR_ST 3
55 #define CHAR_DECO 4
56 #define CHAR_GCHORD 5
57 #define CHAR_BSLASH 6
58 #define CHAR_OBRA 7
59 #define CHAR_BAR 8
60 #define CHAR_OPAR 9
61 #define CHAR_VOV 10
62 #define CHAR_SPAC 11
63 #define CHAR_MINUS 12
64 #define CHAR_CPAR 13
65 #define CHAR_BRHY 14
66 #define CHAR_DECOS 15
67 #define CHAR_SLASH 16
68 #define CHAR_GR_EN 17
69 #define CHAR_LINEBREAK 18
70 static char char_tb[256] = {
71 0, 0, 0, 0, 0, 0, 0, 0, /* 00 - 07 */
72 0, CHAR_SPAC, CHAR_LINEBREAK, 0, 0, 0, 0, 0, /* 08 - 0f */
73 0, 0, 0, 0, 0, 0, 0, 0, /* 10 - 17 */
74 0, 0, 0, 0, 0, 0, 0, 0, /* 18 - 1f */
75 CHAR_SPAC, CHAR_DECOS, CHAR_GCHORD, CHAR_BAD, /* (sp) ! " # */
76 CHAR_BAD, CHAR_BAD, CHAR_VOV, CHAR_BAD, /* $ % & ' */
77 CHAR_OPAR, CHAR_CPAR, CHAR_BAD, CHAR_DECOS, /* ( ) * + */
78 CHAR_BAD, CHAR_MINUS, CHAR_DECO, CHAR_SLASH, /* , - . / */
79 CHAR_BAD, CHAR_BAD, CHAR_BAD, CHAR_BAD, /* 0 1 2 3 */
80 CHAR_BAD, CHAR_BAD, CHAR_BAD, CHAR_BAD, /* 4 5 6 7 */
81 CHAR_BAD, CHAR_BAD, CHAR_BAR, CHAR_BAD, /* 8 9 : ; */
82 CHAR_BRHY, CHAR_NOTE, CHAR_BRHY, CHAR_BAD, /* < = > ? */
83 CHAR_BAD, CHAR_NOTE, CHAR_NOTE, CHAR_NOTE, /* @ A B C */
84 CHAR_NOTE, CHAR_NOTE, CHAR_NOTE, CHAR_NOTE, /* D E F G */
85 CHAR_DECO, CHAR_DECO, CHAR_DECO, CHAR_DECO, /* H I J K */
86 CHAR_DECO, CHAR_DECO, CHAR_DECO, CHAR_DECO, /* L M N O */
87 CHAR_DECO, CHAR_DECO, CHAR_DECO, CHAR_DECO, /* P Q R S */
88 CHAR_DECO, CHAR_DECO, CHAR_DECO, CHAR_DECO, /* T U V W */
89 CHAR_NOTE, CHAR_DECO, CHAR_NOTE, CHAR_OBRA, /* X Y Z [ */
90 CHAR_BSLASH, CHAR_BAR, CHAR_NOTE, CHAR_NOTE, /* \ ] ^ _ */
91 CHAR_IGN, CHAR_NOTE, CHAR_NOTE, CHAR_NOTE, /* ` a b c */
92 CHAR_NOTE, CHAR_NOTE, CHAR_NOTE, CHAR_NOTE, /* d e f g */
93 CHAR_DECO, CHAR_DECO, CHAR_DECO, CHAR_DECO, /* h i j k */
94 CHAR_DECO, CHAR_DECO, CHAR_DECO, CHAR_DECO, /* l m n o */
95 CHAR_DECO, CHAR_DECO, CHAR_DECO, CHAR_DECO, /* p q r s */
96 CHAR_DECO, CHAR_DECO, CHAR_DECO, CHAR_DECO, /* t u v w */
97 CHAR_NOTE, CHAR_NOTE, CHAR_NOTE, CHAR_GR_ST, /* x y z { */
98 CHAR_BAR, CHAR_GR_EN, CHAR_DECO, CHAR_BAD, /* | } ~ (del) */
99 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 80 - 8f */
100 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 90 - 9f */
101 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* a0 - af */
102 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* b0 - bf */
103 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* c0 - cf */
104 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* d0 - df */
105 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* e0 - ef */
106 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* f0 - ff */
107 };
108
109 static const char all_notes[] = "CDEFGABcdefgab";
110
111 static int parse_info(char *p);
112 static char *parse_gchord(char *p);
113 static int parse_line(char *p);
114 static char *parse_note(char *p,
115 int flags);
116 static void syntax(char *msg, char *q);
117 static void vover_new(void);
118
119 /* -- abcMIDI like errors -- */
print_error(char * s,int col)120 static void print_error(char *s, int col)
121 {
122 if (col >= 0)
123 fprintf(stderr, "%s:%d:%d: error: %s\n", abc_fn, linenum, col, s);
124 else
125 fprintf(stderr, "%s:%d: error: %s\n", abc_fn, linenum, s);
126 }
127
128 /* -- new symbol -- */
abc_new(int type,char * text)129 static struct SYMBOL *abc_new(int type, char *text)
130 {
131 struct SYMBOL *s;
132
133 s = getarena(sizeof(struct SYMBOL));
134 memset(s, 0, sizeof(struct SYMBOL));
135 if (text) {
136 s->text = getarena(strlen(text) + 1);
137 strcpy(s->text, text);
138 }
139 if (!parse.last_sym) {
140 parse.first_sym = s;
141 } else {
142 if ((s->abc_next = parse.last_sym->abc_next) != NULL)
143 s->abc_next->abc_prev = s;
144 parse.last_sym->abc_next = s;
145 s->abc_prev = parse.last_sym;
146 }
147 last_sym = parse.last_sym = s;
148 s->abc_type = type;
149 s->state = parse.abc_state;
150 s->fn = abc_fn;
151 s->linenum = linenum;
152 s->colnum = colnum;
153 return s;
154 }
155
156 /* -- parse an ABC line -- */
abc_parse(char * p,char * fname,int ln)157 void abc_parse(char *p, char *fname, int ln)
158 {
159 abc_fn = fname;
160 linenum = ln;
161 abc_line = p;
162
163 /* parse the music line */
164 switch (parse_line(p)) {
165 case 2: /* start of tune (X:) */
166 g_abc_vers = parse.abc_vers;
167 g_ulen = ulen;
168 g_microscale = microscale;
169
170 meter = 2;
171 memcpy(g_char_tb, char_tb, sizeof g_char_tb);
172 memcpy(g_deco_tb, parse.deco_tb, sizeof g_deco_tb);
173 memcpy(g_micro_tb, parse.micro_tb, sizeof g_micro_tb);
174 break;
175 case 1: /* end of tune */
176 if (parse.first_sym) {
177 do_tune();
178 parse.first_sym = parse.last_sym = NULL;
179 }
180 parse.abc_state = ABC_S_GLOBAL;
181 parse.abc_vers = g_abc_vers;
182 ulen = g_ulen;
183 microscale = g_microscale;
184 memcpy(char_tb, g_char_tb, sizeof g_char_tb);
185 memcpy(parse.deco_tb, g_deco_tb, sizeof parse.deco_tb);
186 memcpy(parse.micro_tb, g_micro_tb, sizeof parse.micro_tb);
187 lvlarena(0);
188 if (dc.n > 0)
189 syntax("Decoration without symbol", 0);
190 dc.n = 0;
191 break;
192 }
193 }
194
195 /* treat the end of file */
abc_eof(void)196 void abc_eof(void)
197 {
198 // if (parse.abc_state == ABC_S_HEAD)
199 // severity = 1;
200 do_tune();
201 parse.first_sym = parse.last_sym = NULL;
202 if (parse.abc_state != ABC_S_GLOBAL) {
203 parse.abc_vers = g_abc_vers;
204 ulen = g_ulen;
205 microscale = g_microscale;
206 memcpy(char_tb, g_char_tb, sizeof g_char_tb);
207 }
208 }
209
210 /* -- treat the broken rhythm '>' and '<' -- */
broken_rhythm(struct SYMBOL * s,int num)211 static void broken_rhythm(struct SYMBOL *s,
212 int num) /* >0: do dot, <0: do half */
213 {
214 struct notes *notes = &s->u.note;
215 int l, m, n;
216
217 num *= 2;
218 if (num > 0) {
219 if (num == 6)
220 num = 8;
221 n = num * 2 - 1;
222 for (m = 0; m <= s->nhd; m++)
223 notes->notes[m].len = (notes->notes[m].len * n) / num;
224 } else {
225 n = -num;
226 if (n == 6)
227 n = 8;
228 for (m = 0; m <= s->nhd; m++)
229 notes->notes[m].len /= n;
230 }
231 l = notes->notes[0].len;
232 for (m = 1; m <= s->nhd; m++)
233 if (notes->notes[m].len < l)
234 l = notes->notes[m].len;
235 }
236
237 /* -- check for the '!' as end of line (ABC2Win) -- */
check_nl(char * p)238 static int check_nl(char *p)
239 {
240 while (*p != '\0') {
241 switch (*p++) {
242 case '!':
243 return 0;
244 case '|':
245 case '[':
246 case ':':
247 case ']':
248 case ' ':
249 case '\t':
250 return 1;
251 }
252 }
253 return 1;
254 }
255
256 /* -- parse extra K: or V: definitions (clef, octave and microscale -- */
parse_extra(char * p,char ** p_name,char ** p_middle,char ** p_stlines,char ** p_scale,char ** p_octave,char ** p_cue,char ** p_map)257 static char *parse_extra(char *p,
258 char **p_name,
259 char **p_middle,
260 char **p_stlines,
261 char **p_scale,
262 char **p_octave,
263 char **p_cue,
264 char **p_map)
265 {
266 for (;;) {
267 if (strncmp(p, "clef=", 5) == 0
268 || strncmp(p, "bass", 4) == 0
269 || strncmp(p, "treble", 6) == 0
270 || strncmp(p, "alto", 4) == 0
271 || strncmp(p, "tenor", 5) == 0
272 || strncmp(p, "perc", 4) == 0) {
273 if (*p_name)
274 syntax("Double clef name", p);
275 *p_name = p;
276 } else if (strncmp(p, "microscale=", 11) == 0
277 || strncmp(p, "uscale=", 7) == 0) {
278 int i;
279
280 p += p[0] == 'm' ? 11 : 7;
281 i = atoi(p);
282 if (i < 4 || i >= 256)
283 syntax("Invalid value in microscale=", p);
284 else
285 microscale = i;
286 } else if (strncmp(p, "middle=", 7) == 0
287 || strncmp(p, "m=", 2) == 0) {
288 if (*p_middle)
289 syntax("Double clef middle", p);
290 *p_middle = p + (p[1] == '=' ? 2 : 7);
291 } else if (strncmp(p, "octave=", 7) == 0) {
292 if (*p_octave)
293 syntax("Double octave=", p);
294 *p_octave = p + 7;
295 } else if (strncmp(p, "stafflines=", 11) == 0) {
296 int l;
297 char *q;
298
299 if (*p_stlines)
300 syntax("Double stafflines", p);
301 p += 11;
302 if (isdigit((unsigned char) *p)) {
303 switch (atoi(p)) {
304 case 0: *p_stlines = "..."; break;
305 case 1: *p_stlines = "..|"; break;
306 case 2: *p_stlines = ".||"; break;
307 case 3: *p_stlines = ".|||"; break;
308 case 4: *p_stlines = "||||"; break;
309 case 5: *p_stlines = "|||||"; break;
310 case 6: *p_stlines = "||||||"; break;
311 case 7: *p_stlines = "|||||||"; break;
312 case 8: *p_stlines = "||||||||"; break;
313 default:
314 syntax("Bad number of lines", p);
315 break;
316 }
317 } else {
318 q = p;
319 while (!isspace((unsigned char) *p) && *p != '\0')
320 p++;
321 l = p - q;
322 *p_stlines = getarena(l + 1);
323 strncpy(*p_stlines, q, l);
324 (*p_stlines)[l] = '\0';
325 }
326 } else if (strncmp(p, "staffscale=", 11) == 0) {
327 if (*p_scale)
328 syntax("Double staffscale", p);
329 *p_scale = p + 11;
330 } else if (strncmp(p, "cue=", 4) == 0) {
331 if (*p_cue)
332 syntax("Double cue", p);
333 *p_cue = p + 4;
334 } else if (strncmp(p, "map=", 4) == 0) {
335 if (*p_map)
336 syntax("Double map", p);
337 *p_map = p + 4;
338 // } else if (strncmp(p, "transpose=", 10) == 0
339 // || strncmp(p, "t=", 2) == 0) {
340 // ; /* ignored - abcMIDI */
341 } else {
342 break;
343 }
344 while (!isspace((unsigned char) *p) && *p != '\0')
345 p++;
346 while (isspace((unsigned char) *p))
347 p++;
348 if (*p == '\0')
349 break;
350 }
351 return p;
352 }
353
354 /* -- parse a decoration 'xxx<decosep>' -- */
get_deco(char * p,unsigned char * p_dc)355 static char *get_deco(char *p,
356 unsigned char *p_dc)
357 {
358 char *q, sep, **t;
359 unsigned i, l;
360
361 *p_dc = 0;
362 q = p;
363 sep = q[-1];
364 if (char_tb[(unsigned char) sep] == CHAR_DECOS) {
365 if (sep == '+') {
366 if (*p == '+' && p[1] == '+')
367 p++; /* special case "+++" */
368 }
369 } else {
370 sep = '\0'; /* Barfly U: */
371 }
372 while (*p != sep) {
373 if (*p == '\0') {
374 syntax("Decoration not terminated", q);
375 return p;
376 }
377 p++;
378 }
379 l = p - q;
380 if (*p == sep)
381 p++;
382 for (i = 1, t = &parse.deco_tb[1];
383 *t && i < DC_NAME_SZ;
384 i++, t++) {
385 if (strlen(*t) == l
386 && strncmp(*t, q, l) == 0) {
387 *p_dc = i + 128;
388 return p;
389 }
390 }
391
392 /* new decoration */
393 if (i < DC_NAME_SZ) {
394 // if (parse.abc_state != ABC_S_GLOBAL)
395 // lvlarena(0);
396 *t = getarena(l + 1);
397 // if (parse.abc_state != ABC_S_GLOBAL)
398 // lvlarena(1);
399 memcpy(*t, q, l);
400 (*t)[l] = '\0';
401 *p_dc = i + 128;
402 } else {
403 syntax("Too many decoration types", q);
404 }
405 return p;
406 }
407
408 /* -- parse a list of accidentals (K:) -- */
parse_acc(char * p,struct SYMBOL * s)409 static char *parse_acc(char *p,
410 struct SYMBOL *s)
411 {
412 int pit, acc;
413 unsigned nacc;
414
415 nacc = 0;
416 for (;;) {
417 if (nacc >= sizeof s->u.key.pits) {
418 syntax("Too many accidentals", p);
419 break;
420 }
421 p = parse_acc_pit(p, &pit, &acc);
422 if (acc < 0)
423 break;
424 s->u.key.pits[nacc] = pit;
425 s->u.key.accs[nacc++] = acc;
426 while (isspace((unsigned char) *p))
427 p++;
428 if (*p == '\0')
429 break;
430 if (*p != '^' && *p != '_' && *p != '=')
431 break;
432 }
433 s->u.key.microscale = microscale;
434 if (s->u.key.empty != 2)
435 s->u.key.nacc = nacc;
436 return p;
437 }
438
439 /* -- parse a clef (K: or V:) -- */
parse_clef(struct SYMBOL * s,char * name,char * middle)440 static void parse_clef(struct SYMBOL *s,
441 char *name,
442 char *middle)
443 {
444 int clef = -1;
445 int transpose = 0;
446 int clef_line = 2;
447 char *warn = NULL;
448 char str[80];
449
450 str[0] = '\0';
451 if (name && strncmp(name, "clef=", 5) == 0) {
452 name += 5;
453 switch (*name) {
454 case '\"':
455 name = get_str(str, name, sizeof str);
456 s->u.clef.name = getarena(strlen(str) + 1);
457 strcpy(s->u.clef.name, str);
458 clef = TREBLE;
459 break;
460 case 'g':
461 warn = name;
462 transpose = -7;
463 case 'G':
464 clef = TREBLE;
465 break;
466 case 'f':
467 warn = name;
468 transpose = -14;
469 clef = BASS;
470 clef_line = 4;
471 break;
472 case 'F':
473 if (name[1] == ',') /* abc2.1.1 clef=F == clef=F, */
474 transpose = -7;
475 clef = BASS;
476 clef_line = 4;
477 break;
478 case 'c':
479 warn = name;
480 transpose = -7;
481 case 'C':
482 clef = ALTO;
483 clef_line = 3;
484 break;
485 case 'P':
486 clef = PERC;
487 clef_line = 3;
488 break;
489 }
490 if (clef >= 0) {
491 name++;
492 if (*name == ',' || *name== '\'')
493 warn = name;
494 while (*name == ',') {
495 transpose += 7;
496 name++;
497 }
498 while (*name == '\'') {
499 transpose -= 7;
500 name++;
501 }
502 }
503 }
504 if (name && clef < 0) {
505 if (!strncmp(name, "bass", 4)) {
506 clef = BASS;
507 clef_line = 4;
508 s->u.clef.check_pitch = 1;
509 name += 4;
510 } else if (!strncmp(name, "treble", 6)) {
511 clef = TREBLE;
512 name += 6;
513 } else if (!strncmp(name, "alto", 4)
514 || !strncmp(name, "tenor", 5)) {
515 clef = ALTO;
516 clef_line = *name == 'a' ? 3 : 4;
517 s->u.clef.check_pitch = 1;
518 if (*name == 'a')
519 name += 4;
520 else
521 name += 5;
522 } else if (!strncmp(name, "perc", 4)) {
523 clef = PERC;
524 clef_line = 3;
525 name += 4;
526 } else if (!strncmp(name, "auto", 4)) {
527 clef = AUTOCLEF;
528 name += 4;
529 } else if (strncmp(name, "none", 4) == 0) {
530 clef = TREBLE;
531 s->u.clef.invis = 1;
532 s->flags |= ABC_F_INVIS;
533 name += 4;
534 } else {
535 syntax("Unknown clef", name);
536 clef = TREBLE;
537 }
538 }
539
540 if (clef >= 0) {
541 if (isdigit((unsigned char) *name))
542 clef_line = *name++ - '0';
543 if (name[1] == '8') {
544 switch (*name) {
545 case '^':
546 transpose -= 7;
547 case '+':
548 s->u.clef.octave = 1;
549 break;
550 case '_':
551 transpose += 7;
552 case '-':
553 s->u.clef.octave = -1;
554 break;
555 }
556 }
557 }
558
559 if (middle) {
560 int pit, acc, l;
561 static const char line_tb[7] =
562 {ALTO, TREBLE, ALTO, BASS, ALTO, BASS, ALTO};
563
564 warn = middle;
565 /* 'middle=<note pitch>' */
566 parse_acc_pit(middle, &pit, &acc);
567 if (acc < 0) // if error
568 pit = 22;
569
570 if (clef < 0)
571 clef = line_tb[(pit + 7) % 7];
572
573 switch (clef) {
574 default:
575 l = 20 + 4;
576 break;
577 case ALTO:
578 l = 16 + 4;
579 break;
580 case BASS:
581 l = 12 + 4;
582 break;
583 }
584 clef_line = (l - pit + 28) % 7;
585 if (clef_line & 1) {
586 syntax("Bad 'middle' value for the clef", middle);
587 pit++;
588 }
589 clef_line = clef_line / 2 + 1;
590
591 transpose = l - (clef_line - 1) * 2 - pit;
592 s->u.clef.check_pitch = 0;
593 }
594
595 s->u.clef.type = clef;
596 s->u.clef.line = clef_line;
597 s->u.clef.transpose = transpose;
598 if (warn) {
599 int sev_sav;
600
601 sev_sav = severity;
602 syntax("Warning: Deprecated or non-standard item", warn);
603 severity = sev_sav;
604 }
605 }
606
607 /* get the octave= value */
parse_octave(char * p)608 static int parse_octave(char *p)
609 {
610 int oct;
611
612 if (p) {
613 oct = 1;
614 if (*p == '-') {
615 oct = -1;
616 p++;
617 }
618 if (*p >= '0' && *p <= '4')
619 return oct * (*p - '0');
620 syntax("Bad octave value", p);
621 }
622 return NO_OCTAVE;
623 }
624
625 /* -- parse a 'K:' -- */
parse_key(char * p,struct SYMBOL * s)626 static void parse_key(char *p,
627 struct SYMBOL *s)
628 {
629 int sf, empty, instr;
630 // int mode;
631 char *clef_name, *clef_middle, *clef_stlines, *clef_scale;
632 char *p_octave, *p_cue, *p_map;
633
634 // set important default values
635 // s->u.key.stafflines = "|||||";
636 s->u.key.octave = NO_OCTAVE;
637
638 if (*p == '\0') {
639 s->u.key.empty = 1;
640 return;
641 }
642 sf = 0;
643 // mode = 0;
644 empty = 0;
645 instr = 0;
646 switch (*p++) {
647 case 'F': sf = -1; break;
648 case 'B': sf++;
649 case 'E': sf++;
650 case 'A': sf++;
651 case 'D': sf++;
652 case 'G': sf++;
653 case 'C': break;
654 case 'H':
655 if (*p == 'P') {
656 instr = K_HP;
657 p++;
658 } else if (*p == 'p') {
659 instr = K_Hp;
660 sf = 2;
661 p++;
662 } else {
663 syntax("Unknown bagpipe-like key", p);
664 }
665 break;
666 case 'P':
667 instr = K_DRUM;
668 p++;
669 break;
670 case 'n':
671 if (strncmp(p, "one", 3) == 0) { // none
672 empty = 2;
673 p += 3;
674 while (isspace((unsigned char) *p))
675 p++;
676 if (*p == '\0') {
677 s->u.key.empty = empty;
678 return;
679 }
680 break;
681 }
682 // fall thru
683 default:
684 p--;
685 empty = 1;
686 break;
687 }
688 s->u.key.empty = empty;
689
690 if (!empty) {
691 if (*p == '#') {
692 sf += 7;
693 p++;
694 } else if (*p == 'b') {
695 sf -= 7;
696 p++;
697 }
698 while (isspace((unsigned char) *p))
699 p++;
700 switch (*p) {
701 case 'a':
702 case 'A':
703 if (strncasecmp(p, "aeo", 3) == 0) {
704 sf -= 3;
705 // mode = 5;
706 break;
707 }
708 goto unk;
709 case 'd':
710 case 'D':
711 if (strncasecmp(p, "dor", 3) == 0) {
712 sf -= 2;
713 // mode = 1;
714 break;
715 }
716 goto unk;
717 case 'i':
718 case 'I':
719 if (strncasecmp(p, "ion", 3) == 0) {
720 // mode = 0;
721 break;
722 }
723 goto unk;
724 case 'l':
725 case 'L':
726 if (strncasecmp(p, "loc", 3) == 0) {
727 sf -= 5;
728 // mode = 6;
729 break;
730 }
731 if (strncasecmp(p, "lyd", 3) == 0) {
732 sf += 1;
733 // mode = 3;
734 break;
735 }
736 goto unk;
737 case 'm':
738 case 'M':
739 if (strncasecmp(p, "maj", 3) == 0)
740 break;
741 if (strncasecmp(p, "mix", 3) == 0) {
742 sf -= 1;
743 // mode = 4;
744 break;
745 }
746 if (strncasecmp(p, "min", 3) == 0
747 || !isalpha((unsigned char) p[1])) { /* 'm' alone */
748 sf -= 3;
749 // mode = 5;
750 break;
751 }
752 goto unk;
753 case 'p':
754 case 'P':
755 if (strncasecmp(p, "phr", 3) == 0) {
756 sf -= 4;
757 // mode = 2;
758 break;
759 }
760 goto unk;
761 default:
762 unk:
763 empty = 1; // (local value)
764 break;
765 }
766 if (!empty) {
767 while (isalpha((unsigned char) *p))
768 p++;
769 while (isspace((unsigned char) *p))
770 p++;
771 }
772
773 // [exp] accidentals
774 if (strncmp(p, "exp ", 4) == 0) {
775 p += 4;
776 while (isspace((unsigned char) *p))
777 p++;
778 if (*p == '\0')
779 syntax("no accidental after 'exp'", p);
780 s->u.key.exp = 1;
781 }
782 if (s->u.key.exp && strncmp(p, "none", 4) == 0) {
783 sf = 0;
784 p += 4;
785 while (isspace((unsigned char) *p))
786 p++;
787 } else switch (*p) {
788 case '^':
789 case '_':
790 case '=':
791 p = parse_acc(p, s); /* accidentals */
792 break;
793 }
794 }
795
796 if (sf > 7 || sf < -7) {
797 syntax("Too many sharps/flats", p);
798 if (sf > 0)
799 sf -= 12;
800 else
801 sf += 12;
802 }
803
804 // extra parameters
805 clef_name = clef_middle = clef_stlines = clef_scale = NULL;
806 p_octave = p_cue = p_map = NULL;
807 parse_extra(p, &clef_name, &clef_middle, &clef_stlines,
808 &clef_scale, &p_octave, &p_cue, &p_map);
809
810 s->u.key.sf = sf;
811 // s->u.key.mode = mode;
812 s->u.key.instr = instr;
813 s->u.key.octave = parse_octave(p_octave);
814 if (p_cue) {
815 if (strncmp(p_cue, "on", 2) == 0)
816 s->u.key.cue = 1;
817 else
818 s->u.key.cue = -1;
819 }
820 if (clef_stlines)
821 s->u.key.stafflines = clef_stlines;
822 if (clef_scale) {
823 float sc;
824
825 sc = atof(clef_scale);
826 if (sc >= 0.5 && sc <= 3)
827 s->u.key.staffscale = sc;
828 else
829 syntax("Bad value of staffscale", clef_scale);
830 }
831 if (clef_name || clef_middle) {
832 s = abc_new(ABC_T_CLEF, NULL);
833 parse_clef(s, clef_name, clef_middle);
834 }
835 if (p_map) {
836 strcpy(tex_buf, "%%voicemap ");
837 get_str(&tex_buf[11], p_map, TEX_BUF_SZ - 12);
838 abc_new(ABC_T_PSCOM, tex_buf);
839 }
840 }
841
842 /* -- set default length from 'L:' -- */
get_len(char * p,struct SYMBOL * s)843 static char *get_len(char *p,
844 struct SYMBOL *s)
845 {
846 int l1, l2, d;
847 char *error_txt = NULL;
848
849 if (strcmp(p, "auto") == 0) { /* L:auto */
850 ulen = 15120; // 2*2*2*2*3*3*3*5*7
851 s->u.length.base_length = -1;
852 return error_txt;
853 }
854 l1 = 0;
855 l2 = 1;
856 if (sscanf(p, "%d /%d ", &l1, &l2) != 2
857 || l1 == 0) {
858 s->u.length.base_length = ulen ? ulen : BASE_LEN / 8;
859 return "Bad unit note length: unchanged";
860 }
861
862 if (l2 == 0) {
863 error_txt = "Bad length divisor, set to 4";
864 l2 = 4;
865 }
866 d = BASE_LEN / l2;
867 if (d * l2 != BASE_LEN) {
868 error_txt = "Length incompatible with BASE, using 1/8";
869 d = BASE_LEN / 8;
870 } else {
871 d *= l1;
872 if (l1 != 1
873 || (l2 & (l2 - 1))) {
874 error_txt = "Incorrect unit note length, using 1/8";
875 d = BASE_LEN / 8;
876 }
877 }
878 s->u.length.base_length = d;
879 return error_txt;
880 }
881
882 /* -- parse a 'M:' -- */
parse_meter(char * p,struct SYMBOL * s)883 static char *parse_meter(char *p,
884 struct SYMBOL *s)
885 {
886 int m1, m2, d, wmeasure, nm, in_parenth;
887 unsigned i;
888 char *q;
889 static char top_err[] = "Cannot identify meter top";
890
891 if (*p == '\0')
892 return "Empty meter string";
893 nm = 0;
894 in_parenth = 0;
895 m1 = 0;
896 if (strncmp(p, "none", 4) == 0) {
897 p += 4; /* no meter */
898 wmeasure = 1; /* simplify measure numbering and MREST conversion */
899 } else {
900 wmeasure = 0;
901 while (*p != '\0') {
902 if (*p == '=')
903 break;
904 if (nm >= MAX_MEASURE)
905 return "Too many values in M:";
906 switch (*p) {
907 case 'C':
908 s->u.meter.meter[nm].top[0] = *p++;
909 if (*p == '|')
910 s->u.meter.meter[nm].top[1] = *p++;
911 m1 = 4;
912 m2 = 4;
913 break;
914 case 'c':
915 case 'o':
916 if (*p == 'c')
917 m1 = 4;
918 else
919 m1 = 3;
920 m2 = 4;
921 s->u.meter.meter[nm].top[0] = *p++;
922 if (*p == '.')
923 s->u.meter.meter[nm].top[1] = *p++;
924 break;
925 case '(':
926 if (p[1] == '(') { /* "M:5/4 ((2+3)/4)" */
927 in_parenth = 1;
928 s->u.meter.meter[nm++].top[0] = *p++;
929 }
930 q = p + 1;
931 while (*q != '\0') {
932 if (*q == ')' || *q == '/')
933 break;
934 q++;
935 }
936 if (*q == ')' && q[1] == '/') { /* "M:5/4 (2+3)/4" */
937 p++; /* remove the parenthesis */
938 continue;
939 } /* "M:5 (2+3)" */
940 /* fall thru */
941 case ')':
942 in_parenth = *p == '(';
943 s->u.meter.meter[nm++].top[0] = *p++;
944 continue;
945 default:
946 if (sscanf(p, "%d", &m1) != 1
947 || m1 <= 0)
948 return top_err;
949 i = 0;
950 m2 = 2; /* default when no bottom value */
951 for (;;) {
952 while (isdigit((unsigned char) *p)
953 && i < sizeof s->u.meter.meter[0].top)
954 s->u.meter.meter[nm].top[i++] = *p++;
955 if (*p == ')') {
956 if (p[1] != '/')
957 break;
958 p++;
959 }
960 if (*p == '/') {
961 p++;
962 if (sscanf(p, "%d", &m2) != 1
963 || m2 <= 0)
964 return "Cannot identify meter bottom";
965 i = 0;
966 while (isdigit((unsigned char) *p)
967 && i < sizeof s->u.meter.meter[0].bot)
968 s->u.meter.meter[nm].bot[i++] = *p++;
969 break;
970 }
971 if (*p != ' ' && *p != '+')
972 break;
973 if (*p == '\0' || p[1] == '(') /* "M:5 (2/4+3/4)" */
974 break;
975 if (i < sizeof s->u.meter.meter[0].top)
976 s->u.meter.meter[nm].top[i++] = *p++;
977 if (sscanf(p, "%d", &d) != 1
978 || d <= 0)
979 return top_err;
980 if (p[-1] == ' ') {
981 if (d > m1)
982 m1 = d;
983 } else {
984 m1 += d;
985 }
986 }
987 break;
988 }
989 if (!in_parenth)
990 wmeasure += m1 * BASE_LEN / m2;
991 nm++;
992 if (*p == ' ')
993 p++;
994 else if (*p == '+')
995 s->u.meter.meter[nm++].top[0] = *p++;
996 }
997 }
998 meter = m1;
999 if (*p == '=') {
1000 if (sscanf(++p, "%d/%d", &m1, &m2) != 2
1001 || m1 <= 0
1002 || m2 <= 0)
1003 return "Cannot identify meter explicit duration";
1004 wmeasure = m1 * BASE_LEN / m2;
1005 s->u.meter.expdur = 1;
1006 }
1007 s->u.meter.wmeasure = wmeasure;
1008 s->u.meter.nmeter = nm;
1009
1010 /* in the tune header, change the unit note length */
1011 if (parse.abc_state == ABC_S_HEAD && ulen == 0) {
1012 if (wmeasure >= BASE_LEN * 3 / 4
1013 || wmeasure <= 1)
1014 ulen = BASE_LEN / 8;
1015 else
1016 ulen = BASE_LEN / 16;
1017 }
1018 return 0;
1019 }
1020
1021 /* -- get a possibly quoted string -- */
get_str(char * d,char * s,int maxlen)1022 char *get_str(char *d, /* destination */
1023 char *s, /* source */
1024 int maxlen) /* max length */
1025 {
1026 char c;
1027
1028 maxlen--; /* have place for the EOS */
1029 while (isspace((unsigned char) *s))
1030 s++;
1031 if (*s == '"') {
1032 s++;
1033 while ((c = *s) != '\0') {
1034 if (c == '"') {
1035 s++;
1036 break;
1037 }
1038 if (c == '\\') {
1039 if (--maxlen > 0)
1040 *d++ = c;
1041 c = *++s;
1042 }
1043 if (--maxlen > 0)
1044 *d++ = c;
1045 s++;
1046 }
1047 } else {
1048 while ((c = *s) != '\0') {
1049 if (isspace((unsigned char) c))
1050 break;
1051 if (--maxlen > 0)
1052 *d++ = c;
1053 s++;
1054 }
1055 }
1056 *d = '\0';
1057 while (isspace((unsigned char) *s))
1058 s++;
1059 return s;
1060 }
1061
1062 /* -- parse a tempo (Q:) -- */
parse_tempo(char * p,struct SYMBOL * s)1063 static char *parse_tempo(char *p,
1064 struct SYMBOL *s)
1065 {
1066 char c, str[80];
1067 int i, l, n, top, bot;
1068
1069 /* string before */
1070 if (*p == '"') {
1071 p = get_str(str, p, sizeof str);
1072 s->u.tempo.str1 = getarena(strlen(str) + 1);
1073 strcpy(s->u.tempo.str1, str);
1074 }
1075
1076 /* beat */
1077 if (*p == 'C' || *p == 'c'
1078 || *p == 'L' || *p == 'l') {
1079 s->u.tempo.beats[0] = ulen;
1080 if (parse.abc_vers >= (2 << 16))
1081 syntax("Deprecated Q: value", p);
1082 p++;
1083 while (isspace((unsigned char) *p))
1084 p++;
1085 if (*p != '=')
1086 goto inval;
1087 c = '=';
1088 p--;
1089 } else if (isdigit((unsigned char) *p)) {
1090 if (strchr(p, '/') != NULL) {
1091 i = 0;
1092 while (isdigit((unsigned char) *p)) {
1093 if (sscanf(p, "%d/%d%n", &top, &bot, &n) != 2
1094 || bot <= 0)
1095 goto inval;
1096 l = (BASE_LEN * top) / bot;
1097 if (l <= 0
1098 || i >= sizeof s->u.tempo.beats
1099 / sizeof s->u.tempo.beats[0])
1100 goto inval;
1101 s->u.tempo.beats[i++] = l;
1102 p += n;
1103 while (isspace((unsigned char) *p))
1104 p++;
1105 }
1106 c = *p;
1107 if (c != '=')
1108 goto inval;
1109 } else {
1110 s->u.tempo.beats[0] = ulen;
1111 if (parse.abc_vers >= (2 << 16))
1112 syntax("Deprecated Q: value", p);
1113 c = '=';
1114 p--;
1115 }
1116 } else {
1117 c = '\0';
1118 }
1119
1120 /* tempo value */
1121 if (c == '=') {
1122 p++;
1123 if (strncmp(p, "ca. ", 4) == 0) {
1124 s->u.tempo.circa = 1;
1125 p += 4;
1126 }
1127 if (sscanf(p, "%d/%d%n", &top, &bot, &n) == 2) {
1128 if (bot <= 0)
1129 goto inval;
1130 l = (BASE_LEN * top) / bot;
1131 if (l <= 0)
1132 goto inval;
1133 s->u.tempo.new_beat = l;
1134 } else {
1135 if (sscanf(p, "%d%n", &top, &n) != 1)
1136 goto inval;
1137 s->u.tempo.tempo = top;
1138 }
1139 p += n;
1140 while (isspace((unsigned char) *p))
1141 p++;
1142 }
1143
1144 /* string after */
1145 if (*p == '"') {
1146 p = get_str(str, p, sizeof str);
1147 s->u.tempo.str2 = getarena(strlen(str) + 1);
1148 strcpy(s->u.tempo.str2, str);
1149 }
1150
1151 return 0;
1152 inval:
1153 return "Invalid tempo";
1154 }
1155
1156 /* -- get a user defined symbol (U:) -- */
get_user(char * p,struct SYMBOL * s)1157 static char *get_user(char *p,
1158 struct SYMBOL *s)
1159 {
1160 unsigned char c;
1161 char *value;
1162
1163 c = (unsigned char) *p++;
1164 if (c == '\\') {
1165 c = (unsigned char) *p++;
1166 switch (c) {
1167 case 'n':
1168 c = '\n';
1169 break;
1170 case 't':
1171 c = '\t';
1172 break;
1173 }
1174 }
1175 switch (char_tb[c]) {
1176 default:
1177 return "Bad decoration character";
1178 case CHAR_DECO:
1179 break;
1180 case CHAR_BAD:
1181 case CHAR_IGN:
1182 case CHAR_SPAC:
1183 case CHAR_DECOS:
1184 case CHAR_LINEBREAK:
1185 char_tb[c] = CHAR_DECO;
1186 break;
1187 }
1188 s->u.user.symbol = c;
1189
1190 /* skip '=' */
1191 while (isspace((unsigned char) *p) || *p == '=')
1192 p++;
1193 if (char_tb[(unsigned char) *p] == CHAR_DECOS)
1194 p++;
1195 /*fixme: 'U: <char> = "text"' is not treated */
1196 get_deco(p, &s->u.user.value);
1197
1198 /* treat special pseudo decorations */
1199 value = parse.deco_tb[s->u.user.value - 128];
1200 if (strcmp(value, "beambreak") == 0)
1201 char_tb[c] = CHAR_SPAC;
1202 else if (strcmp(value, "ignore") == 0)
1203 char_tb[c] = CHAR_IGN;
1204 else if (strcmp(value, "nil") == 0
1205 || strcmp(value, "none") == 0)
1206 char_tb[c] = CHAR_BAD;
1207 else
1208 return 0;
1209 s->u.user.value = 0; /* not a decoration */
1210 return 0;
1211 }
1212
1213 /* -- parse the voice parameters (V:) -- */
parse_voice(char * p,struct SYMBOL * s)1214 static char *parse_voice(char *p,
1215 struct SYMBOL *s)
1216 {
1217 int voice;
1218 char *error_txt = NULL;
1219 char *clef_name, *clef_middle, *clef_stlines, *clef_scale;
1220 char *p_octave, *p_cue, *p_map;
1221 signed char *p_stem;
1222 static struct kw_s {
1223 char *name;
1224 short len;
1225 short index;
1226 } kw_tb[] = {
1227 {"name=", 5, 0},
1228 {"nm=", 3, 0},
1229 {"subname=", 8, 1},
1230 {"sname=", 6, 1},
1231 {"snm=", 4, 1},
1232 {"merge", 5, 2},
1233 {"up", 2, 3},
1234 {"down", 4, 4},
1235 {"stem=", 5, 5},
1236 {"gstem=", 6, 6},
1237 {"auto", 4, 7},
1238 {"dyn=", 4, 8},
1239 {"lyrics=", 7, 9},
1240 {"scale=", 6, 10},
1241 {"gchord=", 7, 11},
1242 {0}
1243 };
1244 struct kw_s *kw;
1245
1246 /* save the parameters of the previous voice */
1247 curvoice->ulen = ulen;
1248 curvoice->microscale = microscale;
1249
1250 if (voice_tb[0].id[0] == '\0') {
1251 switch (s->abc_prev->abc_type) {
1252 case ABC_T_EOLN:
1253 case ABC_T_NOTE:
1254 case ABC_T_REST:
1255 case ABC_T_BAR:
1256 /* the previous voice was implicit (after K:) */
1257 voice_tb[0].id[0] = '1';
1258 break;
1259 }
1260 }
1261 {
1262 char *id, sep;
1263
1264 id = p;
1265 while (isalnum((unsigned char) *p) || *p == '_')
1266 p++;
1267 sep = *p;
1268 *p = '\0';
1269 if (voice_tb[0].id[0] == '\0') {
1270 voice = 0; /* first voice */
1271 } else {
1272 for (voice = 0; voice <= nvoice; voice++) {
1273 if (strcmp(id, voice_tb[voice].id) == 0)
1274 goto found;
1275 }
1276 if (voice >= MAXVOICE) {
1277 syntax("Too many voices", id);
1278 voice--;
1279 }
1280 }
1281 nvoice = voice;
1282 strncpy(voice_tb[voice].id, id, sizeof voice_tb[voice].id - 1);
1283 voice_tb[voice].mvoice = voice;
1284 found:
1285 strcpy(s->u.voice.id, voice_tb[voice].id);
1286 *p = sep;
1287 }
1288 curvoice = &voice_tb[voice];
1289 s->u.voice.voice = voice;
1290
1291 /* if in tune, set the voice parameters */
1292 if (parse.abc_state == ABC_S_TUNE) {
1293 ulen = curvoice->ulen;
1294 microscale = curvoice->microscale;
1295 }
1296
1297 /* parse the other parameters */
1298 clef_name = clef_middle = clef_stlines = clef_scale = NULL;
1299 p_octave = p_cue = p_map = NULL;
1300 p_stem = &s->u.voice.stem;
1301 for (;;) {
1302 while (isspace((unsigned char) *p))
1303 p++;
1304 if (*p == '\0')
1305 break;
1306 p = parse_extra(p, &clef_name, &clef_middle, &clef_stlines,
1307 &clef_scale, &p_octave, &p_cue, &p_map);
1308 if (*p == '\0')
1309 break;
1310 for (kw = kw_tb; kw->name; kw++) {
1311 if (strncmp(p, kw->name, kw->len) == 0)
1312 break;
1313 }
1314 if (!kw->name) {
1315 while (!isspace((unsigned char) *p) && *p != '\0')
1316 p++; /* ignore unknown keywords */
1317 continue;
1318 }
1319 p += kw->len;
1320 switch (kw->index) {
1321 case 0: /* name */
1322 p = get_str(tex_buf, p, TEX_BUF_SZ);
1323 s->u.voice.fname = getarena(strlen(tex_buf) + 1);
1324 strcpy(s->u.voice.fname, tex_buf);
1325 break;
1326 case 1: /* subname */
1327 p = get_str(tex_buf, p, TEX_BUF_SZ);
1328 s->u.voice.nname = getarena(strlen(tex_buf) + 1);
1329 strcpy(s->u.voice.nname, tex_buf);
1330 break;
1331 case 2: /* merge */
1332 s->u.voice.merge = 1;
1333 break;
1334 case 3: /* up */
1335 *p_stem = 1;
1336 break;
1337 case 4: /* down */
1338 *p_stem = -1;
1339 break;
1340 case 5: /* stem= */
1341 p_stem = &s->u.voice.stem;
1342 break;
1343 case 6: /* gstem= */
1344 p_stem = &s->u.voice.gstem;
1345 break;
1346 case 7: /* auto */
1347 *p_stem = 2;
1348 break;
1349 case 8: /* dyn= */
1350 p_stem = &s->u.voice.dyn;
1351 break;
1352 case 9: /* lyrics= */
1353 p_stem = &s->u.voice.lyrics;
1354 break;
1355 case 10: { /* scale= */
1356 float sc;
1357
1358 sc = atof(p);
1359 if (sc >= 0.5 && sc <= 2)
1360 s->u.voice.scale = sc;
1361 else
1362 error_txt = "Bad value for voice scale";
1363 while (!isspace((unsigned char) *p) && *p != '\0')
1364 p++;
1365 break;
1366 }
1367 case 11: /* gchord= */
1368 p_stem = &s->u.voice.gchord;
1369 break;
1370 }
1371 }
1372
1373 s->u.voice.octave = parse_octave(p_octave);
1374 if (p_cue) {
1375 if (strncmp(p_cue, "on", 2) == 0)
1376 s->u.voice.cue = 1;
1377 else
1378 s->u.voice.cue = -1;
1379 }
1380 if (clef_stlines)
1381 s->u.voice.stafflines = clef_stlines;
1382 // else
1383 // s->u.voice.stafflines = "|||||";
1384 if (clef_scale) {
1385 float sc;
1386
1387 sc = atof(clef_scale);
1388 if (sc >= 0.5 && sc <= 3)
1389 s->u.voice.staffscale = sc;
1390 else
1391 syntax("Bad value of staffscale", clef_scale);
1392 }
1393 if (clef_name || clef_middle) {
1394 s = abc_new(ABC_T_CLEF, NULL);
1395 parse_clef(s, clef_name, clef_middle);
1396 }
1397 if (p_map) {
1398 strcpy(tex_buf, "%%voicemap ");
1399 get_str(&tex_buf[11], p_map, TEX_BUF_SZ - 12);
1400 abc_new(ABC_T_PSCOM, tex_buf);
1401 }
1402 return error_txt;
1403 }
1404
1405 /* -- parse a bar -- */
parse_bar(char * p)1406 static char *parse_bar(char *p)
1407 {
1408 struct SYMBOL *s;
1409 char *q;
1410 int bar_type, i;
1411 char repeat_value[32];
1412
1413 q = --p; // keep the first char
1414 bar_type = 0;
1415 for (;;) {
1416 switch (*p++) {
1417 case '|':
1418 bar_type <<= 4;
1419 bar_type |= B_BAR;
1420 continue;
1421 case '[':
1422 bar_type <<= 4;
1423 bar_type |= B_OBRA;
1424 continue;
1425 case ']':
1426 bar_type <<= 4;
1427 bar_type |= B_CBRA;
1428 continue;
1429 case ':':
1430 bar_type <<= 4;
1431 bar_type |= B_COL;
1432 continue;
1433 default:
1434 break;
1435 }
1436 break;
1437 }
1438 p--;
1439
1440 /* if the last element is '[', it may start
1441 * a chord, an embedded header or an other bar */
1442 if ((bar_type & 0x0f) == B_OBRA && bar_type != B_OBRA
1443 && *p != ' ') {
1444 bar_type >>= 4;
1445 p--;
1446 }
1447
1448 if (bar_type == (B_OBRA << 8) + (B_BAR << 4) + B_CBRA) /* [|] */
1449 bar_type = (B_OBRA << 4) + B_CBRA; /* [] */
1450
1451 /* curvoice->last_note = NULL; */
1452 if (vover > 0) {
1453 curvoice = &voice_tb[curvoice->mvoice];
1454 vover = 0;
1455 }
1456 s = abc_new(ABC_T_BAR, gchord);
1457 if (gchord)
1458 gchord = NULL;
1459
1460 /* handle the repeat sequences */
1461 if (bar_type == B_COL) {
1462 bar_type = B_BAR;
1463 s->u.bar.dotted = 1;
1464 } else {
1465 if (*q == ']') { /* repeat bar stop */
1466 i = p - q - 1;
1467 if (i > 0) /* remove the starting ']' */
1468 s->u.bar.type &= (1 << (i * 4)) - 1;
1469 s->flags |= ABC_F_RBSTOP;
1470 s->sflags |= S_RBSTOP;
1471 } else if ((bar_type & 0x0f) == B_COL /* left or */
1472 || *q == ':') { /* right repeat bar */
1473 s->flags |= ABC_F_RBSTOP;
1474 s->sflags |= S_RBSTOP;
1475 if (*q == ':') /* right repeat bar */
1476 s->sflags |= S_RRBAR;
1477 }
1478 }
1479
1480 s->u.bar.type = bar_type;
1481
1482 if (dc.n > 0) {
1483 memcpy(&s->u.bar.dc, &dc, sizeof s->u.bar.dc);
1484 dc.n = 0;
1485 }
1486
1487 if (!lyric_started) {
1488 lyric_started = 1;
1489 s->flags |= ABC_F_LYRIC_START;
1490 }
1491
1492 if (!isdigit((unsigned char) *p) /* if not a repeat bar */
1493 && (*p != '"' || p[-1] != '[')) /* ('["' only) */
1494 return p;
1495
1496 if (*p == '"') {
1497 p = get_str(repeat_value, p, sizeof repeat_value);
1498 } else {
1499 char *q;
1500
1501 q = repeat_value;
1502 while (isdigit((unsigned char) *p)
1503 || *p == ','
1504 || *p == '-'
1505 || (*p == '.' && isdigit((unsigned char) p[1]))) {
1506 if (q < &repeat_value[sizeof repeat_value - 1])
1507 *q++ = *p++;
1508 else
1509 p++;
1510 }
1511 *q = '\0';
1512 }
1513 if (bar_type != B_OBRA
1514 || s->text) {
1515 s = abc_new(ABC_T_BAR, repeat_value);
1516 s->u.bar.type = B_OBRA;
1517 } else {
1518 s->text = getarena(strlen(repeat_value) + 1);
1519 strcpy(s->text, repeat_value);
1520 }
1521 s->u.bar.repeat_bar = 1;
1522 s->flags |= ABC_F_RBSTART | ABC_F_RBSTOP;
1523 s->sflags |= S_RBSTART | S_RBSTOP;
1524 return p;
1525 }
1526
1527 // parse the note accidental and pitch
parse_acc_pit(char * p,int * pit,int * acc)1528 char *parse_acc_pit(char *p,
1529 int *pit,
1530 int *acc)
1531 {
1532 /* look for accidental sign */
1533 switch (*p) {
1534 case '^':
1535 p++;
1536 if (*p == '^') {
1537 p++;
1538 *acc = A_DS;
1539 } else {
1540 *acc = A_SH;
1541 }
1542 break;
1543 case '=':
1544 p++;
1545 *acc = A_NT;
1546 break;
1547 case '_':
1548 p++;
1549 if (*p == '_') {
1550 p++;
1551 *acc = A_DF;
1552 } else {
1553 *acc = A_FT;
1554 }
1555 break;
1556 default:
1557 *acc = 0;
1558 }
1559
1560 /* look for microtone value */
1561 if (*acc != 0
1562 && (isdigit((unsigned char) *p)
1563 || (*p == '/' && microscale == 0))) {
1564 int n, d;
1565 char *q;
1566
1567 n = d = 1;
1568 if (*p != '/') {
1569 n = strtol(p, &q, 10);
1570 p = q;
1571 }
1572 if (*p == '/') {
1573 p++;
1574 if (!isdigit((unsigned char) *p)) {
1575 d = 2;
1576 } else {
1577 d = strtol(p, &q, 10);
1578 p = q;
1579 }
1580 }
1581 if (microscale == 0) {
1582 d--;
1583 d += (n - 1) << 8; /* short [ (n-1) | (d-1) ] */
1584 for (n = 1; n < MAXMICRO; n++) {
1585 if (parse.micro_tb[n] == d)
1586 break;
1587 if (parse.micro_tb[n] == 0) {
1588 parse.micro_tb[n] = d;
1589 break;
1590 }
1591 }
1592 if (n == MAXMICRO) {
1593 syntax("Too many microtone accidentals", p);
1594 n = 0;
1595 }
1596 }
1597 *acc += (n << 3);
1598 }
1599
1600 /* get the pitch */
1601 {
1602 char *p_n;
1603
1604 p_n = strchr(all_notes, *p);
1605 if (!p_n || *p == '\0') {
1606 syntax(*acc ? "Missing note after accidental"
1607 : "Not a note", p);
1608 *acc = -1;
1609 if (*p == '\0')
1610 p--;
1611 } else {
1612 *pit = p_n - all_notes + 16;
1613 }
1614 p++;
1615 }
1616 while (*p == '\'') { /* eat up following ' chars */
1617 *pit += 7;
1618 p++;
1619 }
1620 while (*p == ',') { /* eat up following , chars */
1621 *pit -= 7;
1622 p++;
1623 }
1624 return p;
1625 }
1626
1627 /* -- parse the decorations of notes and bars -- */
parse_deco(char * p,struct decos * deco,int m)1628 static char *parse_deco(char *p,
1629 struct decos *deco,
1630 int m) /* note index / -1 */
1631 {
1632 int n;
1633 unsigned char t;
1634
1635 n = deco->n;
1636 for (;;) {
1637 t = (unsigned char) *p++;
1638 if (char_tb[t] != CHAR_DECO && char_tb[t] != CHAR_DECOS)
1639 break;
1640 if (char_tb[t] == CHAR_DECOS)
1641 p = get_deco(p, &t);
1642 if (n >= MAXDC) {
1643 syntax("Too many decorations for the note", p);
1644 } else if (t != 0) {
1645 deco->tm[n].t = t;
1646 deco->tm[n++].m = m;
1647 }
1648 }
1649 deco->n = n;
1650 return p - 1;
1651 }
1652
1653 /* -- parse a decoration line (d: or s:) -- */
parse_decoline(char * p)1654 static char *parse_decoline(char *p)
1655 {
1656 struct SYMBOL *is;
1657 unsigned char t;
1658 int n;
1659
1660 if ((is = deco_cont) == NULL)
1661 is = deco_start;
1662 else
1663 deco_cont = NULL;
1664
1665 /* scan the decoration line */
1666 while (*p != '\0') {
1667 while (isspace((unsigned char) *p))
1668 p++;
1669 if (*p == '\0')
1670 break;
1671 switch (*p) {
1672 case '|':
1673 while (is && (is->abc_type != ABC_T_BAR
1674 || is->u.bar.type == B_OBRA))
1675 is = is->abc_next;
1676 if (!is) {
1677 syntax("Not enough bar lines for deco line", p);
1678 return NULL;
1679 }
1680 is = is->abc_next;
1681 p++;
1682 continue;
1683 case '*':
1684 while (is && is->abc_type != ABC_T_NOTE)
1685 is = is->abc_next;
1686 if (!is) {
1687 syntax("Not enough notes for deco line", p);
1688 return NULL;
1689 }
1690 is = is->abc_next;
1691 p++;
1692 continue;
1693 case '\\':
1694 if (p[1] == '\0') {
1695 if (!is)
1696 return "Not enough notes for deco line";
1697 deco_cont = is;
1698 return NULL;
1699 }
1700 syntax("'\\' ignored", p);
1701 p++;
1702 continue;
1703 case '"':
1704 p = parse_gchord(p + 1);
1705 break;
1706 default:
1707 if (char_tb[(unsigned char) *p] == CHAR_DECOS)
1708 p = get_deco(p + 1, &t);
1709 else
1710 t = (unsigned char) *p++;
1711 break;
1712 }
1713
1714 /* store the decoration and gchord/annotation in the next note */
1715 while (is && (is->abc_type != ABC_T_NOTE
1716 || (is->flags & ABC_F_GRACE)))
1717 is = is->abc_next;
1718 if (!is)
1719 return "Not enough notes for deco line";
1720
1721 if (gchord) {
1722 if (is->text) {
1723 char *gch;
1724
1725 n = strlen(is->text);
1726 gch = getarena(n + strlen(gchord) + 2);
1727 strcpy(gch, is->text);
1728 gch[n] = '\n';
1729 strcpy(gch + n + 1, gchord);
1730 gchord = gch;
1731 }
1732 is->text = gchord;
1733 gchord = NULL;
1734 } else {
1735 n = is->u.note.dc.n;
1736 if (n >= MAXDC) {
1737 syntax("Too many decorations for the note", p);
1738 } else if (t != 0) {
1739 is->u.note.dc.tm[n].t = t;
1740 is->u.note.dc.tm[n].m = -1;
1741 is->u.note.dc.n = ++n;
1742 }
1743 }
1744 is = is->abc_next;
1745 }
1746 return NULL;
1747 }
1748
1749 /* -- parse a guitar chord / annotation -- */
parse_gchord(char * p)1750 static char *parse_gchord(char *p)
1751 {
1752 char *q;
1753 int l, l2;
1754
1755 q = p;
1756 while (*p != '"') {
1757 if (*p == '\\')
1758 p++;
1759 if (*p == '\0') {
1760 syntax("No end of guitar chord", p);
1761 break;
1762 }
1763 p++;
1764 }
1765 l = p - q;
1766 if (gchord) {
1767 char *gch;
1768
1769 /* many guitar chords: concatenate with '\n' */
1770 l2 = strlen(gchord);
1771 gch = getarena(l2 + 1 + l + 1);
1772 strcpy(gch, gchord);
1773 gch[l2++] = '\n';
1774 strncpy(&gch[l2], q, l);
1775 gch[l2 + l] = '\0';
1776 gchord = gch;
1777 } else {
1778 gchord = getarena(l + 1);
1779 strncpy(gchord, q, l);
1780 gchord[l] = '\0';
1781 }
1782 if (*p != '\0')
1783 p++;
1784 return p;
1785 }
1786
1787 /* -- parse a note length -- */
parse_len(char * p,int dur_u,int * p_len)1788 static char *parse_len(char *p,
1789 int dur_u,
1790 int *p_len)
1791 {
1792 int len, fac;
1793 char *q;
1794
1795 len = dur_u;
1796 if (isdigit((unsigned char) *p)) {
1797 len *= strtol(p, &q, 10);
1798 if (len <= 0 || len > BASE_LEN * 8) {
1799 syntax("Bad length", p);
1800 len = BASE_LEN;
1801 }
1802 p = q;
1803 }
1804 fac = 1;
1805 while (*p == '/') {
1806 p++;
1807 if (isdigit((unsigned char) *p)) {
1808 fac *= strtol(p, &q, 10);
1809 if (fac == 0) {
1810 syntax("Bad length divisor", p - 1);
1811 fac = 1;
1812 }
1813 p = q;
1814 } else {
1815 fac *= 2;
1816 }
1817 }
1818 if (len % fac)
1819 syntax("Bad length divisor", p - 1);
1820 len /= fac;
1821 *p_len = len;
1822 return p;
1823 }
1824
1825 /* -- parse a ABC line -- */
1826 /* return 1 on end of tune, and 2 on start of new tune */
parse_line(char * p)1827 static int parse_line(char *p)
1828 {
1829 struct SYMBOL *s;
1830 char *q, c;
1831 char *dot = NULL;
1832 struct SYMBOL *last_note_sav = NULL;
1833 struct decos dc_sav;
1834 int i, flags, flags_sav = 0, slur;
1835 static char qtb[10] = {0, 1, 3, 2, 3, 0, 2, 0, 3, 0};
1836
1837 colnum = 0;
1838 switch (*p) {
1839 case '\0': /* blank line */
1840 switch (parse.abc_state) {
1841 case ABC_S_GLOBAL:
1842 if (parse.last_sym
1843 && parse.last_sym->abc_type != ABC_T_NULL)
1844 abc_new(ABC_T_NULL, NULL);
1845 case ABC_S_HEAD: /*fixme: may have blank lines in headers?*/
1846 return 0;
1847 }
1848 return 1;
1849 case '%':
1850 if (p[1] == '%') {
1851 s = abc_new(ABC_T_PSCOM, p);
1852 p += 2; /* skip '%%' */
1853 if (strncasecmp(p, "decoration ", 11) == 0) {
1854 p += 11;
1855 while (isspace((unsigned char) *p))
1856 p++;
1857 switch (*p) {
1858 case '!':
1859 char_tb['!'] = CHAR_DECOS;
1860 char_tb['+'] = CHAR_BAD;
1861 break;
1862 case '+':
1863 char_tb['+'] = CHAR_DECOS;
1864 char_tb['!'] = CHAR_BAD;
1865 break;
1866 }
1867 return 0;
1868 }
1869 if (strncasecmp(p, "linebreak ", 10) == 0) {
1870 for (i = 0; i < sizeof char_tb; i++) {
1871 if (char_tb[i] == CHAR_LINEBREAK)
1872 char_tb[i] = i != '!' ?
1873 CHAR_BAD :
1874 CHAR_DECOS;
1875 }
1876 p += 10;
1877 for (;;) {
1878 while (isspace((unsigned char) *p))
1879 p++;
1880 if (*p == '\0')
1881 break;
1882 switch (*p) {
1883 case '!':
1884 case '$':
1885 case '*':
1886 case ';':
1887 case '?':
1888 case '@':
1889 char_tb[(unsigned char) *p++]
1890 = CHAR_LINEBREAK;
1891 break;
1892 case '<':
1893 if (strncmp(p, "<none>", 6) == 0)
1894 return 0;
1895 if (strncmp(p, "<EOL>", 5) == 0) {
1896 char_tb['\n'] = CHAR_LINEBREAK;
1897 p += 5;
1898 break;
1899 }
1900 /* fall thru */
1901 default:
1902 if (strcmp(p, "lock") != 0)
1903 syntax("Invalid character in %%%%linebreak",
1904 p);
1905 return 0;
1906 }
1907 }
1908 return 0;
1909 }
1910 if (strncasecmp(p, "microscale ", 11) == 0) {
1911 int v;
1912
1913 p += 11;
1914 while (isspace((unsigned char) *p))
1915 p++;
1916 sscanf(p, "%d", &v);
1917 if (v < 4 || v >= 256 || v & 1)
1918 syntax("Invalid value in %%microscale", p);
1919 else
1920 microscale = v;
1921 return 0;
1922 }
1923 if (strncasecmp(p, "user ", 5) == 0) {
1924 p += 5;
1925 while (isspace((unsigned char) *p))
1926 p++;
1927 get_user(p, s);
1928 return 0;
1929 }
1930 return 0;
1931 }
1932 /* fall thru */
1933 case '\\': /* abc2mtex specific lines */
1934 return 0; /* skip */
1935 }
1936
1937 /* header fields */
1938 if (p[1] == ':'
1939 && *p != '|' && *p != ':') { /* not '|:' nor '::' */
1940 int new_tune;
1941
1942 new_tune = parse_info(p);
1943
1944 /* handle BarFly voice definition */
1945 /* 'V:n <note line ending with a bar>' */
1946 if (*p != 'V'
1947 || parse.abc_state != ABC_S_TUNE)
1948 return new_tune; /* (normal return) */
1949 c = p[strlen(p) - 1];
1950 if (c != '|' && c != ']')
1951 return new_tune;
1952 while (!isspace((unsigned char) *p) && *p != '\0')
1953 p++;
1954 while (isspace((unsigned char) *p))
1955 p++;
1956 }
1957 if (parse.abc_state != ABC_S_TUNE)
1958 return 0;
1959
1960 /* music */
1961 flags = 0;
1962 if (parse.abc_vers <= (2 << 16))
1963 lyric_started = 0;
1964 deco_start = deco_cont = NULL;
1965 slur = 0;
1966 while (*p != '\0') {
1967 colnum = p - abc_line;
1968 switch (char_tb[(unsigned char) *p++]) {
1969 case CHAR_GCHORD: /* " */
1970 if (flags & ABC_F_GRACE)
1971 goto bad_char;
1972 p = parse_gchord(p);
1973 break;
1974 case CHAR_GR_ST: /* '{' */
1975 if (flags & ABC_F_GRACE)
1976 goto bad_char;
1977 last_note_sav = curvoice->last_note;
1978 curvoice->last_note = NULL;
1979 memcpy(&dc_sav, &dc, sizeof dc);
1980 dc.n = 0;
1981 flags_sav = flags;
1982 flags = ABC_F_GRACE;
1983 if (*p == '/') {
1984 flags |= ABC_F_SAPPO;
1985 p++;
1986 }
1987 break;
1988 case CHAR_GR_EN: /* '}' */
1989 if (!(flags & ABC_F_GRACE))
1990 goto bad_char;
1991 parse.last_sym->flags |= ABC_F_GR_END;
1992 if (dc.n != 0)
1993 syntax("Decoration ignored", p);
1994 curvoice->last_note = last_note_sav;
1995 memcpy(&dc, &dc_sav, sizeof dc);
1996 flags = flags_sav;
1997 break;
1998 case CHAR_DECOS:
1999 if (p[-1] == '!'
2000 && char_tb['\n'] == CHAR_LINEBREAK
2001 && check_nl(p)) {
2002 s = abc_new(ABC_T_EOLN, NULL); /* abc2win EOL */
2003 s->u.eoln.type = 2;
2004 break;
2005 }
2006 /* fall thru */
2007 case CHAR_DECO:
2008 if (p[-1] == '.') {
2009 if (*p == '(' || *p == '-') {
2010 dot = p;
2011 break;
2012 }
2013 // if (*p == '|') {
2014 // p = parse_bar(p + 1);
2015 // parse.last_sym->u.bar.dotted = 1;
2016 // break;
2017 // }
2018 }
2019 p = parse_deco(p - 1, &dc, -1);
2020 break;
2021 case CHAR_LINEBREAK:
2022 s = abc_new(ABC_T_EOLN, NULL);
2023 // s->u.eoln.type = 0;
2024 break;
2025 case CHAR_NOTE:
2026 p = parse_note(p - 1, flags);
2027 flags &= ABC_F_GRACE;
2028 parse.last_sym->u.note.slur_st = slur;
2029 slur = 0;
2030 if (parse.last_sym->u.note.notes[0].len > 0) /* if not space */
2031 curvoice->last_note = parse.last_sym;
2032 break;
2033 case CHAR_SLASH: /* '/' */
2034 if (flags & ABC_F_GRACE)
2035 goto bad_char;
2036 q = p;
2037 while (*q == '/')
2038 q++;
2039 if (char_tb[(unsigned char) *q] != CHAR_BAR)
2040 goto bad_char;
2041 s = abc_new(ABC_T_MREP, NULL);
2042 s->u.bar.type = 0;
2043 s->u.bar.len = q - p + 1;
2044 syntax("Non standard measure repeat syntax", p - 1);
2045 p = q;
2046 break;
2047 case CHAR_BSLASH: /* '\\' */
2048 if (*p == '\0')
2049 break;
2050 syntax("'\\' ignored", p - 1);
2051 break;
2052 case CHAR_OBRA: /* '[' */
2053 if (*p == '|' || *p == ']' || *p == ':'
2054 || isdigit((unsigned char) *p) || *p == '"'
2055 || *p == ' ') {
2056 if (flags & ABC_F_GRACE)
2057 goto bad_char;
2058 p = parse_bar(p);
2059 break;
2060 }
2061 if (p[1] != ':') {
2062 p = parse_note(p - 1, flags); /* chord */
2063 flags &= ABC_F_GRACE;
2064 parse.last_sym->u.note.slur_st = slur;
2065 slur = 0;
2066 curvoice->last_note = parse.last_sym;
2067 break;
2068 }
2069
2070 /* embedded information field */
2071 #if 0
2072 /*fixme:OK for [I:staff n], ?? for other headers*/
2073 if (flags & ABC_F_GRACE)
2074 goto bad_char;
2075 #endif
2076 while (p[2] == ' ') { /* remove the spaces */
2077 p[2] = ':';
2078 p[1] = *p;
2079 p++;
2080 }
2081 c = ']';
2082 q = p;
2083 while (*p != '\0' && *p != c)
2084 p++;
2085 if (*p == '\0') {
2086 syntax("Escape sequence [..] not closed", q);
2087 c = '\0';
2088 } else {
2089 *p = '\0';
2090 }
2091 parse_info(q);
2092 *p = c;
2093 if (c != '\0')
2094 p++;
2095 break;
2096 case CHAR_BAR: /* '|', ':' or ']' */
2097 if (flags & ABC_F_GRACE)
2098 goto bad_char;
2099 p = parse_bar(p);
2100 break;
2101 case CHAR_OPAR: /* '(' */
2102 if (*p > '0' && *p <= '9') {
2103 int pplet, qplet, rplet;
2104
2105 pplet = strtol(p, &q, 10);
2106 p = q;
2107 if ((unsigned) pplet < sizeof qtb / sizeof qtb[0])
2108 qplet = qtb[pplet];
2109 else
2110 qplet = qtb[0];
2111 rplet = pplet;
2112 if (*p == ':') {
2113 p++;
2114 if (isdigit((unsigned char) *p)) {
2115 qplet = strtol(p, &q, 10);
2116 p = q;
2117 }
2118 if (*p == ':') {
2119 p++;
2120 if (isdigit((unsigned char) *p)) {
2121 rplet = strtol(p, &q, 10);
2122 p = q;
2123 }
2124 }
2125 }
2126 if (rplet < 1) {
2127 syntax("Invalid 'r' in tuplet", p);
2128 break;
2129 }
2130 if (pplet >= 128 || qplet >= 128 || rplet >= 128) {
2131 syntax("Invalid 'p:q:r' in tuplet", p);
2132 break;
2133 }
2134 if (qplet == 0)
2135 qplet = meter % 3 == 0 ? 3 : 2;
2136 s = abc_new(ABC_T_TUPLET, NULL);
2137 s->u.tuplet.p_plet = pplet;
2138 s->u.tuplet.q_plet = qplet;
2139 s->u.tuplet.r_plet = rplet;
2140 s->flags |= flags;
2141 break;
2142 }
2143 if (*p == '&') {
2144 if (flags & ABC_F_GRACE)
2145 goto bad_char;
2146 p++;
2147 if (vover != 0) {
2148 syntax("Nested voice overlay", p - 1);
2149 break;
2150 }
2151 s = abc_new(ABC_T_V_OVER, NULL);
2152 s->u.v_over.type = V_OVER_S;
2153 s->u.v_over.voice = curvoice - voice_tb;
2154 vover = -1; /* multi-bars */
2155 break;
2156 }
2157 slur <<= 4;
2158 if (p == dot + 1 && dc.n == 0)
2159 slur |= SL_DOTTED;
2160 switch (*p) {
2161 case '\'':
2162 slur += SL_ABOVE;
2163 p++;
2164 break;
2165 case ',':
2166 slur += SL_BELOW;
2167 p++;
2168 break;
2169 default:
2170 slur += SL_AUTO;
2171 break;
2172 }
2173 break;
2174 case CHAR_CPAR: /* ')' */
2175 switch (parse.last_sym->abc_type) {
2176 case ABC_T_NOTE:
2177 case ABC_T_REST:
2178 break;
2179 default:
2180 goto bad_char;
2181 }
2182 parse.last_sym->u.note.slur_end++;
2183 break;
2184 case CHAR_VOV: /* '&' */
2185 if (flags & ABC_F_GRACE)
2186 goto bad_char;
2187 if (*p != ')'
2188 || vover == 0) { /*??*/
2189 if (!curvoice->last_note) {
2190 syntax("Bad start of voice overlay", p);
2191 break;
2192 }
2193 s = abc_new(ABC_T_V_OVER, NULL);
2194 /*s->u.v_over.type = V_OVER_V; */
2195 vover_new();
2196 s->u.v_over.voice = curvoice - voice_tb;
2197 if (vover == 0)
2198 vover = 1; /* single bar */
2199 break;
2200 }
2201 p++;
2202 vover = 0;
2203 s = abc_new(ABC_T_V_OVER, NULL);
2204 s->u.v_over.type = V_OVER_E;
2205 s->u.v_over.voice = curvoice->mvoice;
2206 curvoice->last_note = NULL; /* ?? */
2207 curvoice = &voice_tb[curvoice->mvoice];
2208 break;
2209 case CHAR_SPAC: /* ' ' and '\t' */
2210 flags |= ABC_F_SPACE;
2211 break;
2212 case CHAR_MINUS: { /* '-' */
2213 int tie_pos;
2214
2215 if (!curvoice->last_note
2216 || curvoice->last_note->abc_type != ABC_T_NOTE)
2217 goto bad_char;
2218 if (p == dot + 1 && dc.n == 0)
2219 tie_pos = SL_DOTTED;
2220 else
2221 tie_pos = 0;
2222 switch (*p) {
2223 case '\'':
2224 tie_pos += SL_ABOVE;
2225 p++;
2226 break;
2227 case ',':
2228 tie_pos += SL_BELOW;
2229 p++;
2230 break;
2231 default:
2232 tie_pos += SL_AUTO;
2233 break;
2234 }
2235 for (i = 0; i <= curvoice->last_note->nhd; i++) {
2236 if (curvoice->last_note->u.note.notes[i].ti1 == 0)
2237 curvoice->last_note->u.note.notes[i].ti1 = tie_pos;
2238 else if (curvoice->last_note->nhd == 0)
2239 syntax("Too many ties", p);
2240 }
2241 break;
2242 }
2243 case CHAR_BRHY: /* '>' and '<' */
2244 if (!curvoice->last_note)
2245 goto bad_char;
2246 i = 1;
2247 while (*p == p[-1]) {
2248 i++;
2249 p++;
2250 }
2251 if (i > 3) {
2252 syntax("Bad broken rhythm", p - 1);
2253 i = 3;
2254 }
2255 if (p[-1] == '<')
2256 i = -i;
2257 broken_rhythm(curvoice->last_note, i);
2258 curvoice->last_note->u.note.brhythm = i;
2259 break;
2260 case CHAR_IGN: /* '*' & '`' */
2261 break;
2262 default:
2263 bad_char:
2264 syntax((flags & ABC_F_GRACE)
2265 ? "Bad character in grace note sequence"
2266 : "Bad character",
2267 p - 1);
2268 break;
2269 }
2270 }
2271
2272 /*fixme: may we have grace notes across lines?*/
2273 if (flags & ABC_F_GRACE) {
2274 syntax("EOLN in grace note sequence", p - 1);
2275 if (curvoice->last_note)
2276 curvoice->last_note->flags |= ABC_F_GR_END;
2277 curvoice->last_note = last_note_sav;
2278 memcpy(&dc, &dc_sav, sizeof dc);
2279 }
2280
2281 /* add eoln */
2282 s = abc_new(ABC_T_EOLN, NULL);
2283 if (flags & ABC_F_SPACE)
2284 s->flags |= ABC_F_SPACE;
2285 if (p[-1] == '\\'
2286 || char_tb['\n'] != CHAR_LINEBREAK)
2287 s->u.eoln.type = 1; /* no break */
2288
2289 return 0;
2290 }
2291
2292 /* -- parse a note or a rest -- */
parse_note(char * p,int flags)2293 static char *parse_note(char *p,
2294 int flags)
2295 {
2296 struct SYMBOL *s;
2297 char *q;
2298 int pit, len, acc, nostem, chord, j, m, n;
2299
2300 if (flags & ABC_F_GRACE) { /* in a grace note sequence */
2301 s = abc_new(ABC_T_NOTE, NULL);
2302 } else {
2303 s = abc_new(ABC_T_NOTE, gchord);
2304 if (gchord)
2305 gchord = NULL;
2306 }
2307 s->flags |= flags;
2308 s->u.note.notes[0].color = -1;
2309
2310 if (!lyric_started) {
2311 lyric_started = 1;
2312 s->flags |= ABC_F_LYRIC_START;
2313 }
2314 if (*p != 'X' && *p != 'Z'
2315 && !(flags & ABC_F_GRACE)) {
2316 if (!deco_start)
2317 deco_start = s;
2318 }
2319 chord = 0;
2320
2321 /* rest */
2322 switch (*p) {
2323 case 'X':
2324 s->flags |= ABC_F_INVIS;
2325 case 'Z': /* multi-rest */
2326 s->abc_type = ABC_T_MREST;
2327 p++;
2328 len = 1;
2329 if (isdigit((unsigned char) *p)) {
2330 len = strtol(p, &q, 10);
2331 if (len == 0 && len > 100) {
2332 syntax("Bad number of measures", p);
2333 len = 1;
2334 }
2335 p = q;
2336 }
2337 s->u.bar.type = 0;
2338 s->u.bar.len = len;
2339 goto add_deco;
2340 case 'y': /* space (BarFly) */
2341 s->abc_type = ABC_T_REST;
2342 s->flags |= ABC_F_INVIS;
2343 p++;
2344 if (isdigit((unsigned char) *p) /* number of points */
2345 || *p == '-') { /* accept negative offset... */
2346 s->u.note.notes[0].shhd = strtol(p, &q, 10);
2347 p = q;
2348 } else {
2349 s->u.note.notes[0].shhd = 10; // default
2350 }
2351 goto add_deco;
2352 case 'x': /* invisible rest */
2353 s->flags |= ABC_F_INVIS;
2354 /* fall thru */
2355 case 'z':
2356 s->abc_type = ABC_T_REST;
2357 p = parse_len(p + 1, ulen, &len);
2358 s->u.note.notes[0].len = len;
2359 goto do_brhythm;
2360 case '[': /* '[..]' = chord */
2361 chord = 1;
2362 p++;
2363 break;
2364 }
2365
2366 q = p;
2367
2368 /* get pitch, length and possible accidental */
2369 m = 0;
2370 nostem = 0;
2371 for (;;) {
2372 if (chord) {
2373 if (m >= MAXHD) {
2374 syntax("Too many notes in chord", p);
2375 m--;
2376 }
2377 n = 0;
2378 if (*p == '.') {
2379 n = SL_DOTTED;
2380 p++;
2381 }
2382 if (*p == '(') {
2383 p++;
2384 switch (*p) {
2385 case '\'':
2386 n += SL_ABOVE;
2387 p++;
2388 break;
2389 case ',':
2390 n += SL_BELOW;
2391 p++;
2392 break;
2393 default:
2394 n += SL_AUTO;
2395 break;
2396 }
2397 s->u.note.notes[m].sl1 = (s->u.note.notes[m].sl1 << 3)
2398 + n;
2399 }
2400 }
2401 p = parse_deco(p, &dc, m); /* note head decorations */
2402 p = parse_acc_pit(p, &pit, &acc);
2403 if (*p == '0') {
2404 nostem = 1;
2405 p++;
2406 }
2407 p = parse_len(p, (flags & ABC_F_GRACE) ?
2408 BASE_LEN / 8 : // for grace note alone
2409 ulen,
2410 &len);
2411 s->u.note.notes[m].pit = pit;
2412 s->pits[m] = pit;
2413 s->u.note.notes[m].len = len;
2414 s->u.note.notes[m].acc = acc;
2415 s->u.note.notes[m].color = -1;
2416
2417 if (chord) {
2418 for (;;) {
2419 if (*p == '.') {
2420 if (p[1] != '-')
2421 break;
2422 p++;
2423 }
2424 if (*p == '-') {
2425 switch (p[1]) {
2426 case '\'':
2427 s->u.note.notes[m].ti1 = SL_ABOVE;
2428 p++;
2429 break;
2430 case ',':
2431 s->u.note.notes[m].ti1 = SL_BELOW;
2432 p++;
2433 break;
2434 default:
2435 s->u.note.notes[m].ti1 = SL_AUTO;
2436 break;
2437 }
2438 } else if (*p == ')') {
2439 s->u.note.notes[m].sl2++;
2440 } else {
2441 break;
2442 }
2443 p++;
2444 }
2445 }
2446 if (acc >= 0) /* if no error */
2447 m++; /* normal case */
2448
2449 if (!chord)
2450 break;
2451 if (*p == ']') {
2452 p++;
2453 if (*p == '0') {
2454 nostem = 1;
2455 p++;
2456 }
2457 if (*p == '/' || isdigit((unsigned char) *p)) {
2458 p = parse_len(p, ulen, &len);
2459 for (j = 0; j < m; j++) {
2460 s->u.note.notes[j].len =
2461 len * s->u.note.notes[j].len / ulen;
2462 }
2463 }
2464 break;
2465 }
2466 if (*p == '\0') {
2467 syntax("Chord not closed", q);
2468 break;
2469 }
2470 }
2471 if (nostem)
2472 s->flags |= ABC_F_STEMLESS;
2473
2474 if (m == 0) /* if no note (or error) */
2475 goto err;
2476
2477 s->u.note.microscale = microscale;
2478 s->nhd = m - 1;
2479
2480 do_brhythm:
2481 if (curvoice->last_note
2482 && curvoice->last_note->u.note.brhythm != 0)
2483 broken_rhythm(s, -curvoice->last_note->u.note.brhythm);
2484 add_deco:
2485 if (dc.n > 0) {
2486 memcpy(s->abc_type != ABC_T_MREST ? &s->u.note.dc
2487 : &s->u.bar.dc,
2488 &dc, sizeof dc);
2489 dc.n = 0;
2490 }
2491
2492 /* forbid rests in grace note sequences */
2493 if (s->abc_type != ABC_T_NOTE && (flags & ABC_F_GRACE)) {
2494 syntax("Not a note in grace note sequence", p);
2495 goto err;
2496 }
2497 return p;
2498
2499 err:
2500 if ((parse.last_sym = s->abc_prev) == NULL) {
2501 parse.first_sym = NULL;
2502 } else {
2503 s->abc_prev->abc_next = NULL;
2504 s->abc_prev->flags |= (s->flags & ABC_F_ERROR);
2505 }
2506 return p;
2507 }
2508
2509 /* -- parse an information field -- */
2510 /* return 2 on start of new tune */
parse_info(char * p)2511 static int parse_info(char *p)
2512 {
2513 struct SYMBOL *s;
2514 char info_type = *p;
2515 char *error_txt = NULL;
2516
2517 s = abc_new(ABC_T_INFO, p);
2518
2519 p += 2;
2520
2521 switch (info_type) {
2522 case 'd':
2523 case 's':
2524 if (parse.abc_state == ABC_S_GLOBAL)
2525 break;
2526 if (!deco_start) {
2527 error_txt = "Erroneous 'd:'/'s:'";
2528 break;
2529 }
2530 error_txt = parse_decoline(p);
2531 break;
2532 case 'K':
2533 if (parse.abc_state == ABC_S_GLOBAL)
2534 break;
2535 parse_key(p, s);
2536 if (parse.abc_state == ABC_S_HEAD) {
2537 int i;
2538
2539 parse.abc_state = ABC_S_TUNE;
2540 if (ulen == 0)
2541 ulen = BASE_LEN / 8;
2542 for (i = MAXVOICE; --i >= 0; )
2543 voice_tb[i].ulen = ulen;
2544 lyric_started = 0;
2545 }
2546 break;
2547 case 'L':
2548 error_txt = get_len(p, s);
2549 if (s->u.length.base_length > 0)
2550 ulen = s->u.length.base_length;
2551 break;
2552 case 'M':
2553 error_txt = parse_meter(p, s);
2554 break;
2555 case 'Q':
2556 error_txt = parse_tempo(p, s);
2557 break;
2558 case 'U':
2559 error_txt = get_user(p, s);
2560 break;
2561 case 'V':
2562 if (parse.abc_state == ABC_S_GLOBAL)
2563 break;
2564 error_txt = parse_voice(p, s);
2565 break;
2566 case 'X':
2567 memset(voice_tb, 0, sizeof voice_tb);
2568 nvoice = 0;
2569 curvoice = voice_tb;
2570 parse.abc_state = ABC_S_HEAD;
2571 lvlarena(1);
2572 return 2;
2573 }
2574 if (error_txt)
2575 syntax(error_txt, p);
2576 return 0;
2577 }
2578
2579 /* -- print a syntax error message -- */
syntax(char * msg,char * q)2580 static void syntax(char *msg,
2581 char *q)
2582 {
2583 int n, len, m1, m2, pp;
2584 int maxcol = 73;
2585
2586 severity = 1;
2587 n = q - abc_line;
2588 len = strlen(abc_line);
2589 if ((unsigned) n > (unsigned) len)
2590 n = -1;
2591 print_error(msg, n);
2592 if (n < 0) {
2593 if (q && *q != '\0')
2594 fprintf(stderr, " (near '%s')\n", q);
2595 return;
2596 }
2597 m1 = 0;
2598 m2 = len;
2599 if (m2 > maxcol) {
2600 if (n < maxcol) {
2601 m2 = maxcol;
2602 } else {
2603 m1 = n - 20;
2604 m2 = m1 + maxcol;
2605 if (m2 > len)
2606 m2 = len;
2607 }
2608 }
2609
2610 fprintf(stderr, "%4d ", linenum);
2611 pp = 6;
2612 if (m1 > 0) {
2613 fprintf(stderr, "...");
2614 pp += 3;
2615 }
2616 fprintf(stderr, "%.*s", m2 - m1, &abc_line[m1]);
2617 if (m2 < len)
2618 fprintf(stderr, "...");
2619 fprintf(stderr, "\n");
2620
2621 if ((unsigned) n < 200)
2622 fprintf(stderr, "%*s\n", n + pp - m1, "^");
2623
2624 if (last_sym)
2625 last_sym->flags |= ABC_F_ERROR;
2626 }
2627
2628 /* -- switch to a new voice overlay -- */
vover_new(void)2629 static void vover_new(void)
2630 {
2631 int voice, mvoice;
2632
2633 mvoice = curvoice->mvoice;
2634 for (voice = curvoice - voice_tb + 1; voice <= nvoice; voice++)
2635 if (voice_tb[voice].mvoice == mvoice)
2636 break;
2637 if (voice > nvoice) {
2638 if (nvoice >= MAXVOICE) {
2639 syntax("Too many voices", 0);
2640 return;
2641 }
2642 nvoice = voice;
2643 voice_tb[voice].id[0] = '&';
2644 voice_tb[voice].mvoice = mvoice;
2645 }
2646 voice_tb[voice].ulen = curvoice->ulen;
2647 voice_tb[voice].microscale = curvoice->microscale;
2648 curvoice = &voice_tb[voice];
2649 }
2650