music/mad -> Multimedia
[AROS-Contrib.git] / music / notation / abcm2ps / abcparse.c
blobe7ef9ab98c010602f10dbe504ece30e425e7366c
1 /*++
2 * Generic ABC parser.
4 * Copyright (C) 1998-2003 Jean-François Moine
5 * Adapted from abc2ps, Copyright (C) 1996, 1997 Michael Methfessel
7 * Contact: mailto:moinejf@free.fr
8 * Original site: http://moinejf.free.fr/
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *--*/
26 #include "config.h"
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <ctype.h>
32 #include "abcparse.h"
34 /* interface */
35 static void *(*alloc_f)(int size);
36 static void (*free_f)(void *);
37 static void (*level_f)(int level);
38 static int client_sz;
39 static int keep_comment;
41 static int abc_state; /* parse state */
42 static int gulen, ulen; /* unit note length set by M: or L: */
43 static char *gchord; /* guitar chord */
44 static int meter; /* upper value of time sig for n-plets */
45 static struct deco dc; /* decorations */
46 static int lyric_started; /* lyric started */
47 static struct abcsym *deco_start; /* 1st note of the line for d: / s: */
48 static struct abcsym *deco_cont; /* current symbol when d: / s: continuation */
49 static int vover_bar; /* in a simple voice overlay sequence */
51 #define VOICE_NAME_SZ 64 /* max size of a voice name */
53 static unsigned char *file; /* remaining abc file */
54 static short linenum; /* current line number */
55 static char *scratch_line; /* parse line */
56 static int scratch_length = 0; /* allocated length */
57 static int line_length; /* current line length */
59 static short nvoice; /* number of voices (0..n-1) */
60 static struct { /* voice table and current pointer */
61 char name[32]; /* voice name */
62 struct abcsym *last_note; /* last note or rest */
63 struct abcsym *tie; /* last note with starting ties */
64 short ulen; /* unit note length */
65 char slur; /* number of slur starts */
66 unsigned char pplet, qplet, rplet; /* nplet - fixme: may be global?*/
67 signed char add_pitch; /* key transpose */
68 unsigned char mvoice; /* main voice when voice overlay */
69 } voice_tb[MAXVOICE], *curvoice;
71 /* char table for note line parsing */
72 #define CHAR_BAD 0
73 #define CHAR_IGN 1
74 #define CHAR_NOTE 2
75 #define CHAR_REST 3
76 #define CHAR_ACC 4
77 #define CHAR_GRACE 5
78 #define CHAR_DECO 6
79 #define CHAR_GCHORD 7
80 #define CHAR_BSLASH 8
81 #define CHAR_OBRA 9
82 #define CHAR_BAR 10
83 #define CHAR_OPAR 11
84 #define CHAR_VOV 12
85 #define CHAR_VOVE 13
86 #define CHAR_SPAC 14
87 #define CHAR_MINUS 15
88 #define CHAR_CPAR 16
89 #define CHAR_BRHY 17
90 #define CHAR_DECOS 18
91 static char char_tb[256] = {
92 0, 0, 0, 0, 0, 0, 0, 0, 0, CHAR_SPAC, 0, 0, 0, 0, 0, 0, /* 00 - 0f */
93 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10 - 1f */
94 CHAR_SPAC, CHAR_DECOS, CHAR_GCHORD, CHAR_BAD, /* (sp) ! " # */
95 CHAR_BAD, CHAR_BAD, CHAR_VOV, CHAR_BAD, /* $ % & ' */
96 CHAR_OPAR, CHAR_CPAR, CHAR_IGN, CHAR_DECOS, /* ( ) * + */
97 CHAR_BAD, CHAR_MINUS, CHAR_DECO, CHAR_BAD, /* , - . / */
98 CHAR_BAD, CHAR_BAD, CHAR_BAD, CHAR_BAD, /* 0 1 2 3 */
99 CHAR_BAD, CHAR_BAD, CHAR_BAD, CHAR_BAD, /* 4 5 6 7 */
100 CHAR_BAD, CHAR_BAD, CHAR_BAR, CHAR_BAD, /* 8 9 : ; */
101 CHAR_BRHY, CHAR_ACC, CHAR_BRHY, CHAR_BAD, /* < = > ? */
102 CHAR_BAD, CHAR_NOTE, CHAR_NOTE, CHAR_NOTE, /* @ A B C */
103 CHAR_NOTE, CHAR_NOTE, CHAR_NOTE, CHAR_NOTE, /* D E F G */
104 CHAR_DECO, CHAR_DECO, CHAR_DECO, CHAR_DECO, /* H I J K */
105 CHAR_DECO, CHAR_DECO, CHAR_DECO, CHAR_DECO, /* L M N O */
106 CHAR_DECO, CHAR_DECO, CHAR_DECO, CHAR_DECO, /* P Q R S */
107 CHAR_DECO, CHAR_DECO, CHAR_DECO, CHAR_DECO, /* T U V W */
108 CHAR_DECO, CHAR_DECO, CHAR_REST, CHAR_OBRA, /* X Y Z [ */
109 CHAR_BSLASH, CHAR_BAR, CHAR_ACC, CHAR_ACC, /* \ ] ^ _ */
110 CHAR_IGN, CHAR_NOTE, CHAR_NOTE, CHAR_NOTE, /* ` a b c */
111 CHAR_NOTE, CHAR_NOTE, CHAR_NOTE, CHAR_NOTE, /* d e f g */
112 CHAR_DECO, CHAR_DECO, CHAR_DECO, CHAR_DECO, /* h i j k */
113 CHAR_DECO, CHAR_DECO, CHAR_DECO, CHAR_DECO, /* l m n o */
114 CHAR_DECO, CHAR_DECO, CHAR_DECO, CHAR_DECO, /* p q r s */
115 CHAR_DECO, CHAR_DECO, CHAR_DECO, CHAR_DECO, /* t u v w */
116 CHAR_REST, CHAR_REST, CHAR_REST, CHAR_GRACE, /* x y z { */
117 CHAR_BAR, CHAR_BAD, CHAR_DECO, CHAR_BAD, /* | } ~ (del) */
118 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 80 - 8f */
119 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 90 - 9f */
120 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* a0 - af */
121 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* b0 - bf */
122 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* c0 - cf */
123 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* d0 - df */
124 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* e0 - ef */
125 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* f0 - ff */
128 static char all_notes[] = "CDEFGABcdefgab^=_";
129 char *deco_tb[128];
131 int severity;
133 static unsigned char *get_line(void);
134 static unsigned char *parse_len(unsigned char *p,
135 int *p_len);
136 static char *parse_basic_note(char *p,
137 int *pitch,
138 int *length,
139 int *accidental,
140 int *stemless);
141 static unsigned char *parse_clef(unsigned char *p,
142 struct clef_s *p_clef);
143 static void parse_header(struct abctune *t,
144 unsigned char *p,
145 char *comment);
146 static int parse_line(struct abctune *t,
147 unsigned char *p);
148 static unsigned char *parse_note(struct abctune *t,
149 unsigned char *p);
150 static void syntax(char *msg, char *q);
151 static void vover_new(void);
153 /* -- abcMIDI like errors -- */
154 static void print_error(char *s,
155 int col)
157 if (col >= 0)
158 fprintf(stderr, "Error in line %d.%d: %s\n", linenum, col, s);
159 else fprintf(stderr, "Error in line %d: %s\n", linenum, s);
162 static void print_warning(char *s)
164 fprintf(stderr, "Warning in line %d: %s\n", linenum, s);
167 /* -- delete an ABC symbol -- */
168 void abc_delete(struct abcsym *as)
170 switch (as->type) {
171 case ABC_T_INFO:
172 switch (as->text[0]) {
173 case 'Q':
174 if (as->u.tempo.str1)
175 free_f(as->u.tempo.str1);
176 if (as->u.tempo.str2)
177 free_f(as->u.tempo.str2);
178 break;
179 case 'V':
180 if (as->u.voice.name)
181 free_f(as->u.voice.name);
182 if (as->u.voice.fname)
183 free_f(as->u.voice.fname);
184 if (as->u.voice.nname)
185 free_f(as->u.voice.nname);
186 break;
188 break;
190 if (as->text)
191 free_f(as->text);
192 if (as->comment)
193 free_f(as->comment);
195 if (as->prev)
196 as->prev->next = as->next;
197 if (as->next)
198 as->next->prev = as->prev;
199 if (as->tune->first_sym == as)
200 as->tune->first_sym = as->next;
201 if (as->tune->last_sym == as)
202 if ((as->tune->last_sym = as->prev) == 0)
203 free_f(as);
206 /* -- free all tunes memory areas -- */
207 void abc_free(struct abctune *first_tune)
209 struct abctune *t;
211 if (!free_f)
212 return;
213 t = first_tune;
214 for (;;) {
215 struct abcsym *s;
217 if (t == 0)
218 break;
219 s = t->first_sym;
221 /* free the associated symbols */
222 for (;;) {
223 struct abcsym *n;
225 n = s->next;
226 abc_delete(s);
227 if ((s = n) == 0)
228 break;
231 /* free the tune */
233 struct abctune *n;
235 n = t->next;
236 free_f(t);
237 t = n;
242 /* -- initialize the parser -- */
243 void abc_init(void *alloc_f_api(int size),
244 void free_f_api(void *ptr),
245 void level_f_api(int level),
246 int client_sz_api,
247 int keep_comment_api)
249 if (scratch_line != 0) {
250 fprintf(stderr, "abc_init already initialized\n");
251 return;
253 scratch_line = malloc(256 + 1);
254 scratch_length = 256;
255 alloc_f = alloc_f_api;
256 free_f = free_f_api;
257 level_f = level_f_api;
258 client_sz = client_sz_api;
259 keep_comment = keep_comment_api;
262 /* -- insert an ABC description -- */
263 void abc_insert(char *file_api,
264 struct abcsym *s)
266 unsigned char *p;
267 struct abctune *t;
269 /* initialize */
270 file = file_api;
271 if (level_f)
272 level_f(abc_state != ABC_S_GLOBAL);
273 abc_state = ABC_S_TUNE;
274 linenum = 0;
275 t = s->tune;
276 t->last_sym = s;
278 /* scan till end of description */
279 for (;;) {
280 if ((p = get_line()) == 0)
281 break; /* done */
283 if (*p == '\0')
284 break; /* blank line --> done */
286 /*fixme-insert: don't accept X: nor T:*/
287 /* parse the music line */
288 if (!parse_line(t, p))
289 break;
293 /* -- new symbol -- */
294 struct abcsym *abc_new(struct abctune *t,
295 unsigned char *p,
296 unsigned char *comment)
298 struct abcsym *s;
300 s = alloc_f(sizeof *s + client_sz);
301 memset(s, 0, sizeof *s + client_sz);
302 s->tune = t;
303 if (p != 0) {
304 s->text = alloc_f(strlen(p) + 1);
305 strcpy(s->text, p);
307 if (comment != 0) {
308 s->comment = alloc_f(strlen(comment) + 1);
309 strcpy(s->comment, comment);
311 if (t->last_sym == 0)
312 t->first_sym = t->last_sym = s;
313 else {
314 if ((s->next = t->last_sym->next) != 0)
315 s->next->prev = s;
316 t->last_sym->next = s;
317 s->prev = t->last_sym;
318 t->last_sym = s;
320 s->linenum = linenum;
321 return s;
324 /* -- parse an ABC file -- */
325 struct abctune *abc_parse(char *file_api)
327 unsigned char *p;
328 struct abctune *first_tune = 0;
329 struct abctune *t, *last_tune;
331 /* initialize */
332 file = file_api;
333 t = 0;
334 abc_state = ABC_S_GLOBAL;
335 if (level_f)
336 level_f(0);
337 linenum = 0;
338 last_tune = 0;
339 gulen = 0;
341 /* scan till end of file */
342 for (;;) {
343 if ((p = get_line()) == 0) {
344 if (abc_state == ABC_S_HEAD) {
345 print_error("unexpected EOF in header definition",
346 -1);
347 severity = 1;
349 break; /* done */
351 while (isspace(*p)) /* skip starting blanks */
352 p++;
354 /* start a new tune if not done */
355 if (t == 0) {
356 struct abctune *n;
358 if (*p == '\0')
359 continue;
360 n = alloc_f(sizeof *n);
361 memset(n, 0 , sizeof *n);
362 if (last_tune == 0)
363 first_tune = n;
364 else {
365 last_tune->next = n;
366 n->prev = last_tune;
368 last_tune = t = n;
369 ulen = gulen;
372 /* parse the music line */
373 if (!parse_line(t, p))
374 t = 0;
376 return first_tune;
379 /* -- cut off after % and remove trailing blanks -- */
380 static unsigned char *decomment_line(unsigned char *p)
382 int i;
383 unsigned char c, *comment = 0;
385 i = 0;
386 for (;;) {
387 if ((c = *p++) == '%') {
388 if (i > 0 && p[-2] != '\\') {
389 if (keep_comment)
390 comment = p;
391 c = '\0';
394 if (c == '\0') {
395 p--;
396 break;
398 i++;
401 /* remove trailing blanks */
402 while (--i > 0) {
403 c = *--p;
404 if (!isspace(c)) {
405 p[1] = '\0';
406 break;
409 return comment;
412 /* -- define a voice by name -- */
413 /* the voice is created if it does not exist */
414 static char *def_voice(unsigned char *p,
415 int *p_voice)
417 char *name;
418 char sep;
419 int voice;
421 name = p;
422 while (isalnum(*p) || *p == '_')
423 p++;
424 sep = *p;
425 *p = '\0';
427 if (voice_tb[0].name[0] == '\0')
428 voice = 0; /* first voice */
429 else {
430 for (voice = 0; voice <= nvoice; voice++) {
431 if (strcmp(name, voice_tb[voice].name) == 0)
432 goto done;
434 if (voice >= MAXVOICE) {
435 syntax("Too many voices", name);
436 voice--;
439 nvoice = voice;
440 strncpy(voice_tb[voice].name, name, sizeof voice_tb[voice].name - 1);
441 voice_tb[voice].mvoice = voice;
442 done:
443 *p_voice = voice;
444 *p = sep;
445 return p;
448 /* -- treat the broken rhythm '>' and '<' -- */
449 static void broken_rhythm(struct note *note,
450 int num) /* >0: do dot, <0: do half */
452 int l, m, n;
454 num *= 2;
455 if (num > 0) {
456 if (num == 6)
457 num = 8;
458 n = num * 2 - 1;
459 for (m = 0; m <= note->nhd; m++)
460 note->lens[m] = (note->lens[m] * n) / num;
461 } else {
462 n = -num;
463 if (n == 6)
464 n = 8;
465 for (m = 0; m <= note->nhd; m++)
466 note->lens[m] /= n;
468 l = note->lens[0];
469 for (m = 1; m <= note->nhd; m++)
470 if (note->lens[m] < l)
471 l = note->lens[m];
474 /* -- check for the '!' as end of line (ABC2Win) -- */
475 static int check_nl(unsigned char *p)
477 while (*p != '\0') {
478 switch (*p++) {
479 case '!':
480 return 0;
481 case '|':
482 case '[':
483 case ':':
484 case ']':
485 case ' ':
486 case '\t':
487 return 1;
490 return 1;
493 /* -- parse a decoration '[!|+]xxx[!|+]' -- */
494 static char *get_deco(unsigned char *p,
495 unsigned char *p_deco)
497 unsigned char *q, sep;
498 char **t;
499 int i, l;
501 *p_deco = 0;
502 q = p;
503 sep = q[-1];
504 if (sep != '!' && sep != '+')
505 sep = '\0'; /* Barfly U: */
506 while (*p != sep) {
507 if (*p == '\0') {
508 syntax("Decoration not terminated", q);
509 return p;
511 p++;
513 l = p - q;
514 if (*p == sep)
515 p++;
516 for (i = 1, t = &deco_tb[1];
517 *t != 0 && i < 128;
518 i++, t++) {
519 if (strlen(*t) == l
520 && strncmp(*t, q, l) == 0) {
521 *p_deco = i + 128;
522 return p;
526 /* new decoration */
527 if (i < 128) {
528 if (level_f && abc_state != ABC_S_GLOBAL)
529 level_f(0);
530 *t = alloc_f(l + 1);
531 if (level_f && abc_state != ABC_S_GLOBAL)
532 level_f(1);
533 memcpy(*t, q, l);
534 (*t)[l] = '\0';
535 *p_deco = i + 128;
536 } else syntax("Too many decoration types", q);
537 return p;
540 /* -- parse a list of accidentals (K:) -- */
541 static unsigned char *parse_acc(unsigned char *p,
542 struct abcsym *s)
544 int pit, len, acc, nostem, nacc;
546 nacc = s->u.key.nacc;
547 for (;;) {
548 if (nacc >= sizeof s->u.key.pits) {
549 syntax("Too many accidentals", 0);
550 break;
552 p = parse_basic_note(p, &pit, &len, &acc, &nostem);
553 s->u.key.pits[nacc] = pit - curvoice->add_pitch;
554 s->u.key.accs[nacc++] = acc;
555 if (*p == '\0')
556 break;
557 if (*p != '^' && *p != '_' && *p != '=')
558 break;
560 s->u.key.nacc = nacc;
561 return p;
564 /* -- parse a 'K:' -- */
565 static void parse_key(unsigned char *p,
566 struct abcsym *s)
568 int sf;
569 struct clef_s clef;
571 /* check for clef alone */
572 memset(&clef, 0, sizeof clef);
573 clef.type = -1;
574 p = parse_clef(p, &clef);
576 sf = 0;
577 switch (*p++) {
578 case 'F': sf = -1; break;
579 case 'B': sf++;
580 case 'E': sf++;
581 case 'A': sf++;
582 case 'D': sf++;
583 case 'G': sf++;
584 case 'C': break;
585 case 'H':
586 s->u.key.bagpipe = 1;
587 if (*p == 'P')
588 p++;
589 else if (*p == 'p') {
590 sf = 2;
591 p++;
592 } else syntax("Unknown bagpipe-like key", p);
593 break;
594 case '^':
595 case '_':
596 case '=':
597 p--; /* explicit accidentals */
598 break;
599 case '\0':
600 s->u.key.empty = 1;
601 p--;
602 break;
603 default:
604 syntax("Key not recognized", p);
605 p--;
606 break;
608 if (*p == '#') {
609 sf += 7;
610 p++;
611 } else if (*p == 'b') {
612 sf -= 7;
613 p++;
616 while (*p != '\0') {
617 while (isspace(*p))
618 p++;
619 if (*p == '\0')
620 break;
622 /* check for clef */
623 p = parse_clef(p, &clef);
624 if (clef.type >= 0)
625 continue;
626 switch (*p) {
627 case 'a':
628 case 'A':
629 if (strncasecmp(p, "aeo", 3) == 0) {
630 sf -= 3;
631 s->u.key.minor = 1;
632 } else goto unk;
633 break;
634 case 'd':
635 case 'D':
636 if (strncasecmp(p, "dor", 3) == 0)
637 sf -= 2;
638 else goto unk;
639 break;
640 case 'i':
641 case 'I':
642 if (strncasecmp(p, "ion", 3) == 0)
643 break;
644 goto unk;
645 case 'l':
646 case 'L':
647 if (strncasecmp(p, "loc", 3) == 0)
648 sf -= 5;
649 else if (strncasecmp(p, "lyd", 3) == 0)
650 sf += 1;
651 else goto unk;
652 break;
653 case 'm':
654 case 'M':
655 if (strncasecmp(p, "maj", 3) == 0)
657 else if (strncasecmp(p, "mix", 3) == 0)
658 sf -= 1;
659 else if (strncasecmp(p, "min", 3) == 0
660 || !isalpha(p[1])) { /* 'm' alone */
661 sf -= 3;
662 s->u.key.minor = 1;
663 } else goto unk;
664 break;
665 case 'o':
666 case 'O':
667 if (strncasecmp(p, "octave", 6) == 0) { /* (abcMIDI) */
668 p += 6;
669 while (!isspace(*p) && *p != '\0')
670 p++;
671 continue;
673 goto unk;
674 case 'p':
675 case 'P':
676 if (strncasecmp(p, "phr", 3) == 0)
677 sf -= 4;
678 else goto unk;
679 break;
680 case '^':
681 case '_':
682 case '=':
683 p = parse_acc(p, s); /* explicit accidentals */
684 continue;
685 case '+':
686 case '-':
687 if (p[1] == '8') {
688 /* "+8" / "-8" (fixme: not standard) */
689 if (*p == '+')
690 curvoice->add_pitch += 7;
691 else curvoice->add_pitch -= 7;
692 p += 2;
693 continue;
695 goto unk;
696 default:
697 unk:
698 syntax("Unknown token in key specifier", p);
699 while (!isspace(*p) && *p != '\0')
700 p++;
701 continue;
703 while (isalpha(*p))
704 p++;
707 if (sf > 7 || sf < -7) {
708 syntax("Too many sharps/flats", p);
709 if (sf > 0)
710 sf -= 12;
711 else sf += 12;
713 s->u.key.sf = sf;
715 if (clef.type >= 0) {
716 struct abcsym *s2;
718 s2 = abc_new(s->tune, 0, 0);
719 s2->type = ABC_T_CLEF;
720 memcpy(&s2->u.clef, &clef, sizeof s2->u.clef);
724 /* -- set default length from 'L:' -- */
725 static char *get_len(unsigned char *p,
726 struct abcsym *s)
728 int l1, l2, d;
729 char *error_txt = 0;
731 l1 = 0;
732 l2 = 1;
733 if (sscanf(p, "%d /%d ", &l1, &l2) != 2
734 || l1 == 0) {
735 s->u.length.base_length = ulen ? ulen : BASE_LEN / 8;
736 return "Bad unit note length: unchanged";
739 d = BASE_LEN / l2;
740 if (d * l2 != BASE_LEN) {
741 error_txt = "Length incompatible with BASE, using 1/8";
742 d = BASE_LEN / 8;
743 } else {
744 d *= l1;
745 if (l1 != 1
746 || (l2 & (l2 - 1))) {
747 error_txt = "Incorrect unit note length, using 1/8";
748 d = BASE_LEN / 8;
751 s->u.length.base_length = d;
752 return error_txt;
755 /* -- get a new line from the current file in memory -- */
756 static unsigned char *get_line(void)
758 int l;
759 unsigned char *p;
760 unsigned char *line;
762 p = file;
763 if (*p == '\0')
764 return 0;
765 line = p; /* (for syntax error) */
767 /* memorize the beginning of the next line */
768 while (*p != '\0'
769 && *p != '\r'
770 && *p != '\n') {
771 p++;
773 l = p - line;
774 if (*p != '\0')
775 p++;
776 /* solve PC-DOS */
777 if (p[-1] == '\r' && *p == '\n')
778 p++;
779 file = p;
781 linenum++;
783 /* allocate space for the line */
784 if (scratch_line != 0
785 && l >= scratch_length) {
786 free(scratch_line);
787 scratch_line = 0;
789 if (scratch_line == 0) {
790 scratch_line = malloc(l + 1);
791 scratch_length = l;
793 p = scratch_line;
794 strncpy(p, line, l);
795 p[l] = '\0';
796 line_length = l; /* for syntax error */
798 return p;
801 /* -- parse a 'M:' -- */
802 static char *parse_meter(unsigned char *p,
803 struct abcsym *s)
805 int m1, m2, d, wmeasure;
806 int nm, i;
807 int in_parenth;
809 if (*p == '\0')
810 return "Empty meter string";
811 nm = 0;
812 in_parenth = 0;
813 wmeasure = 0;
814 if (*p == 'N' || *p == 'n')
815 ; /* no meter */
816 else if (*p == 'C') {
817 s->u.meter.meter[0].top[0] = *p++;
818 if (*p == '|')
819 s->u.meter.meter[0].top[1] = *p++;
820 wmeasure = 4 * BASE_LEN / 4;
821 nm = 1;
822 } else while (*p != '\0') {
823 if (*p == '(' || *p == ')') {
824 if (*p == '(')
825 in_parenth = 1;
826 else in_parenth = 0;
827 s->u.meter.meter[nm].top[0] = *p++;
828 nm++;
829 continue;
831 if (sscanf(p, "%d", &m1) != 1
832 || m1 <= 0)
833 return "Cannot identify meter top";
834 i = 0;
835 m2 = 2; /* default when no bottom value */
836 for (;;) {
837 while (isdigit(*p)
838 && i < sizeof s->u.meter.meter[0].top)
839 s->u.meter.meter[nm].top[i++] = *p++;
840 if (*p == '/') {
841 p++;
842 if (sscanf(p, "%d", &m2) != 1
843 || m2 <= 0)
844 return "Cannot identify meter bottom";
845 i = 0;
846 while (isdigit(*p)
847 && i < sizeof s->u.meter.meter[0].bot)
848 s->u.meter.meter[nm].bot[i++] = *p++;
849 break;
851 if (*p != ' ' && *p != '+')
852 break;
853 s->u.meter.meter[nm].top[i++] = *p++;
854 if (sscanf(p, "%d", &d) != 1
855 || d <= 0)
856 return "Cannot identify meter top";
857 if (p[-1] == ' ') {
858 if (d > m1)
859 m1 = d;
860 } else m1 += d;
862 if (!in_parenth)
863 wmeasure += m1 * BASE_LEN / m2;
864 nm++;
865 if (*p == ' ' || *p == '+') {
866 s->u.meter.meter[nm].top[0] = *p++;
867 nm++;
871 s->u.meter.wmeasure = wmeasure;
872 s->u.meter.nmeter = nm;
874 /* if in the header, change the unit note length */
875 if (abc_state == ABC_S_HEAD && ulen == 0) {
876 if (wmeasure >= BASE_LEN * 3 / 4
877 || wmeasure == 0)
878 ulen = BASE_LEN / 8;
879 else ulen = BASE_LEN / 16;
882 return 0;
885 /* -- treat %%staves -- */
886 static void get_staves(unsigned char *p,
887 struct abcsym *s)
889 int voice;
890 char flags, flags2;
891 struct staff_s *staff;
893 /* define the voices */
894 flags = 0;
895 staff = 0;
896 voice = 0;
897 while (*p != '\0') {
898 switch (*p) {
899 case ' ':
900 case '\t':
901 break;
902 case '[':
903 if (flags & (OPEN_BRACKET | OPEN_BRACE | OPEN_PARENTH))
904 goto err;
905 flags |= OPEN_BRACKET;
906 staff = 0;
907 break;
908 case ']':
909 if (staff == 0)
910 goto err;
911 staff->flags |= CLOSE_BRACKET;
912 break;
913 case '{':
914 if (flags & (OPEN_BRACKET | OPEN_BRACE | OPEN_PARENTH))
915 goto err;
916 flags |= OPEN_BRACE;
917 staff = 0;
918 break;
919 case '}':
920 if (staff == 0)
921 goto err;
922 staff->flags |= CLOSE_BRACE;
923 break;
924 case '(':
925 if (flags & OPEN_PARENTH)
926 goto err;
927 flags |= OPEN_PARENTH;
928 staff = 0;
929 break;
930 case ')':
931 if (staff == 0)
932 goto err;
933 staff->flags |= CLOSE_PARENTH;
934 break;
935 case '|':
936 if (staff == 0)
937 goto err;
938 staff->flags |= STOP_BAR;
939 break;
940 default:
941 if (!isalnum(*p) && *p != '_')
942 goto err;
944 int v;
946 p = def_voice(p, &v);
947 staff = &s->u.staves[voice];
948 voice++;
949 staff->voice = v;
950 staff->name = alloc_f(strlen(voice_tb[v].name) + 1);
951 strcpy(staff->name, voice_tb[v].name);
953 staff->flags = flags;
954 flags = 0;
955 continue;
957 p++;
960 /* check for errors */
961 if (flags != 0)
962 goto err;
964 flags = CLOSE_BRACKET | CLOSE_BRACE | CLOSE_PARENTH; /* bad flags */
965 flags2 = flags;
966 for (voice = 0, staff = s->u.staves;
967 voice <= MAXVOICE && staff->name;
968 voice++, staff++) {
969 if (staff->flags & flags)
970 goto err;
971 if (staff->flags & CLOSE_PARENTH)
972 flags = flags2;
973 if (staff->flags & OPEN_BRACKET) {
974 flags &= ~CLOSE_BRACKET;
975 flags |= OPEN_BRACKET | OPEN_BRACE;
976 } else if (staff->flags & CLOSE_BRACKET) {
977 flags &= ~(OPEN_BRACKET | OPEN_BRACE);
978 flags |= CLOSE_BRACKET;
979 } else if (staff->flags & OPEN_BRACE) {
980 flags &= ~CLOSE_BRACE;
981 flags |= OPEN_BRACKET | OPEN_BRACE;
982 } else if (staff->flags & CLOSE_BRACE) {
983 flags &= ~(OPEN_BRACKET | OPEN_BRACE);
984 flags |= CLOSE_BRACE;
986 if (staff->flags & OPEN_PARENTH) {
987 flags2 = flags;
988 flags &= ~CLOSE_PARENTH;
991 return;
993 err:
994 syntax("%%%%staves error", p);
997 /* -- get a possibly quoted string -- */
998 char *get_str(unsigned char *d, /* destination */
999 unsigned char *s, /* source */
1000 int maxlen) /* max length */
1002 char sep, c;
1004 maxlen--; /* have place for the EOS */
1005 while (isspace(*s))
1006 s++;
1008 if (*s == '"') {
1009 sep = '"';
1010 s++;
1011 } else sep = ' ';
1012 while ((c = *s) != '\0') {
1013 if (c == sep
1014 || (c == '\t' && sep == ' ')) {
1015 if (sep != ' ')
1016 s++;
1017 break;
1019 if (c == '\\'
1020 && (c == sep
1021 || (c == '\t' && sep == ' '))) {
1022 s++;
1023 continue;
1025 if (--maxlen > 0)
1026 *d++ = c;
1027 s++;
1029 *d = '\0';
1030 while (isspace(*s))
1031 s++;
1032 return s;
1035 /* -- parse a tempo (Q:) -- */
1036 static char *parse_tempo(unsigned char *p,
1037 struct abcsym *s)
1039 int have_error = 0;
1040 unsigned char *q;
1041 int l;
1043 /* string before */
1044 if (*p == '"') {
1045 q = ++p;
1046 while (*p != '"' && *p != '\0')
1047 p++;
1048 l = p - q;
1049 s->u.tempo.str1 = alloc_f(l + 1);
1050 strncpy(s->u.tempo.str1, q, l);
1051 s->u.tempo.str1[l] = '\0';
1052 if (*p == '"')
1053 p++;
1054 while (isspace(*p))
1055 p++;
1058 /* beat */
1059 if (*p == 'C' || *p == 'c'
1060 || *p == 'L' || *p == 'l') {
1061 int len;
1063 p = parse_len(p + 1, &len);
1064 if (len <= 0)
1065 have_error++;
1066 else s->u.tempo.length[0] = len;
1067 while (isspace(*p))
1068 p++;
1069 } else if (isdigit(*p) && strchr(p, '/') != 0) {
1070 int i;
1072 i = 0;
1073 while (isdigit(*p)) {
1074 int top, bot, n;
1076 if (sscanf(p, "%d /%d%n", &top, &bot, &n) != 2
1077 || bot <= 0) {
1078 have_error++;
1079 break;
1081 l = (BASE_LEN * top) / bot;
1082 if (l <= 0
1083 || i >= sizeof s->u.tempo.length
1084 / sizeof s->u.tempo.length[0])
1085 have_error++;
1086 else s->u.tempo.length[i++] = l;
1087 p += n;
1088 while (isspace(*p))
1089 p++;
1093 /* tempo value ('Q:beat=value' or 'Q:value') */
1094 if (*p == '=')
1095 p++;
1096 if (isdigit(*p)) {
1097 int value;
1099 value = atoi(p);
1100 if (value < 0)
1101 have_error++;
1102 else s->u.tempo.value = value;
1103 while (isdigit(*p) || isspace(*p))
1104 p++;
1107 /* string after */
1108 if (*p == '"') {
1109 q = ++p;
1110 while (*p != '"' && *p != '\0')
1111 p++;
1112 l = p - q;
1113 s->u.tempo.str2 = alloc_f(l + 1);
1114 strncpy(s->u.tempo.str2, q, l);
1115 s->u.tempo.str2[l] = '\0';
1118 return have_error ? "Invalid tempo" : 0;
1121 /* -- get a user defined accent (U:) -- */
1122 static char *get_user(unsigned char *p,
1123 struct abcsym *s)
1125 /*fixme: may have 'U: <char> = "text" */
1126 if (char_tb[*p] != CHAR_DECO) /* accept any character */
1127 /*fixme: should be for the current tune only */
1128 char_tb[*p] = CHAR_DECO;
1129 s->u.user.symbol = *p++;
1131 /* skip '=' */
1132 while (isspace(*p) || *p == '=')
1133 p++;
1134 if (*p == '!' || *p == '+')
1135 p++;
1136 get_deco(p, &s->u.user.value);
1137 return 0;
1140 /* -- parse the voice parameters (V:) -- */
1141 static char *parse_voice(unsigned char *p,
1142 struct abcsym *s)
1144 int voice;
1145 char *error_txt = 0;
1146 char name[VOICE_NAME_SZ];
1147 struct clef_s clef;
1148 static struct kw_s {
1149 char *name;
1150 short len;
1151 short index;
1152 } kw_tb[] = {
1153 {"name=", 5, 0},
1154 {"nm=", 3, 0},
1155 {"subname=", 7, 1},
1156 {"sname=", 6, 1},
1157 {"snm=", 4, 1},
1158 {"merge", 5, 2},
1159 {"up", 2, 3},
1160 {"down", 4, 4},
1161 {0, 0, 0}
1163 struct kw_s *kw;
1165 /* save the unit note length of the previous voice */
1166 curvoice->ulen = ulen;
1168 if (voice_tb[0].name[0] == '\0') {
1169 switch (s->prev->type) {
1170 case ABC_T_EOLN:
1171 case ABC_T_NOTE:
1172 case ABC_T_REST:
1173 case ABC_T_BAR:
1174 /* the previous voice was implicit (after K:) */
1175 voice_tb[0].name[0] = '1';
1176 break;
1180 int voice2;
1182 p = def_voice(p, &voice2);
1183 voice = voice2;
1185 curvoice = &voice_tb[voice];
1186 s->u.voice.voice = voice;
1187 s->u.voice.name = alloc_f(strlen(curvoice->name) + 1);
1188 strcpy(s->u.voice.name, curvoice->name);
1190 /* if in tune, set the unit note length */
1191 if (abc_state == ABC_S_TUNE
1192 && curvoice->ulen != 0)
1193 ulen = curvoice->ulen;
1195 /* parse the other parameters */
1196 memset(&clef, 0, sizeof clef);
1197 clef.type = -1;
1198 for (;;) {
1199 while (isspace(*p))
1200 p++;
1201 if (*p == '\0')
1202 break;
1203 for (kw = kw_tb; kw->name; kw++) {
1204 if (strncmp(p, kw->name, kw->len) == 0)
1205 break;
1207 if (!kw->name) {
1209 /* unknown keyword, try a clef */
1210 p = parse_clef(p, &clef);
1211 if (clef.type >= 0)
1212 continue;
1213 while (!isspace(*p) && *p != '\0')
1214 p++; /* ignore unknown keywords */
1215 continue;
1217 p += kw->len;
1218 switch (kw->index) {
1219 case 0: /* name */
1220 p = get_str(name, p, VOICE_NAME_SZ);
1221 s->u.voice.fname = alloc_f(strlen(name) + 1);
1222 strcpy(s->u.voice.fname, name);
1223 break;
1224 case 1: /* subname */
1225 p = get_str(name, p, VOICE_NAME_SZ);
1226 s->u.voice.nname = alloc_f(strlen(name) + 1);
1227 strcpy(s->u.voice.nname, name);
1228 break;
1229 case 2: /* merge */
1230 s->u.voice.merge = 1;
1231 break;
1232 case 3: /* up */
1233 s->u.voice.stem = 1;
1234 break;
1235 case 4: /* down */
1236 s->u.voice.stem = -1;
1237 break;
1240 if (clef.type >= 0) {
1241 struct abcsym *s2;
1243 s2 = abc_new(s->tune, 0, 0);
1244 s2->type = ABC_T_CLEF;
1245 memcpy(&s2->u.clef, &clef, sizeof s2->u.clef);
1247 return error_txt;
1250 /* -- parse a bar -- */
1251 static char *parse_bar(struct abctune *t,
1252 unsigned char *p)
1254 struct abcsym *s;
1255 int bar_type;
1256 char repeat_value[32];
1258 p--;
1259 bar_type = 0;
1260 for (;;) {
1261 switch (*p++) {
1262 case '|':
1263 bar_type <<= 4;
1264 bar_type |= B_BAR;
1265 continue;
1266 case '[':
1267 bar_type <<= 4;
1268 bar_type |= B_OBRA;
1269 continue;
1270 case ']':
1271 bar_type <<= 4;
1272 bar_type |= B_CBRA;
1273 continue;
1274 case ':':
1275 bar_type <<= 4;
1276 bar_type |= B_COL;
1277 continue;
1278 default:
1279 break;
1281 break;
1283 p--;
1284 if ((bar_type & 0x0f) == B_OBRA && bar_type != B_OBRA) {
1285 bar_type >>= 4; /* have an other bar for '[' */
1286 p--;
1288 if (bar_type == (B_OBRA << 8) + (B_BAR << 4) + B_CBRA) /* [|] */
1289 bar_type = (B_OBRA << 4) + B_CBRA; /* [] */
1291 /* curvoice->last_note = 0; */
1292 if (vover_bar) {
1293 curvoice = &voice_tb[curvoice->mvoice];
1294 vover_bar = 0;
1296 s = abc_new(t, gchord, 0);
1297 if (gchord) {
1298 if (free_f)
1299 free_f(gchord);
1300 gchord = 0;
1302 s->type = ABC_T_BAR;
1303 s->state = ABC_S_TUNE;
1304 s->u.bar.type = bar_type;
1306 if (dc.n > 0) {
1307 memcpy(&s->u.bar.dc, &dc, sizeof s->u.bar.dc);
1308 dc.n = 0;
1310 if (!isdigit(*p) /* if not a repeat bar */
1311 && (*p != '"' || p[-1] != '[')) { /* ('["' only) */
1312 int n;
1314 if (*p != '/')
1315 return p;
1317 /* measure repeat */
1318 n = 0;
1319 while (*p == '/') {
1320 n++;
1321 p++;
1323 s = abc_new(t, 0, 0);
1324 s->type = ABC_T_MREP;
1325 s->state = ABC_S_TUNE;
1326 s->u.bar.type = 0;
1327 s->u.bar.len = n;
1328 return p;
1331 if (*p == '"')
1332 p = get_str(repeat_value, p, sizeof repeat_value);
1333 else {
1334 char *q;
1336 q = repeat_value;
1337 while (isdigit(*p)
1338 || *p == ','
1339 || *p == '-'
1340 || (*p == '.' && isdigit(p[1]))) {
1341 if (q < &repeat_value[sizeof repeat_value - 1])
1342 *q++ = *p++;
1343 else p++;
1345 *q = '\0';
1347 if (repeat_value[0] != '1' || repeat_value[1] != '\0')
1348 curvoice->tie = 0;
1349 if (bar_type != B_OBRA
1350 || s->text != 0) {
1351 s = abc_new(t, repeat_value, 0);
1352 s->type = ABC_T_BAR;
1353 s->state = ABC_S_TUNE;
1354 s->u.bar.type = B_OBRA;
1355 } else {
1356 s->text = alloc_f(strlen(repeat_value) + 1);
1357 strcpy(s->text, repeat_value);
1359 s->u.bar.repeat_bar = 1;
1360 return p;
1363 /* -- parse note or rest with pitch and length -- */
1364 static char *parse_basic_note(char *p,
1365 int *pitch,
1366 int *length,
1367 int *accidental,
1368 int *stemless)
1370 int pit, len, acc, nostem;
1372 acc = pit = nostem = 0;
1374 /* look for accidental sign */
1375 switch (*p) {
1376 case '^':
1377 p++;
1378 if (*p == '^') {
1379 acc = A_DS;
1380 p++;
1381 } else acc = A_SH;
1382 break;
1383 case '=':
1384 p++;
1385 acc = A_NT;
1386 break;
1387 case '_':
1388 p++;
1389 if (*p == '_') {
1390 acc = A_DF;
1391 p++;
1392 } else acc = A_FT;
1393 break;
1396 char *p_n;
1398 p_n = strchr(all_notes, *p);
1399 if (p_n == 0
1400 || p_n - all_notes >= 14) {
1401 if (acc)
1402 syntax("Missing note after accidental",
1404 else syntax("Not a note", p);
1405 pit = 16 + 7; /* 'c' */
1406 } else pit = p_n - all_notes + 16;
1407 p++;
1410 while (*p == '\'') { /* eat up following ' chars */
1411 pit += 7;
1412 p++;
1415 while (*p == ',') { /* eat up following , chars */
1416 pit -= 7;
1417 p++;
1420 if (*p == '0') {
1421 nostem = 1;
1422 p++;
1425 p = parse_len(p, &len);
1426 len = len * ulen / BASE_LEN;
1428 *pitch = pit + curvoice->add_pitch;
1429 *length = len;
1430 *accidental = acc;
1431 *stemless = nostem;
1433 return p;
1436 /* -- parse a clef (K: or V:) -- */
1437 static unsigned char *parse_clef(unsigned char *p,
1438 struct clef_s *p_clef)
1440 int clef = -1;
1441 int transpose = 0;
1442 int clef_line = 2;
1443 int clef_name;
1444 char *middle = 0;
1446 while (*p != '\0') {
1447 clef_name = 0;
1448 if (strncmp(p, "clef=", 5) == 0) {
1449 p += 5;
1450 clef_name = 1;
1451 switch (*p) {
1452 case 'g':
1453 transpose = -7;
1454 case 'G':
1455 clef = TREBLE;
1456 break;
1457 case 'f':
1458 transpose = -14;
1459 clef = BASS;
1460 clef_line = 4;
1461 break;
1462 case 'F':
1463 transpose = -7;
1464 clef = BASS;
1465 clef_line = 4;
1466 break;
1467 case 'c':
1468 transpose = -7;
1469 case 'C':
1470 clef = ALTO;
1471 clef_line = 3;
1472 break;
1473 case 'P':
1474 clef = PERC;
1475 break;
1476 default:
1477 clef_name = 0;
1479 if (clef_name) {
1480 p++;
1481 while (*p == ',') {
1482 transpose += 7;
1483 p++;
1485 while (*p == '\'') {
1486 transpose -= 7;
1487 p++;
1491 if (!strncmp(p, "bass", 4)) {
1492 clef = BASS;
1493 clef_line = 4;
1494 #ifdef CLEF_TRANSPOSE
1495 transpose = -14;
1496 #else
1497 p_clef->check_pitch = 1;
1498 #endif
1499 p += 4;
1500 clef_name = 1;
1501 } else if (!strncmp(p, "treble", 6)) {
1502 clef = TREBLE;
1503 p += 6;
1504 clef_name = 1;
1505 } else if (!strncmp(p, "alto", 4)
1506 || !strncmp(p, "tenor", 5)) {
1507 clef = ALTO;
1508 clef_line = *p == 'a' ? 3 : 4;
1509 #ifdef CLEF_TRANSPOSE
1510 transpose = -7;
1511 #else
1512 p_clef->check_pitch = 1;
1513 #endif
1514 if (*p == 'a')
1515 p += 4;
1516 else p += 5;
1517 clef_name = 1;
1518 } else if (!strncmp(p, "perc", 4)) {
1519 clef = PERC;
1520 p += 4;
1521 } else if (strncmp(p, "none", 4) == 0) {
1522 clef = TREBLE;
1523 p_clef->invis = 1;
1524 p += 4;
1525 } else if (!strncmp(p, "middle=", 7)) {
1526 p += 7;
1527 middle = p;
1528 while (!isspace(*p) && *p != '\0')
1529 p++;
1530 while (isspace(*p))
1531 p++;
1532 } else break;
1534 if (!clef_name)
1535 continue;
1537 switch (*p) {
1538 case '1':
1539 case '2':
1540 case '3':
1541 case '4':
1542 case '5':
1543 clef_line = *p++ - '0';
1544 break;
1546 if (p[1] == '8') {
1547 if (*p == '-') {
1548 p_clef->octave = -1;
1549 p += 2;
1550 } else if (*p == '+') {
1551 p_clef->octave = 1;
1552 p += 2;
1555 while (isspace(*p))
1556 p++;
1559 if (middle != 0) {
1560 int pit, len, acc, nostem, l;
1562 /* 'middle=<note pitch>' */
1563 if (clef < 0)
1564 clef = TREBLE;
1565 curvoice->add_pitch = 0;
1566 parse_basic_note(middle, &pit, &len, &acc, &nostem);
1567 l = 20;
1568 switch (clef) {
1569 case ALTO:
1570 l = 16;
1571 break;
1572 case BASS:
1573 l = 12;
1574 break;
1576 l = l - pit + 4 + 14;
1577 clef_line = (l % 7) / 2 + 1;
1578 transpose = l / 7 * 7 - 14;
1579 #ifndef CLEF_TRANSPOSE
1580 p_clef->check_pitch = 0;
1581 #endif
1584 if (clef >= 0) {
1585 curvoice->add_pitch = transpose;
1586 p_clef->line = clef_line;
1587 p_clef->transpose = transpose;
1588 if (p_clef->type >= 0)
1589 syntax("Double clef definition", p);
1591 p_clef->type = clef;
1592 return p;
1595 /* -- parse for decoration on note/bar -- */
1596 unsigned char *parse_deco(unsigned char *p,
1597 struct deco *deco)
1599 int n;
1600 unsigned char c, d;
1602 n = deco->n;
1603 for (;;) {
1604 c = *p++;
1605 if (char_tb[c] != CHAR_DECO && char_tb[c] != CHAR_DECOS)
1606 break;
1608 if (char_tb[c] == CHAR_DECOS)
1609 p = get_deco(p, &d);
1610 else d = c;
1611 if (n >= MAXDC)
1612 syntax("Too many decorations for the note", p);
1613 else if (d != 0)
1614 deco->t[n++] = d;
1616 deco->n = n;
1617 return p - 1;
1620 /* -- parse a decoration line (d: or s:) -- */
1621 static char *parse_decoline(unsigned char *p)
1623 struct abcsym *is;
1624 unsigned char d;
1625 int n;
1627 if ((is = deco_cont) == 0)
1628 is = deco_start;
1629 else deco_cont = 0;
1631 /* scan the decoration line */
1632 while (*p != '\0') {
1633 while (isspace(*p))
1634 p++;
1635 if (*p == '\0')
1636 break;
1637 switch (*p) {
1638 case '|':
1639 while (is != 0 && (is->type != ABC_T_BAR
1640 || is->u.bar.type == B_OBRA))
1641 is = is->next;
1642 if (is == 0) {
1643 syntax("Not enough bar lines for lyric line", p);
1644 return 0;
1646 is = is->next;
1647 p++;
1648 continue;
1649 case '*':
1650 while (is != 0 && is->type != ABC_T_NOTE)
1651 is = is->next;
1652 if (is == 0) {
1653 syntax("Not enough notes for decoration line", p);
1654 return 0;
1656 is = is->next;
1657 p++;
1658 continue;
1659 case '\\':
1660 if (p[1] == '\0') {
1661 if (is == 0)
1662 return "Not enough notes for decoration line";
1663 deco_cont = is;
1664 return 0;
1666 syntax("'\\' ignored", p);
1667 p++;
1668 continue;
1669 case '!':
1670 case '+':
1671 p = get_deco(p + 1, &d);
1672 break;
1673 default:
1674 d = *p++;
1675 break;
1678 /* store the decoration in the next note */
1679 while (is != 0 && is->type != ABC_T_NOTE)
1680 is = is->next;
1681 if (is == 0)
1682 return "Not enough notes for decoration line";
1684 n = is->u.note.dc.n;
1685 if (n >= MAXDC)
1686 syntax("Too many decorations for the note", p);
1687 else {
1688 is->u.note.dc.t[n] = d;
1689 is->u.note.dc.n = n + 1;
1691 is = is->next;
1693 return 0;
1696 /* -- parse a note length -- */
1697 static unsigned char *parse_len(unsigned char *p,
1698 int *p_len)
1700 int len, fac;
1702 len = BASE_LEN;
1703 if (isdigit(*p)) {
1704 len *= strtol(p, 0, 10);
1705 while (isdigit(*p))
1706 p++;
1708 fac = 1;
1709 while (*p == '/') {
1710 p++;
1711 if (isdigit(*p)) {
1712 fac *= strtol(p, 0, 10);
1713 while (isdigit(*p))
1714 p++;
1715 } else fac *= 2;
1716 if (len % fac) {
1717 syntax("Bad length divisor", p - 1);
1718 break;
1721 len /= fac;
1722 *p_len = len;
1723 return p;
1726 /* -- parse a music line -- */
1727 /* return 0 at end of tune */
1728 static int parse_line(struct abctune *t,
1729 unsigned char *p)
1731 struct abcsym *s;
1732 unsigned char *comment;
1733 struct abcsym *last_note_sav = 0;
1734 unsigned char *q, c;
1735 int i;
1736 char sappo = 0;
1737 static char qtb[10] = {1, 1, 3, 2, 3, 0, 2, 0, 3, 0};
1739 again: /* for history */
1740 switch (*p) {
1741 case '\0':
1742 switch (abc_state) {
1743 case ABC_S_GLOBAL:
1744 case ABC_S_HEAD: /*fixme: may have blank lines in headers*/
1745 if (keep_comment) {
1746 s = abc_new(t, 0, 0);
1747 s->type = ABC_T_NULL;
1748 s->state = abc_state;
1750 return 1;
1752 abc_state = ABC_S_GLOBAL;
1753 if (level_f)
1754 level_f(0);
1755 return 0;
1756 case '%':
1757 if (p[1] == '%') {
1758 comment = decomment_line(p + 2);
1759 s = abc_new(t, p, comment);
1760 s->type = ABC_T_PSCOM;
1761 s->state = abc_state;
1762 p += 2; /* skip '%%' */
1763 if (strncasecmp(p, "fmt ", 4) == 0)
1764 p += 4; /* skip 'fmt' */
1765 if (strncmp(p, "begintext", 9) == 0) {
1766 for (;;) {
1767 if ((p = get_line()) == 0) {
1768 syntax("EOF while parsing %%begintext pseudo-comment",
1769 scratch_line);
1770 return 0;
1772 s = abc_new(t, p, 0);
1773 s->type = ABC_T_PSCOM;
1774 s->state = abc_state;
1775 if (*p != '%' || p[1] != '%')
1776 continue;
1777 p += 2;
1778 if (strncasecmp(p, "fmt ", 4) == 0)
1779 p += 4;
1780 if (strncmp(p, "endtext", 7) == 0)
1781 return 1;
1783 /* not reached */
1785 if (strncmp(p, "staves ", 7) == 0)
1786 get_staves(p + 7, s);
1787 return 1;
1789 if (keep_comment) {
1790 s = abc_new(t, p, 0);
1791 s->type = ABC_T_NULL;
1792 s->state = abc_state;
1794 return 1; /* skip comments */
1795 case '\\':
1796 return 1; /* ignore abc2mtex specific lines */
1798 comment = decomment_line(p);
1800 /* header fields */
1801 if (p[1] == ':'
1802 && *p != '|' && *p != ':') { /* not '|:' nor '::' */
1803 parse_header(t, p, comment);
1804 if (*p == 'H') {
1806 /* wait for an other 'x:' or any '%%' */
1807 for (;;) {
1808 if ((p = get_line()) == 0)
1809 break;
1810 if (p[1] == ':'
1811 || (p[1] == '%' && *p == '%'))
1812 goto again;
1813 if (abc_state == ABC_S_HEAD) {
1814 s = abc_new(t, p, 0);
1815 s->type = ABC_T_INFO2;
1816 s->state = abc_state;
1821 /* handle BarFly voice definition */
1822 /* 'V:n <note line ending with a bar>' */
1823 if (*p != 'V'
1824 || abc_state != ABC_S_TUNE)
1825 return 1;
1826 c = p[strlen(p) - 1];
1827 if (c != '|' && c != ']')
1828 return 1;
1829 while (!isspace(*p) && *p != '\0')
1830 p++;
1831 while (isspace(*p))
1832 p++;
1834 if (abc_state != ABC_S_TUNE) {
1835 if (keep_comment) {
1836 s = abc_new(t, p, comment);
1837 s->type = ABC_T_NULL;
1838 s->state = abc_state;
1840 return 1;
1843 if (scratch_line[0] == ' ' && curvoice->last_note != 0)
1844 curvoice->last_note->u.note.word_end = 1;
1846 lyric_started = 0;
1847 deco_start = deco_cont = 0;
1848 while (*p != '\0') {
1849 switch (char_tb[*p++]) {
1850 case CHAR_GCHORD: { /* " */
1851 int l;
1852 int more_gch;
1854 gch_continue:
1855 more_gch = 0;
1856 q = p;
1857 while (*p != '"') {
1858 if (*p == '\0') {
1859 more_gch = 1;
1860 break;
1862 p++;
1864 l = p - q;
1865 if (gchord) {
1866 int l2;
1867 char *gch;
1869 /* many guitar chord: concatenate with '\n' */
1870 l2 = strlen(gchord);
1871 gch = alloc_f(l2 + 1 + l + 1);
1872 strcpy(gch, gchord);
1873 gch[l2++] = '\n';
1874 strncpy(&gch[l2], q, l);
1875 gch[l2 + l] = '\0';
1876 if (free_f)
1877 free_f(gchord);
1878 gchord = gch;
1879 } else {
1880 gchord = alloc_f(l + 1);
1881 strncpy(gchord, q, l);
1882 gchord[l] = '\0';
1884 if (*p != '\0')
1885 p++;
1886 else if (more_gch) {
1887 if ((p = get_line()) == 0) {
1888 syntax("EOF reached while parsing guitar chord",
1890 return 0;
1892 goto gch_continue;
1895 break;
1896 case CHAR_GRACE: /* '{' or '}' */
1897 if (p[-1] == '{') {
1898 if (*p == '/') {
1899 sappo = 1;
1900 p++;
1902 char_tb['{'] = CHAR_BAD;
1903 char_tb['}'] = CHAR_GRACE;
1904 last_note_sav = curvoice->last_note;
1905 curvoice->last_note = 0;
1906 } else {
1907 char_tb['{'] = CHAR_GRACE;
1908 char_tb['}'] = CHAR_BAD;
1909 /*fixme:bad*/
1910 t->last_sym->u.note.word_end = 1;
1911 curvoice->last_note = last_note_sav;
1913 break;
1914 case CHAR_DECO:
1915 case CHAR_DECOS:
1916 if (p[-1] == '!' && check_nl(p)) {
1917 s = abc_new(t, 0, 0); /* abc2win EOL */
1918 s->type = ABC_T_EOLN;
1919 s->state = abc_state;
1920 break;
1922 if (p[-1] == '.' && *p == '|') {
1923 p = parse_bar(t, p + 1);
1924 /*fixme: should have other dashed bars, as '.||' */
1925 t->last_sym->u.bar.type = B_COL;
1926 break;
1928 p = parse_deco(p - 1, &dc);
1929 break;
1930 case CHAR_ACC:
1931 case CHAR_NOTE:
1932 case CHAR_REST:
1933 p = parse_note(t, p - 1);
1934 if (sappo) {
1935 t->last_sym->u.note.sappo = 1;
1936 sappo = 0;
1938 curvoice->last_note = t->last_sym;
1939 break;
1940 case CHAR_BSLASH: /* '\\' */
1941 /*fixme: KO if in grace note sequence*/
1942 if (*p == '\0')
1943 return 1;
1944 syntax("'\\' ignored", p - 1);
1945 break;
1946 case CHAR_OBRA: /* '[' */
1947 if (*p == '|' || *p == ']'
1948 || isdigit(*p) || *p == '"') {
1949 p = parse_bar(t, p);
1950 break;
1952 if (p[1] != ':') {
1953 p = parse_note(t, p - 1); /* chord */
1954 if (sappo) {
1955 t->last_sym->u.note.sappo = 1;
1956 sappo = 0;
1958 curvoice->last_note = t->last_sym;
1959 break;
1962 /* embedded header */
1963 c = ']';
1964 q = p;
1965 while (*p != '\0' && *p != c)
1966 p++;
1967 if (*p == '\0') {
1968 syntax("Escape sequence [..] not closed",
1970 c = '\0';
1971 } else *p = '\0';
1972 abc_state = ABC_S_EMBED;
1973 parse_header(t, q, 0);
1974 abc_state = ABC_S_TUNE;
1975 *p++ = c;
1976 break;
1977 case CHAR_BAR: /* '|', ':' or ']' */
1978 p = parse_bar(t, p);
1979 break;
1980 case CHAR_OPAR: /* '(' */
1981 if (isdigit(*p)) {
1982 curvoice->pplet = *p - '0';
1983 curvoice->qplet = qtb[curvoice->pplet];
1984 curvoice->rplet = curvoice->pplet;
1985 p++;
1986 if (*p == ':') {
1987 p++;
1988 if (isdigit(*p)) {
1989 curvoice->qplet = *p - '0';
1990 p++;
1992 if (*p == ':') {
1993 p++;
1994 if (isdigit(*p)) {
1995 curvoice->rplet = *p - '0';
1996 p++;
2000 if (curvoice->qplet == 0)
2001 curvoice->qplet = meter % 3 == 0
2003 : 2;
2004 } else if (*p == '&') {
2005 s = abc_new(t, 0, 0);
2006 s->type = ABC_T_V_OVER;
2007 p++;
2008 if (*p == '&') {
2009 s->u.v_over.type = V_OVER_SD;
2010 p++;
2011 } else s->u.v_over.type = V_OVER_SS;
2012 s->u.v_over.voice = curvoice - voice_tb;
2013 char_tb[')'] = CHAR_VOVE;
2014 } else curvoice->slur++;
2015 break;
2016 case CHAR_CPAR: /* ')' */
2017 switch (t->last_sym->type) {
2018 case ABC_T_NOTE:
2019 case ABC_T_REST:
2020 break;
2021 default:
2022 goto bad_char;
2024 t->last_sym->u.note.slur_end++;
2025 break;
2026 case CHAR_VOV: /* '&' */
2027 s = abc_new(t, 0, 0);
2028 s->type = ABC_T_V_OVER;
2029 if (*p == '&') {
2030 s->u.v_over.type = V_OVER_D;
2031 p++;
2032 } /*else s->u.v_over.type = V_OVER_S; */
2033 vover_new();
2034 s->u.v_over.voice = curvoice - voice_tb;
2035 if (char_tb[')'] != CHAR_VOVE)
2036 vover_bar = 1;
2037 break;
2038 case CHAR_VOVE: /* ')' after '(&' */
2039 s = abc_new(t, 0, 0);
2040 s->type = ABC_T_V_OVER;
2041 s->u.v_over.type = V_OVER_E;
2042 s->u.v_over.voice = curvoice->mvoice;
2043 char_tb[')'] = CHAR_CPAR;
2044 curvoice->last_note = 0; /* ?? */
2045 curvoice = &voice_tb[curvoice->mvoice];
2046 break;
2047 case CHAR_SPAC: /* ' ' and '\t' */
2048 if (curvoice->last_note != 0)
2049 curvoice->last_note->u.note.word_end = 1;
2050 break;
2051 case CHAR_MINUS: /* '-' */
2052 if ((curvoice->tie = curvoice->last_note) == 0
2053 || curvoice->tie->type != ABC_T_NOTE)
2054 goto bad_char;
2055 for (i = 0; i <= curvoice->tie->u.note.nhd; i++)
2056 curvoice->tie->u.note.ti1[i] = 1;
2057 break;
2058 case CHAR_BRHY: /* '>' and '<' */
2059 if (curvoice->last_note == 0)
2060 goto bad_char;
2061 i = 1;
2062 while (*p == p[-1]) {
2063 i++;
2064 p++;
2066 if (i > 3) {
2067 syntax("Bad broken rhythm", p - 1);
2068 i = 3;
2070 if (p[-1] == '<')
2071 i = -i;
2072 broken_rhythm(&curvoice->last_note->u.note, i);
2073 curvoice->last_note->u.note.brhythm = i;
2074 break;
2075 case CHAR_IGN: /* '*' & '`' */
2076 break;
2077 default:
2078 bad_char:
2079 syntax("Bad character", p - 1);
2080 break;
2084 /*fixme: may we have grace notes across lines?*/
2085 if (char_tb['{'] == CHAR_BAD) {
2086 syntax("No end of grace note sequence", 0);
2087 char_tb['{'] = CHAR_GRACE;
2088 char_tb['}'] = CHAR_BAD;
2089 if (curvoice->last_note != 0)
2090 curvoice->last_note->u.note.word_end = 1;
2091 curvoice->last_note = last_note_sav;
2094 /* add eoln */
2095 s = abc_new(t, 0, 0);
2096 s->type = ABC_T_EOLN;
2097 s->state = abc_state;
2099 return 1;
2102 /* -- parse a note -- */
2103 static unsigned char *parse_note(struct abctune *t,
2104 unsigned char *p)
2106 struct abcsym *s;
2107 unsigned char *q;
2108 int pit, len, acc, nostem;
2109 int chord, sl1, sl2;
2110 int j, m;
2111 int ntie;
2112 signed char tie_pit[MAXHD];
2114 s = abc_new(t, gchord, 0);
2115 s->type = ABC_T_NOTE;
2116 s->state = ABC_S_TUNE;
2117 if (gchord && free_f)
2118 free_f(gchord);
2119 gchord = 0;
2121 if (dc.n > 0) {
2122 memcpy(&s->u.note.dc, &dc, sizeof s->u.note.dc);
2123 dc.n = 0;
2126 if (char_tb['{'] == CHAR_BAD) /* in a grace note sequence */
2127 s->u.note.grace = 1;
2128 else if (curvoice->rplet) { /* start of n-plet */
2129 s->u.note.p_plet = curvoice->pplet;
2130 s->u.note.q_plet = curvoice->qplet;
2131 s->u.note.r_plet = curvoice->rplet;
2132 curvoice->rplet = 0;
2135 /* rest */
2136 switch (*p) {
2137 case 'Z': /* multi-rest */
2138 s->type = ABC_T_MREST;
2139 p++;
2140 len = 1;
2141 if (isdigit(*p)) {
2142 len = strtol(p, 0, 10);
2143 while (isdigit(*p))
2144 p++;
2146 s->u.bar.type = 0;
2147 s->u.bar.len = len;
2148 return p;
2149 case 'y': /* space (BarFly) */
2150 s->type = ABC_T_REST;
2151 s->u.note.invis = 1;
2152 s->u.note.slur_st += curvoice->slur;
2153 curvoice->slur = 0;
2154 return p + 1;
2155 case 'x': /* invisible rest */
2156 s->u.note.invis = 1;
2157 /* fall thru */
2158 case 'z':
2159 s->type = ABC_T_REST;
2160 p = parse_len(p + 1, &len);
2161 s->u.note.lens[0] = len * ulen / BASE_LEN;
2162 if (curvoice->last_note != 0
2163 && curvoice->last_note->u.note.brhythm != 0)
2164 broken_rhythm(&s->u.note,
2165 -curvoice->last_note->u.note.brhythm);
2166 return p;
2169 if (!s->u.note.grace && !lyric_started) {
2170 lyric_started = 1;
2171 s->u.note.lyric_start = 1;
2172 deco_start = s;
2175 chord = 0;
2176 q = p;
2177 if (*p == '[') { /* accept only '[..]' for chord */
2178 chord = 1;
2179 p++;
2182 /* prepare searching the end of ties */
2183 ntie = 0;
2184 if (curvoice->tie != 0) {
2185 for (m = 0; m <= curvoice->tie->u.note.nhd; m++) {
2186 if (curvoice->tie->u.note.ti1[m])
2187 tie_pit[ntie++] = curvoice->tie->u.note.pits[m];
2189 curvoice->tie = 0;
2192 /* get pitch and length */
2193 m = 0;
2194 sl1 = sl2 = 0;
2195 nostem = 0;
2196 for (;;) {
2197 int tmp;
2199 if (chord && *p == '(') {
2200 s->u.note.sl1[m] = ++sl1;
2201 p++;
2203 p = parse_deco(p, &dc); /* for extra decorations within chord */
2204 if (strchr(all_notes, *p) == 0) {
2205 syntax("Not a note", p);
2206 p++;
2207 } else {
2208 p = parse_basic_note(p,
2209 &pit,
2210 &len,
2211 &acc,
2212 &tmp);
2213 if (s->u.note.grace) {
2214 len = len * BASE_LEN / 4 / ulen;
2215 tmp = 0;
2217 s->u.note.pits[m] = pit;
2218 s->u.note.lens[m] = len;
2219 s->u.note.accs[m] = acc;
2220 nostem |= tmp;
2222 for (j = 0; j < ntie; j++) {
2223 if (tie_pit[j] == pit) {
2224 s->u.note.ti2[m] = 1;
2225 tie_pit[j] = -128;
2226 break;
2230 if (chord) {
2231 if (*p == '-') {
2232 s->u.note.ti1[m] = 1;
2233 curvoice->tie = s;
2234 p++;
2236 if (*p == ')') {
2237 s->u.note.sl2[m] = ++sl2;
2238 p++;
2239 if (*p == '-') {
2240 s->u.note.ti1[m] = 1;
2241 p++;
2245 m++;
2248 if (!chord)
2249 break;
2250 if (*p == ']') {
2251 p++;
2252 if (*p == '/' || isdigit(*p)) {
2253 p = parse_len(p, &len);
2254 for (j = 0; j < m; j++) {
2255 tmp = len * s->u.note.lens[j];
2256 s->u.note.lens[j] = tmp / BASE_LEN;
2259 break;
2261 if (*p == '\0') {
2262 syntax("Chord not closed", q);
2263 return p;
2266 s->u.note.stemless = nostem;
2268 /* warn about the bad ties */
2269 if (char_tb['{'] != CHAR_BAD) { /* if not in a grace note sequence */
2270 for (j = 0; j < ntie; j++) {
2271 if (tie_pit[j] != -128)
2272 syntax("Bad tie", p);
2276 if (m == 0) { /* if no note */
2277 if ((t->last_sym = s->prev) == 0)
2278 t->first_sym = 0;
2279 else s->prev->next = 0;
2280 return p;
2282 s->u.note.nhd = m - 1;
2284 if (curvoice->last_note != 0
2285 && curvoice->last_note->u.note.brhythm != 0)
2286 broken_rhythm(&s->u.note,
2287 -curvoice->last_note->u.note.brhythm);
2288 s->u.note.slur_st += curvoice->slur;
2289 curvoice->slur = 0;
2291 return p;
2294 /* -- parse a header -- */
2295 static void parse_header(struct abctune *t,
2296 unsigned char *p,
2297 char *comment)
2299 struct abcsym *s;
2300 unsigned char header_type = *p;
2301 char *error_txt = 0;
2303 s = abc_new(t, p, comment);
2304 s->type = ABC_T_INFO;
2305 s->state = abc_state;
2307 p += 2;
2308 while (isspace(*p))
2309 p++;
2310 switch (header_type) {
2311 case 'd':
2312 case 's':
2313 if (deco_start == 0) {
2314 error_txt = "Erroneous 'd:'/'s:'";
2315 break;
2317 error_txt = parse_decoline(p);
2318 break;
2319 case 'K':
2320 if (abc_state == ABC_S_GLOBAL)
2321 break;
2322 parse_key(p, s);
2323 if (abc_state == ABC_S_HEAD) {
2324 if (ulen == 0)
2325 ulen = BASE_LEN / 8;
2326 abc_state = ABC_S_TUNE;
2328 break;
2329 case 'L':
2330 error_txt = get_len(p, s);
2331 ulen = s->u.length.base_length;
2332 if (abc_state == ABC_S_GLOBAL)
2333 gulen = ulen;
2334 break;
2335 case 'M':
2336 error_txt = parse_meter(p, s);
2337 break;
2338 case 'Q':
2339 error_txt = parse_tempo(p, s);
2340 break;
2341 case 'U':
2342 error_txt = get_user(p, s);
2343 break;
2344 case 'V':
2345 if (abc_state == ABC_S_GLOBAL)
2346 break;
2347 error_txt = parse_voice(p, s);
2348 break;
2349 case 'T':
2350 if (abc_state != ABC_S_GLOBAL)
2351 break;
2352 /* 'T:' may start a new tune without 'X:' */
2353 print_warning("T: without X:");
2354 /* fall thru */
2355 case 'X':
2356 if (abc_state != ABC_S_GLOBAL) {
2357 error_txt = "Previous tune not closed properly";
2358 /*??maybe call end_tune if ABC_S_TUNE??*/
2360 memset(voice_tb, 0, sizeof voice_tb);
2361 nvoice = 0;
2362 curvoice = &voice_tb[0];
2363 abc_state = ABC_S_HEAD;
2364 if (level_f)
2365 level_f(1);
2366 break;
2368 if (error_txt != 0)
2369 syntax(error_txt, p);
2372 /* -- sytax: print message for syntax errror -- */
2373 static void syntax(char *msg,
2374 char *q)
2376 int n, len, m1, m2, pp;
2377 int maxcol = 73;
2379 severity = 1;
2380 n = q - scratch_line;
2381 if ((unsigned) n >= line_length)
2382 n = -1;
2383 print_error(msg, n);
2384 if (n < 0) {
2385 if (q != 0)
2386 fprintf(stderr, " (near '%s')\n", q);
2387 return;
2389 /* printf("\n++++ %s in line %d.%d\n", msg, linenum, n + 1); */
2390 m1 = 0;
2391 m2 = len = line_length - 1;
2392 if (m2 > maxcol) {
2393 if (n < maxcol)
2394 m2 = maxcol;
2395 else {
2396 m1 = n - 20;
2397 m2 = m1 + maxcol;
2398 if (m2 > len)
2399 m2 = len;
2403 fprintf(stderr, "%4d ", linenum);
2404 pp = 6;
2405 if (m1 > 0) {
2406 fprintf(stderr, "...");
2407 pp += 3;
2409 fprintf(stderr, "%*s", m2 - m1, &scratch_line[m1]);
2410 if (m2 < len)
2411 fprintf(stderr, "...");
2412 fprintf(stderr, "\n");
2414 if ((unsigned) n < 200)
2415 fprintf(stderr, "%*s\n", n + pp - m1, "^");
2418 /* -- switch to a new voice overlay -- */
2419 static void vover_new(void)
2421 int voice, mvoice;
2423 mvoice = curvoice - voice_tb;
2424 for (voice = mvoice + 1; voice <= nvoice; voice++)
2425 if (voice_tb[voice].mvoice == mvoice)
2426 break;
2427 if (voice > nvoice) {
2428 if (nvoice >= MAXVOICE) {
2429 syntax("Too many voices", 0);
2430 return;
2432 nvoice = voice;
2433 voice_tb[voice].name[0] = '&';
2434 voice_tb[voice].mvoice = mvoice;
2436 voice_tb[voice].ulen = curvoice->ulen;
2437 voice_tb[voice].add_pitch = curvoice->add_pitch;
2438 curvoice = &voice_tb[voice];