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