Introduction
Introduction Statistics Contact Development Disclaimer Help
parse.h - abc2ps - A powerful sheet setting tool using the simple abc notation
git clone git://vernunftzentrum.de/abc2ps.git
Log
Files
Refs
---
parse.h (58108B)
---
1 /*
2 * This file is part of abc2ps,
3 * Copyright (C) 1996,1997,1998 Michael Methfessel
4 * See file abc2ps.c for details.
5 */
6
7 /* subroutines connected with parsing the input file */
8
9 /* ----- sytax: print message for syntax errror -------- */
10 void syntax (msg, q)
11 char msg[];
12 char *q;
13 {
14 int i,n,len,m1,m2,pp,qq,maxcol=65;
15
16 if (verbose<=2) printf ("\n");
17 qq=q-p0+1;
18 if (qq<0) qq=0;
19 printf ("+++ %s in line %d.%d \n", msg, linenum, qq);
20 m1=0;
21 m2=len=strlen(p0);
22 n=q-p0;
23 if (m2>maxcol) {
24 if (n<maxcol)
25 m2=maxcol;
26 else {
27 m1=n-10;
28 m2=m1+maxcol;
29 if (m2>len) m2=len;
30 }
31 }
32
33 printf ("%4d ", linenum);
34 pp=5;
35 if (m1>0) { printf ("..."); pp+=3; }
36 for (i=m1;i<m2;i++) printf ("%c", p0[i]);
37 if (m2<len) printf ("...");
38 printf ("\n");
39
40 if (n>=0 && n<200) {
41 for (i=0;i<n+pp-m1;i++) printf(" ");
42 printf ("^\n");
43 }
44 }
45
46 /* ----- isnote: checks char for valid note symbol ----- */
47 int isnote (c)
48 char c;
49 {
50 if (c == '\0') return 0;
51 if (strchr("CDEFGABcdefgab^=_",c)) return 1;
52 return 0;
53 }
54
55 /* ----- zero_sym: init global zero SYMBOL struct ----- */
56 void zero_sym ()
57 {
58 int j;
59 zsym.type = 0;
60 zsym.npitch = 0;
61 zsym.word_st = 0;
62 zsym.word_end = 0;
63 zsym.slur_st = 0;
64 zsym.slur_end = 0;
65 zsym.len = 0;
66 zsym.fullmes = 0;
67 zsym.yadd = 0;
68 zsym.xs = 0;
69 zsym.ys = 0;
70 zsym.stem = 0;
71 zsym.eoln = 0;
72 zsym.ylo = 12;
73 zsym.yhi = 12;
74 zsym.u = 0;
75 zsym.v = 0;
76 zsym.w = 0;
77 zsym.t = 0;
78 zsym.q = 0;
79 zsym.invis = 0;
80 zsym.wl = 0;
81 zsym.wr = 0;
82 zsym.pr = 0;
83 zsym.pl = 0;
84 zsym.p_plet = 0;
85 zsym.q_plet = 0;
86 zsym.r_plet = 0;
87 zsym.gchy = 0;
88 zsym.gr.n = 0;
89 zsym.dc.n = 0;
90 zsym.dc.top = 0;
91 zsym.p = -1;
92 strcpy (zsym.text, "");
93 for (j=0;j<MAXHD;j++) zsym.sl1[j]=zsym.sl2[j]=0;
94
95 for (j=0;j<NWLINE;j++) zsym.wordp[j] = 0;
96 }
97
98 /* ----- add_sym: returns index for new symbol at end of list ---- */
99 int add_sym (type)
100 int type;
101 {
102 int k;
103
104 k=voice[ivc].nsym;
105 if (k>=maxSyms) rxi("Too many symbols; increase maxSyms, now ",maxSyms…
106 voice[ivc].nsym++;
107 symv[ivc][k]=zsym;
108 symv[ivc][k].type = type;
109 return k;
110
111 }
112
113 /* ----- insert_sym: returns index for new symbol inserted at k --- */
114 int insert_sym (type,k)
115 int type,k;
116 {
117 int i,n;
118
119 n=voice[ivc].nsym;
120 if (n>=maxSyms) rxi("insert_sym: maxSyms exceeded: ",maxSyms);
121 for (i=n;i>k;i--) symv[ivc][i]=symv[ivc][i-1];
122 n++;
123 symv[ivc][k]=zsym;
124 symv[ivc][k].type = type;
125 voice[ivc].nsym=n;
126 return k;
127 }
128
129 /* ----- get_xref: get xref from string ----- */
130 int get_xref (str)
131 char str[];
132 {
133
134 int a,ok;
135 char *q;
136
137 if (strlen(str)==0) {
138 wng ("xref string is empty", "");
139 return 0;
140 }
141 q=str;
142 ok=1;
143 while (*q != '\0') {
144 if (!isdig(*q)) ok=0;
145 q++;
146 }
147 if (!ok) {
148 wng ("xref string has invalid symbols: ", str);
149 return 0;
150 }
151
152 sscanf (str, "%d", &a);
153
154 return a;
155 }
156
157 /* ----- set_meter: interpret meter string, store in struct ---- */
158 void set_meter (str,meter)
159 char str[];
160 struct METERSTR *meter;
161 {
162
163 int m1,m2,m1a,m1b,m1c,d,l;
164 char *q;
165 int meter1,meter2,dlen,mflag,lflag;
166 char meter_top[31];
167
168 l=strlen(str);
169 if (l==0) { wng("Empty meter string", ""); return; }
170 if (str[0]=='C') {
171 if (str[1]=='|') {
172 meter1=4;
173 meter2=4;
174 dlen=EIGHTH;
175 mflag=2;
176 strcpy(meter_top,"C");
177 }
178 else {
179 meter1=4;
180 meter2=4;
181 dlen=EIGHTH;
182 mflag=1;
183 strcpy(meter_top,"C");
184 }
185 }
186 else {
187 m1=m2=m1a=m1b=m1c=0;
188 strcpy (meter_top, str);
189 q=strchr(meter_top,'/');
190 if (!q) {
191 wng("Cannot identify meter, missing /: ", str);
192 m1=m2=1;
193 return;
194 }
195 *q='\0';
196 if (strchr(meter_top,'+')) {
197 sscanf(str,"%d+%d+%d/", &m1a, &m1b, &m1c);
198 m1=m1a+m1b+m1c;
199 }
200 else {
201 sscanf(str,"%d %d %d/", &m1a, &m1b, &m1c);
202 m1=m1a; if (m1b>m1) m1=m1b; if (m1c>m1) m1=m1c;
203 if (m1>30) { /* handle things like 78/8 */
204 m1a=m1/100;
205 m1c=m1-100*m1a;
206 m1b=m1c/10;
207 m1c=m1c-10*m1b;
208 m1=m1a; if (m1b>m1) m1=m1b; if (m1c>m1) m1=m1c;
209 }
210 }
211
212 q++;
213 sscanf (q, "%d", &m2);
214 if (m1*m2 == 0) wng("Cannot identify meter: ", str);
215 d=BASE/m2;
216 if (d*m2 != BASE) wng("Meter not recognized: ", str);
217 meter1=m1;
218 meter2=m2;
219 dlen=EIGHTH;
220 if (4*meter1 < 3*meter2) dlen=SIXTEENTH;
221 mflag=0;
222 }
223
224 if (verbose>=4)
225 printf ("Meter <%s> is %d over %d with default length 1/%d\n",
226 str, meter1, meter2, BASE/dlen);
227
228 /* handle old-style change of default length */
229 lflag=0;
230 if (str[l-1]=='s') { dlen=dlen*2; lflag=1; }
231 if (str[l-1]=='l') { dlen=dlen/2; lflag=-1; }
232
233 /* store parsed data in struct */
234 meter->meter1 = meter1;
235 meter->meter2 = meter2;
236 meter->mflag = mflag;
237 meter->dlen = dlen;
238 meter->lflag = lflag;
239 strcpy(meter->top, meter_top);
240 }
241
242
243 /* ----- set_dlen: set default length for parsed notes ---- */
244 void set_dlen (str,meter)
245 char str[];
246 struct METERSTR *meter;
247 {
248 int l1,l2,d,dlen;
249
250 l1=0;
251 l2=1;
252 sscanf(str,"%d/%d ", &l1, &l2);
253 if (l1 == 0) return; /* empty string.. don't change default leng…
254 else {
255 d=BASE/l2;
256 if (d*l2 != BASE) {
257 wng("Length incompatible with BASE, using 1/8: ",str);
258 dlen=BASE/8;
259 }
260 else
261 dlen = d*l1;
262 }
263 if (verbose>=4)
264 printf ("Dlen <%s> sets default note length to %d/%d = 1/%d\n",
265 str, dlen, BASE, BASE/dlen);
266
267 meter->dlen=dlen;
268
269 }
270
271 /* ----- set_keysig: interpret keysig string, store in struct ---- */
272 /* This part was adapted from abc2mtex by Chris Walshaw */
273 /* updated 03 Oct 1997 Wil Macaulay - support all modes */
274 /* Returns 1 if key was actually specified, because then we want
275 to transpose. Returns zero if this is just a clef change. */
276 int set_keysig(s,ks,init)
277 char s[];
278 struct KEYSTR *ks;
279 int init;
280 {
281 int c,sf,j,ok;
282 char w[81];
283 int ktype,add_pitch,root,root_acc;
284
285 /* maybe initialize with key C (used for K field in header) */
286 if (init) {
287 ks->sf = 0;
288 ks->ktype = TREBLE;
289 ks->add_pitch = 0;
290 ks->root = 2;
291 ks->root_acc = A_NT;
292 }
293
294 /* check for "treble" "bass" "alto" with no other information */
295 ktype=ks->ktype;
296 add_pitch=0;
297 if (!strcmp(s,"bass")) {ks->ktype=BASS; return 0; }
298 if (!strcmp(s,"treble")) {ks->ktype=TREBLE; return 0; }
299 if (!strcmp(s,"alto")) {ks->ktype=ALTO; return 0; }
300
301 if (!strcmp(s,"bass+8")) {ks->ktype=BASS; ks->add_pitch=8; return …
302 if (!strcmp(s,"treble+8")) {ks->ktype=TREBLE; ks->add_pitch=8; return …
303 if (!strcmp(s,"alto+8")) {ks->ktype=ALTO; ks->add_pitch=8; return …
304
305 if (!strcmp(s,"bass-8")) {ks->ktype=BASS; ks->add_pitch=-8; return…
306 if (!strcmp(s,"treble-8")) {ks->ktype=TREBLE; ks->add_pitch=-8; return…
307 if (!strcmp(s,"alto-8")) {ks->ktype=ALTO; ks->add_pitch=-8; return…
308
309 c=0;
310 bagpipe=0;
311 switch (s[c]) {
312 case 'F':
313 sf = -1; root=5;
314 break;
315 case 'C':
316 sf = 0; root=2;
317 break;
318 case 'G':
319 sf = 1; root=6;
320 break;
321 case 'D':
322 sf = 2; root=3;
323 break;
324 case 'A':
325 sf = 3; root=0;
326 break;
327 case 'E':
328 sf = 4; root=4;
329 break;
330 case 'B':
331 sf = 5; root=1;
332 break;
333 case 'H':
334 bagpipe=1;
335 c++;
336 if (s[c] == 'P') { sf=0; root=2; }
337 else if (s[c] == 'p') { sf=2; root=3; }
338 else wng("unknown bagpipe-like key: ",s);
339 break;
340 default:
341 wng ("Using C because key not recognised: ", s);
342 sf = 0; root=2;
343 }
344 c++;
345
346 root_acc=A_NT;
347 if (s[c] == '#') {
348 sf += 7;
349 c += 1;
350 root_acc=A_SH;
351 } else if (s[c] == 'b') {
352 sf -= 7;
353 c += 1;
354 root_acc=A_FT;
355 }
356
357 /* loop over blank-delimited words: get the next token in lower case */
358 for (;;) {
359 while (s[c] == ' ') c++;
360 if (s[c]=='\0') break;
361
362 j=0;
363 while ((s[c]!=' ') && (s[c]!='\0')) { w[j]=tolower(s[c]); c++; j++; }
364 w[j]='\0';
365
366 /* now identify this word */
367
368 /* first check for mode specifier */
369 if ((strncmp(w,"mix",3)) == 0) {
370 sf -= 1;
371 ok = 1;
372 /* dorian mode on the second note (D in C scale) */
373 } else if ((strncmp(w,"dor",3)) == 0) {
374 sf -= 2;
375 ok = 1;
376 /* phrygian mode on the third note (E in C scale) */
377 } else if ((strncmp(w,"phr",3)) == 0) {
378 sf -= 4;
379 ok = 1;
380 /* lydian mode on the fourth note (F in C scale) */
381 } else if ((strncmp(w,"lyd",3)) == 0) {
382 sf += 1;
383 ok = 1;
384 /* locrian mode on the seventh note (B in C scale) */
385 } else if ((strncmp(w,"loc",3)) == 0) {
386 sf -= 5;
387 ok = 1;
388 /* major and ionian are the same ks */
389 } else if ((strncmp(w,"maj",3)) == 0) {
390 ok = 1;
391 } else if ((strncmp(w,"ion",3)) == 0) {
392 ok = 1;
393 /* aeolian, m, minor are the same ks - sixth note (A in C scale) */
394 } else if ((strncmp(w,"aeo",3)) == 0) {
395 sf -= 3;
396 ok = 1;
397 } else if ((strncmp(w,"min",3)) == 0) {
398 sf -= 3;
399 ok = 1;
400 } else if ((strcmp(w,"m")) == 0) {
401 sf -= 3;
402 ok = 1;
403 }
404
405 /* check for trailing "bass" "treble" "alto" */
406 else if (!strcmp(w,"bass")) {
407 ktype=BASS;
408 }
409 else if (!strcmp(w,"treble")) {
410 ktype=TREBLE;
411 }
412 else if (!strcmp(w,"alto")) {
413 ktype=ALTO;
414 }
415
416 /* check for "+8" or "-8" */
417 else if (!strcmp(w,"+8")) {
418 add_pitch=7;
419 }
420 else if (!strcmp(w,"-8")) {
421 add_pitch=-7;
422 }
423 else wng("Unknown token in key specifier: ",w);
424
425 } /* end of loop over blank-delimted words */
426
427 if (verbose>=4) printf ("Key <%s> gives sharpsflats %d, type %d\n",
428 s, sf, ktype);
429
430 /* copy to struct */
431 ks->sf = sf;
432 ks->ktype = ktype;
433 ks->add_pitch = add_pitch;
434 ks->root = root;
435 ks->root_acc = root_acc;
436
437 return 1;
438
439 }
440
441 /* ----- get_halftones: figure out how by many halftones to transpose --…
442 /* In the transposing routines: pitches A..G are coded as with 0..7 */
443 int get_halftones (key, transpose)
444 struct KEYSTR key;
445 char transpose[];
446 {
447 int pit_old,pit_new,direction,stype,root_new,racc_new,nht;
448 int root_old, racc_old;
449 char *q;
450 /* pit_tab associates true pitches 0-11 with letters A-G */
451 int pit_tab[] = {0,2,3,5,7,8,10};
452
453 if (strlen(transpose)==0) return 0;
454 root_old=key.root;
455 racc_old=key.root_acc;
456
457 /* parse specification for target key */
458 q=transpose;
459 direction=0;
460
461 if (*q=='^') {
462 direction=1; q++;
463 } else if (*q=='_') {
464 direction=-1; q++;
465 }
466 stype=1;
467 if (strchr("ABCDEFG",*q)) {
468 root_new=*q-'A'; q++; stype=2;
469 } else if (strchr("abcdefg",*q)) {
470 root_new=*q-'a'; q++; stype=2;
471 }
472
473 /* first case: offset was given directly as numeric argument */
474 if (stype==1) {
475 sscanf(q,"%d", &nht);
476 if (direction<0) nht=-nht;
477 if (nht==0) {
478 if (direction<0) nht=-12;
479 if (direction>0) nht=+12;
480 }
481 return nht;
482 }
483
484 /* second case: root of target key was specified explicitly */
485 racc_new=0;
486 if (*q=='b') {
487 racc_new=A_FT; q++;
488 } else if (*q=='#') {
489 racc_new=A_SH; q++;
490 } else if (*q!='\0')
491 wng ("expecting accidental in transpose spec: ", transpose);
492
493 /* get pitch as number from 0-11 for root of old key */
494 pit_old=pit_tab[root_old];
495 if (racc_old==A_FT) pit_old--;
496 if (racc_old==A_SH) pit_old++;
497 if (pit_old<0) pit_old+=12;
498 if (pit_old>11) pit_old-=12;
499
500 /* get pitch as number from 0-11 for root of new key */
501 pit_new=pit_tab[root_new];
502 if (racc_new==A_FT) pit_new--;
503 if (racc_new==A_SH) pit_new++;
504 if (pit_new<0) pit_new+=12;
505 if (pit_new>11) pit_new-=12;
506
507 /* number of halftones is difference */
508 nht=pit_new-pit_old;
509 if (direction==0) {
510 if (nht>6) nht-=12;
511 if (nht<-5) nht+=12;
512 }
513 if (direction>0 && nht<=0) nht+=12;
514 if (direction<0 && nht>=0) nht-=12;
515
516 return nht;
517
518 }
519
520
521
522 /* ----- shift_key: make new key by shifting nht halftones --- */
523 void shift_key (sf_old,nht,sfnew,addt)
524 int sf_old,nht,*sfnew,*addt;
525 {
526 int sf_new,r_old,r_new,add_t, dh,dr;
527 int skey_tab[] = {2,6,3,0,4,1,5,2};
528 int fkey_tab[] = {2,5,1,4,0,3,6,2};
529 char root_tab[]={'A','B','C','D','E','F','G'};
530
531 /* get sf_new by adding 7 for each halftone, then reduce mod 12 */
532 sf_new=sf_old+nht*7;
533 sf_new=(sf_new+240)%12;
534 if (sf_new>=6) sf_new=sf_new-12;
535
536 /* get old and new root in ionian mode, shift is difference */
537 r_old=2;
538 if (sf_old>0) r_old=skey_tab[sf_old];
539 if (sf_old<0) r_old=fkey_tab[-sf_old];
540 r_new=2;
541 if (sf_new>0) r_new=skey_tab[sf_new];
542 if (sf_new<0) r_new=fkey_tab[-sf_new];
543 add_t=r_new-r_old;
544
545 /* fix up add_t to get same "decade" as nht */
546 dh=(nht+120)/12; dh=dh-10;
547 dr=(add_t+70)/7; dr=dr-10;
548 add_t=add_t+7*(dh-dr);
549
550 if (verbose>=8)
551 printf ("shift_key: sf_old=%d new %d root: old %c new %c shift by…
552 sf_old, sf_new, root_tab[r_old], root_tab[r_new], add_t);
553
554 *sfnew=sf_new;
555 *addt=add_t;
556
557 }
558
559
560 /* ----- set_transtab: setup for transposition by nht halftones --- */
561 void set_transtab (nht,key)
562 int nht;
563 struct KEYSTR *key;
564 {
565 int a,b,sf_old,sf_new,add_t,i,j,acc_old,acc_new,root_old,root_acc;
566 /* for each note A..G, these tables tell how many sharps (resp. flats)
567 the keysig must have to get the accidental on this note. Phew. */
568 int sh_tab[] = {5,7,2,4,6,1,3};
569 int fl_tab[] = {3,1,6,4,2,7,5};
570 /* tables for pretty printout only */
571 char root_tab[]={'A','B','C','D','E','F','G'};
572 char acc_tab[][3] ={"bb","b "," ","# ","x "};
573 char c1[6],c2[6],c3[6];
574
575 /* nop if no transposition is wanted */
576 if (nht==0) {
577 key->add_transp=0;
578 for (i=0;i<7;i++) key->add_acc[i]=0;
579 return;
580 }
581
582 /* get new sharps_flats and shift of numeric pitch; copy to key */
583 sf_old = key->sf;
584 root_old = key->root;
585 root_acc = key->root_acc;
586 shift_key (sf_old, nht, &sf_new, &add_t);
587 key->sf = sf_new;
588 key->add_transp = add_t;
589
590 /* set up table for conversion of accidentals */
591 for (i=0;i<7;i++) {
592 j=i+add_t;
593 j=(j+70)%7;
594 acc_old=0;
595 if ( sf_old >= sh_tab[i]) acc_old=1;
596 if (-sf_old >= fl_tab[i]) acc_old=-1;
597 acc_new=0;
598 if ( sf_new >= sh_tab[j]) acc_new=1;
599 if (-sf_new >= fl_tab[j]) acc_new=-1;
600 key->add_acc[i]=acc_new-acc_old;
601 }
602
603 /* printout keysig change */
604 if (verbose>=3) {
605 i=root_old;
606 j=i+add_t;
607 j=(j+70)%7;
608 acc_old=0;
609 if ( sf_old >= sh_tab[i]) acc_old=1;
610 if (-sf_old >= fl_tab[i]) acc_old=-1;
611 acc_new=0;
612 if ( sf_new >= sh_tab[j]) acc_new=1;
613 if (-sf_new >= fl_tab[j]) acc_new=-1;
614 strcpy(c3,"s"); if (nht==1 || nht==-1) strcpy(c3,"");
615 strcpy(c1,""); strcpy(c2,"");
616 if (acc_old==-1) strcpy(c1,"b"); if (acc_old==1) strcpy(c1,"#");
617 if (acc_new==-1) strcpy(c2,"b"); if (acc_new==1) strcpy(c2,"#");
618 printf ("Transpose root from %c%s to %c%s (shift by %d halftone%s)\n…
619 root_tab[i],c1,root_tab[j],c2,nht,c3);
620 }
621
622 /* printout full table of transformations */
623 if (verbose>=4) {
624 printf ("old & new keysig conversions\n");
625 for (i=0;i<7;i++) {
626 j=i+add_t;
627 j=(j+70)%7;
628 acc_old=0;
629 if ( sf_old >= sh_tab[i]) acc_old=1;
630 if (-sf_old >= fl_tab[i]) acc_old=-1;
631 acc_new=0;
632 if ( sf_new >= sh_tab[j]) acc_new=1;
633 if (-sf_new >= fl_tab[j]) acc_new=-1;
634 printf("%c%s-> %c%s ", root_tab[i],acc_tab[acc_old+2],
635 root_tab[j],acc_tab[acc_new+2]);
636 for (a=-1;a<=1;a++) {
637 b=a+key->add_acc[i];
638 printf ("%c%s-> %c%s ", root_tab[i],acc_tab[a+2],
639 root_tab[j],acc_tab[b+2]);
640 }
641 printf ("\n");
642 }
643 }
644
645 }
646
647 /* ----- do_transpose: transpose numeric pitch and accidental --- */
648 void do_transpose (key,pitch,acc)
649 struct KEYSTR key;
650 int *pitch, *acc;
651 {
652 int pitch_old,pitch_new,sf_old,sf_new,acc_old,acc_new,i,j;
653
654 pitch_old = *pitch;
655 acc_old = *acc;
656 pitch_new=pitch_old+key.add_transp;
657 i=(pitch_old+70)%7;
658 j=(pitch_new+70)%7;
659
660 if (acc_old) {
661 if (acc_old==A_DF) sf_old=-2;
662 if (acc_old==A_FT) sf_old=-1;
663 if (acc_old==A_NT) sf_old=0 ;
664 if (acc_old==A_SH) sf_old=1;
665 if (acc_old==A_DS) sf_old=2;
666 sf_new=sf_old+key.add_acc[i];
667 if (sf_new==-2) acc_new=A_DF;
668 if (sf_new==-1) acc_new=A_FT;
669 if (sf_new== 0) acc_new=A_NT;
670 if (sf_new== 1) acc_new=A_SH;
671 if (sf_new== 2) acc_new=A_DS;
672 }
673 else {
674 acc_new=0;
675 }
676 *pitch = pitch_new;
677 *acc = acc_new;
678 }
679
680
681 /* ----- gch_transpose: transpose guitar chord string in gch --- */
682 void gch_transpose (key)
683 struct KEYSTR key;
684 {
685 char *q,*r;
686 char str[201];
687 int root_old,root_new,sf_old,sf_new,ok;
688 char root_tab[]={'A','B','C','D','E','F','G'};
689 char root_tub[]={'a','b','c','d','e','f','g'};
690
691 if (halftones==0) return;
692
693 /* try to avoid some common abuses of gchord string */
694 if (strstr(gch,"capo")) return;
695 if (strstr(gch,"Capo")) return;
696 if (strstr(gch,"Fine")) return;
697 if (strstr(gch,"fine")) return;
698
699 q=gch;
700 r=str;
701
702 for (;;) {
703 while (*q==' ' || *q=='(') { *r=*q; q++; r++; }
704 if (*q=='\0') break;
705 ok=0;
706 if (strchr("ABCDEFG",*q)) {
707 root_old=*q-'A'; q++; ok=1;
708 } else if (strchr("abcdefg",*q)) {
709 root_old=*q-'a'; q++; ok=2;
710 }
711
712 if (ok) {
713 sf_old=0;
714 if (*q=='b') { sf_old=-1; q++; }
715 if (*q=='#') { sf_old= 1; q++; }
716 root_new=root_old+key.add_transp;
717 root_new=(root_new+28)%7;
718 sf_new=sf_old+key.add_acc[root_old];
719 if (ok==1) { *r=root_tab[root_new]; r++; }
720 if (ok==2) { *r=root_tub[root_new]; r++; }
721 if (sf_new==-1) { *r='b'; r++; }
722 if (sf_new== 1) { *r='#'; r++; }
723 }
724
725 while (*q!=' ' && *q!='/' && *q!='\0') {*r=*q; q++; r++; }
726 if (*q=='/') {*r=*q; q++; r++; }
727
728 }
729
730 *r='\0';
731 /*| printf("tr_ch: <%s> <%s>\n", gch, str); |*/
732
733 strcpy (gch,str);
734
735 }
736
737
738 /* ----- init_parse_params: initialize variables for parsing --- */
739 void init_parse_params ()
740 {
741 int i;
742
743 slur=0;
744 voice[0].end_slur=0;
745 nwpool=nwline=0;
746 ntinext=0;
747
748 /* for continuation after output: reset nsym, switch to first voice */
749 for (i=0;i<nvoice;i++) {
750 voice[i].nsym=0;
751 voice[i].insert_btype=0;
752 voice[i].end_slur=0;
753 }
754
755 ivc=0;
756
757 word=0;
758 carryover=0;
759 last_note=last_real_note=-1;
760 pplet=qplet=rplet=0;
761 num_ending=0;
762 mes1=mes2=0;
763 strcpy (gch, "");
764
765 }
766
767 /* ----- add_text ---- */
768 void add_text (str,type)
769 char str[];
770 int type;
771 {
772 if (do_mode!=DO_OUTPUT) return;
773 if (ntext>=NTEXT) {
774 wng ("No more room for text line <%s>", str);
775 return;
776 }
777 strcpy (text[ntext], str);
778 text_type[ntext]=type;
779 ntext++;
780 }
781
782 /* ----- reset_info ---- */
783 void reset_info (inf)
784 struct ISTRUCT *inf;
785 {
786
787 /* reset all info fields except info.xref */
788
789 strcpy(inf->parts, "");
790 strcpy(inf->area, "");
791 strcpy(inf->book, "");
792 inf->ncomp=0;
793 strcpy(inf->disc, "");
794 strcpy(inf->group, "");
795 strcpy(inf->hist, "");
796 strcpy(inf->info, "");
797 strcpy(inf->key, "C");
798 strcpy(inf->meter, "4/4");
799 strcpy(inf->notes, "");
800 strcpy(inf->orig, "");
801 strcpy(inf->rhyth, "");
802 strcpy(inf->src, "");
803 /* strcpy(inf->title, "(untitled)"); */
804 strcpy(inf->title, "");
805 strcpy(inf->title2, "");
806 strcpy(inf->title3, "");
807 strcpy(inf->trans, "");
808 strcpy(inf->tempo, "");
809 }
810
811 /* ----- get_default_info: set info to default, except xref field --- */
812 void get_default_info ()
813 {
814 char savestr[STRL];
815
816 strcpy (savestr, info.xref);
817 info=default_info;
818 strcpy (info.xref, savestr);
819
820 }
821
822 /* ----- is_info_field: identify any type of info field ---- */
823 int is_info_field (str)
824 char str[];
825 {
826 if (strlen(str)<2) return 0;
827 if (str[1]!=':') return 0;
828 if (str[0]=='|') return 0; /* |: at start of music line */
829 return 1;
830 }
831
832 /* ----- is_end_line: identify eof ----- */
833 int is_end_line (str)
834 char str[];
835 {
836 if (strlen(str)<3) return 0;
837 if (str[0]=='E' && str[1]=='N' && str[2]=='D') return 1;
838 return 0;
839 }
840
841 /* ----- is_pseudocomment ----- */
842 int is_pseudocomment (str)
843 char str[];
844 {
845 if (strlen(str)<2) return 0;
846 if ((str[0]=='%')&&(str[1]=='%')) return 1;
847 return 0;
848 }
849
850 /* ----- is_comment ----- */
851 int is_comment (str)
852 char str[];
853 {
854 if (strlen(str)<1) return 0;
855 if (str[0]=='%') return 1;
856 if (str[0]=='\\') return 1;
857 return 0;
858 }
859
860
861 /* ----- trim_title: move trailing "The" to front ------------ */
862 void trim_title (s,s0)
863 char s[],s0[];
864 {
865 char *q;
866 char rest[81],str[301];
867 int done;
868
869 strcpy (str, s0);
870 done=0;
871
872 if ((q=strchr(str,','))) {
873 if (*q != '\0') {
874 strip (rest,q+1);
875 if (!strcmp(rest,"The")) {
876 strcpy (s, rest);
877 *q = '\0';
878 strcat (s, " ");
879 strcat (s, str);
880 done=1;
881 }
882 }
883 }
884
885 if (!done) strcpy (s,s0);
886
887 }
888
889
890 /* ----- find_voice ----- */
891 int find_voice (vid,new)
892 char vid[];
893 int *new;
894 {
895 int i;
896
897 for (i=0;i<nvoice;i++)
898 if (!strcmp(vid,voice[i].id)) {
899 *new=0;
900 return i;
901 }
902
903 i=nvoice;
904 if (i>=maxVc)
905 rxi("Too many voices; use -maxv to increase limit, now ",maxVc);
906
907 strcpy(voice[i].id, vid);
908 strcpy(voice[i].name, "");
909 strcpy(voice[i].sname, "");
910 voice[i].stems = 0;
911 voice[i].staves = 0;
912 voice[i].brace = 0;
913 voice[i].bracket = 0;
914 voice[i].do_gch = 1;
915 voice[i].select = 1;
916 voice[i].sep=0.0;
917 voice[i].meter = default_meter;
918 voice[i].key = default_key;
919 voice[i].nsym = 0;
920 nvoice++;
921 if (verbose>5)
922 printf ("Make new voice %d with id \"%s\"\n", i,voice[i].id);
923 *new=1;
924 return i;
925
926 }
927
928 /* ----- switch_voice: read spec for a voice, return voice number ----- …
929 int switch_voice (str)
930 char str[];
931 {
932 int j,np,new,ap;
933 char *r,*q;
934 char t1[201],t2[201];
935
936 if (!do_this_tune) return 0;
937
938 j=-1;
939
940 /* start loop over vioce options: parse t1=t2 */
941 r=str;
942 np=0;
943 for (;;) {
944 while (*r == ' ') r++;
945 if (*r=='\0') break;
946 strcpy(t1,"");
947 strcpy(t2,"");
948 q=t1;
949 while (*r!=' ' && *r!='\0' && *r!='=') { *q=*r; r++; q++; }
950 *q='\0';
951 if (*r=='=') {
952 r++;
953 q=t2;
954 if (*r=='"') {
955 r++;
956 while (*r!='"' && *r!='\0') { *q=*r; r++; q++; }
957 if (*r=='"') r++;
958 }
959 else {
960 while (*r!=' ' && *r!='\0') { *q=*r; r++; q++; }
961 }
962 *q='\0';
963 }
964 np++;
965
966 /* interpret the parsed option. First case is identifier. */
967 if (np==1) j=find_voice (t1,&new);
968
969 else { /* interpret option */
970 if (j<0) bug("j invalid in switch_voice",1);
971 if (!strcmp(t1,"name") || !strcmp(t1,"nm"))
972 strcpy(voice[j].name, t2);
973
974 else if (!strcmp(t1,"sname") || !strcmp(t1,"snm"))
975 strcpy(voice[j].sname, t2);
976
977 else if (!strcmp(t1,"staves") || !strcmp(t1,"stv"))
978 voice[j].staves = atoi(t2);
979
980 else if (!strcmp(t1,"brace") || !strcmp(t1,"brc"))
981 voice[j].brace = atoi(t2);
982
983 else if (!strcmp(t1,"bracket") || !strcmp(t1,"brk"))
984 voice[j].bracket = atoi(t2);
985
986 else if (!strcmp(t1,"gchords") || !strcmp(t1,"gch"))
987 g_logv (str,t2,&voice[j].do_gch);
988
989 /* for sspace: add 2000 as flag if not incremental */
990 else if (!strcmp(t1,"space") || !strcmp(t1,"spc")) {
991 g_unum (str,t2,&voice[j].sep);
992 if (t2[0]!='+' && t2[0]!='-') voice[j].sep += 2000.0;
993 }
994
995 else if (!strcmp(t1,"clef") || !strcmp(t1,"cl")) {
996 ap=0;
997 if (!strcmp(t2,"treble")) voice[j].key.ktype=TREBLE;
998 else if (!strcmp(t2,"treble+8")) {voice[j].key.ktype=TREBLE; ap…
999 else if (!strcmp(t2,"treble-8")) {voice[j].key.ktype=TREBLE; ap…
1000 else if (!strcmp(t2,"treble+16")) {voice[j].key.ktype=TREBLE; ap…
1001 else if (!strcmp(t2,"treble-16")) {voice[j].key.ktype=TREBLE; ap…
1002 else if (!strcmp(t2,"bass")) voice[j].key.ktype=BASS;
1003 else if (!strcmp(t2,"bass+8")) {voice[j].key.ktype=BASS; ap=+…
1004 else if (!strcmp(t2,"bass-8")) {voice[j].key.ktype=BASS; ap=-…
1005 else if (!strcmp(t2,"bass+16")) {voice[j].key.ktype=BASS; ap=+…
1006 else if (!strcmp(t2,"bass-16")) {voice[j].key.ktype=BASS; ap=-…
1007 else if (!strcmp(t2,"alto")) voice[j].key.ktype=ALTO;
1008 else if (!strcmp(t2,"alto+8")) {voice[j].key.ktype=ALTO; ap=+…
1009 else if (!strcmp(t2,"alto-8")) {voice[j].key.ktype=ALTO; ap=-…
1010 else if (!strcmp(t2,"alto+16")) {voice[j].key.ktype=ALTO; ap=+…
1011 else if (!strcmp(t2,"alto-16")) {voice[j].key.ktype=ALTO; ap=-…
1012 else wng("Unknown clef in voice spec: ",t2);
1013 voice[j].key.add_pitch=ap;
1014 }
1015 else if (!strcmp(t1,"stems") || !strcmp(t1,"stm")) {
1016 if (!strcmp(t2,"up")) voice[j].stems=1;
1017 else if (!strcmp(t2,"down")) voice[j].stems=-1;
1018 else if (!strcmp(t2,"free")) voice[j].stems=0;
1019 else wng("Unknown stem setting in voice spec: ",t2);
1020 }
1021 else wng("Unknown option in voice spec: ",t1);
1022 }
1023
1024 }
1025
1026 /* if new voice was initialized, save settings im meter0, key0 */
1027 if (new) {
1028 voice[j].meter0 = voice[j].meter;
1029 voice[j].key0 = voice[j].key;
1030 }
1031
1032 if (verbose>7)
1033 printf ("Switch to voice %d <%s> <%s> <%s> clef=%d\n",
1034 j,voice[j].id,voice[j].name,voice[j].sname,
1035 voice[j].key.ktype);
1036
1037 nsym0=voice[j].nsym; /* set nsym0 to decide about eoln later.. ugly */
1038 return j;
1039
1040 }
1041
1042
1043 /* ----- info_field: identify info line, store in proper place ---- */
1044 /* switch within_block: either goes to default_info or info.
1045 Only xref ALWAYS goes to info. */
1046 int info_field (str)
1047 char str[];
1048 {
1049 char t[STRL];
1050 struct ISTRUCT *inf;
1051 int i;
1052
1053 for (i=0;i<strlen(str);i++) if (str[i]=='%') str[i]='\0';
1054
1055 if (within_block) {
1056 inf=&info;
1057 }
1058 else {
1059 inf=&default_info;
1060 }
1061
1062 if (strlen(str)<2) return 0;
1063 if (str[1]!=':') return 0;
1064 if (str[0]=='|') return 0; /* |: at start of music line */
1065
1066 if (str[0]=='X') {
1067 strip (info.xref, &str[2]);
1068 xrefnum=get_xref(info.xref);
1069 return XREF;
1070 }
1071
1072 else if (str[0]=='A') strip (inf->area, &str[2]);
1073 else if (str[0]=='B') strip (inf->book, &str[2]);
1074 else if (str[0]=='C') {
1075 if (inf->ncomp>=NCOMP)
1076 wng("Too many composer lines","");
1077 else {
1078 strip (inf->comp[inf->ncomp],&str[2]);
1079 inf->ncomp++;
1080 }
1081 }
1082 else if (str[0]=='D') {
1083 strip (inf->disc, &str[2]);
1084 add_text (&str[2], TEXT_D);
1085 }
1086
1087 else if (str[0]=='G') strip (inf->group, &str[2]);
1088 else if (str[0]=='H') {
1089 strip (inf->hist, &str[2]);
1090 add_text (&str[2], TEXT_H);
1091 return HISTORY;
1092 }
1093 else if (str[0]=='W') {
1094 add_text (&str[2], TEXT_W);
1095 return WORDS;
1096 }
1097 else if (str[0]=='I') strip (inf->info, &str[2]);
1098 else if (str[0]=='K') {
1099 strip (inf->key, &str[2]);
1100 return KEY;
1101 }
1102 else if (str[0]=='L') {
1103 strip (inf->len, &str[2]);
1104 return DLEN;
1105 }
1106 else if (str[0]=='M') {
1107 strip (inf->meter, &str[2]);
1108 return METER;
1109 }
1110 else if (str[0]=='N') {
1111 strip (inf->notes, &str[2]);
1112 add_text (&str[2], TEXT_N);
1113 }
1114 else if (str[0]=='O') strip (inf->orig, &str[2]);
1115 else if (str[0]=='R') strip (inf->rhyth, &str[2]);
1116 else if (str[0]=='P') {
1117 strip (inf->parts, &str[2]);
1118 return PARTS;
1119 }
1120 else if (str[0]=='S') strip (inf->src, &str[2]);
1121 else if (str[0]=='T') {
1122 strip (t, &str[2]);
1123 numtitle++;
1124 if (numtitle>3) numtitle=3;
1125 if (numtitle==1) trim_title (inf->title, t);
1126 else if (numtitle==2) trim_title (inf->title2, t);
1127 else if (numtitle==3) trim_title (inf->title3, t);
1128 return TITLE;
1129 }
1130 else if (str[0]=='V') {
1131 strip (lvoiceid, &str[2]);
1132 return VOICE;
1133 }
1134 else if (str[0]=='Z') {
1135 strip (inf->trans, &str[2]);
1136 add_text (&str[2], TEXT_Z);
1137 }
1138 else if (str[0]=='Q') {
1139 strip (inf->tempo, &str[2]);
1140 return TEMPO;
1141 }
1142
1143 else if (str[0]=='E') ;
1144
1145 else {
1146 return 0;
1147 }
1148
1149 return INFO;
1150 }
1151
1152 /* ----- append_meter: add meter to list of symbols -------- */
1153 void append_meter (meter)
1154 struct METERSTR meter;
1155 {
1156 int kk;
1157
1158 kk=add_sym(TIMESIG);
1159 symv[ivc][kk]=zsym;
1160 symv[ivc][kk].type = TIMESIG;
1161 symv[ivc][kk].u = meter.meter1;
1162 symv[ivc][kk].v = meter.meter2;
1163 symv[ivc][kk].w = meter.mflag;
1164 strcpy(symv[ivc][kk].text,meter.top);
1165
1166 }
1167
1168 /* ----- append_key_change: append change of key to sym list ------ */
1169 void append_key_change(oldkey,newkey)
1170 struct KEYSTR oldkey,newkey;
1171 {
1172 int n1,n2,t1,t2,kk;
1173
1174 n1=oldkey.sf;
1175 t1=A_SH;
1176 if (n1<0) { n1=-n1; t1=A_FT; }
1177 n2=newkey.sf;
1178 t2=A_SH;
1179
1180 if (newkey.ktype != oldkey.ktype) { /* clef change */
1181 kk=add_sym(CLEF);
1182 symv[ivc][kk].u=newkey.ktype;
1183 symv[ivc][kk].v=1;
1184 }
1185
1186 if (n2<0) { n2=-n2; t2=A_FT; }
1187 if (t1==t2) { /* here if old and new have same type */
1188 if (n2>n1) { /* more new symbols ..*/
1189 kk=add_sym(KEYSIG); /* draw all of them */
1190 symv[ivc][kk].u=1;
1191 symv[ivc][kk].v=n2;
1192 symv[ivc][kk].w=100;
1193 symv[ivc][kk].t=t1;
1194 }
1195 else if (n2<n1) { /* less new symbols .. */
1196 kk=add_sym(KEYSIG); /* draw all new symbols and neutrals …
1197 symv[ivc][kk].u=1;
1198 symv[ivc][kk].v=n1;
1199 symv[ivc][kk].w=n2+1;
1200 symv[ivc][kk].t=t2;
1201 }
1202 else return;
1203 }
1204 else { /* here for change s->f or f->s */
1205 kk=add_sym(KEYSIG); /* neutralize all old symbols */
1206 symv[ivc][kk].u=1;
1207 symv[ivc][kk].v=n1;
1208 symv[ivc][kk].w=1;
1209 symv[ivc][kk].t=t1;
1210 kk=add_sym(KEYSIG); /* add all new symbols */
1211 symv[ivc][kk].u=1;
1212 symv[ivc][kk].v=n2;
1213 symv[ivc][kk].w=100;
1214 symv[ivc][kk].t=t2;
1215 }
1216
1217 }
1218
1219
1220
1221 /* ----- numeric_pitch ------ */
1222 /* adapted from abc2mtex by Chris Walshaw */
1223 int numeric_pitch(note)
1224 char note;
1225 {
1226
1227 if (note=='z')
1228 return 14;
1229 if (note >= 'C' && note <= 'G')
1230 return(note-'C'+16+voice[ivc].key.add_pitch);
1231 else if (note >= 'A' && note <= 'B')
1232 return(note-'A'+21+voice[ivc].key.add_pitch);
1233 else if (note >= 'c' && note <= 'g')
1234 return(note-'c'+23+voice[ivc].key.add_pitch);
1235 else if (note >= 'a' && note <= 'b')
1236 return(note-'a'+28+voice[ivc].key.add_pitch);
1237 printf ("numeric_pitch: cannot identify <%c>\n", note);
1238 return(0);
1239 }
1240
1241 /* ----- symbolic_pitch: translate numeric pitch back to symbol ------ */
1242 int symbolic_pitch(pit,str)
1243 int pit;
1244 char str[];
1245 {
1246 int p,r,s;
1247 char ltab1[7] = {'C','D','E','F','G','A','B'};
1248 char ltab2[7] = {'c','d','e','f','g','a','b'};
1249
1250 p=pit-16;
1251 r=(p+700)%7;
1252 s=(p-r)/7;
1253
1254 if (p<7) {
1255 sprintf (str,"%c,,,,,",ltab1[r]);
1256 str[1-s]='\0';
1257 }
1258 else {
1259 sprintf (str,"%c'''''",ltab2[r]);
1260 str[s]='\0';
1261 }
1262 }
1263
1264 /* ----- handle_inside_field: act on info field inside body of tune --- …
1265 void handle_inside_field(type)
1266 int type;
1267 {
1268 struct KEYSTR oldkey;
1269 int rc;
1270
1271 if (type==METER) {
1272 if (nvoice==0) ivc=switch_voice (DEFVOICE);
1273 set_meter (info.meter,&voice[ivc].meter);
1274 append_meter (voice[ivc].meter);
1275 }
1276
1277 else if (type==DLEN) {
1278 if (nvoice==0) ivc=switch_voice (DEFVOICE);
1279 set_dlen (info.len, &voice[ivc].meter);
1280 }
1281
1282 else if (type==KEY) {
1283 if (nvoice==0) ivc=switch_voice (DEFVOICE);
1284 oldkey=voice[ivc].key;
1285 rc=set_keysig(info.key,&voice[ivc].key,0);
1286 if (rc) set_transtab (halftones,&voice[ivc].key);
1287 append_key_change(oldkey,voice[ivc].key);
1288 }
1289
1290 else if (type==VOICE) {
1291 ivc=switch_voice (lvoiceid);
1292 }
1293
1294 }
1295
1296
1297
1298 /* ----- parse_uint: parse for unsigned integer ----- */
1299 int parse_uint ()
1300 {
1301 int number,ndig;
1302 char num[21];
1303
1304 if (!isdig(*p)) return 0;
1305 ndig=0;
1306 while (isdig(*p)) {
1307 num[ndig]=*p;
1308 ndig++;
1309 num[ndig]=0;
1310 p++;
1311 }
1312 sscanf (num, "%d", &number);
1313 if (db>3) printf (" parsed unsigned int %d\n", number);
1314 return number;
1315
1316 }
1317
1318 /* ----- parse_bar: parse for some kind of bar ---- */
1319 int parse_bar ()
1320 {
1321 int k;
1322
1323 parse_gchord ();
1324
1325 /* special cases: [1 or [2 without a preceeding bar, [| */
1326 if (*p=='[') {
1327 if ((*(p+1)=='1') || (*(p+1)=='2')) {
1328 k=add_sym (BAR);
1329 symv[ivc][k].u=B_INVIS;
1330 symv[ivc][k].v=1;
1331 if (*(p+1)=='2') symv[ivc][k].v=2;
1332 p=p+2;
1333 return 1;
1334 }
1335 }
1336
1337 /* identify valid standard bar types */
1338 if (*p == '|') {
1339 p++;
1340 if (*p == '|') {
1341 k=add_sym (BAR);
1342 symv[ivc][k].u=B_DBL;
1343 p++;
1344 }
1345 else if (*p == ':') {
1346 k=add_sym(BAR);
1347 symv[ivc][k].u=B_LREP;
1348 p++;
1349 }
1350 else if (*p==']') { /* code |] for fat end bar */
1351 k=add_sym(BAR);
1352 symv[ivc][k].u=B_FAT2;
1353 p=p+1;
1354 }
1355 else {
1356 k=add_sym(BAR);
1357 symv[ivc][k].u=B_SNGL;
1358 }
1359 }
1360 else if (*p == ':') {
1361 p++;
1362 if (*p == '|') {
1363 k=add_sym(BAR);
1364 symv[ivc][k].u=B_RREP;
1365 p++;
1366 }
1367 else if (*p == ':') {
1368 k=add_sym(BAR);
1369 symv[ivc][k].u=B_DREP;
1370 p++; }
1371 else {
1372 syntax ("Syntax error parsing bar", p-1);
1373 return 0;
1374 }
1375 }
1376
1377 else if ((*p=='[') && (*(p+1)=='|') && (*(p+2)==']')) { /* code [|] i…
1378 k=add_sym(BAR);
1379 symv[ivc][k].u=B_INVIS;
1380 p=p+3;
1381 }
1382
1383 else if ((*p=='[') && (*(p+1)=='|')) { /* code [| for thick-thin ba…
1384 k=add_sym(BAR);
1385 symv[ivc][k].u=B_FAT1;
1386 p=p+2;
1387 }
1388
1389 else return 0;
1390
1391 strcpy(symv[ivc][k].text,"");
1392 if (strlen(gch)>0) {
1393 strcpy (symv[ivc][k].text, gch);
1394 strcpy (gch, "");
1395 }
1396
1397 /* see if valid bar is followed by specifier for first or second endin…
1398 if (*p=='1') { symv[ivc][k].v=1; p++; }
1399 else if (*p=='2') { symv[ivc][k].v=2; p++; }
1400 else if ((*p=='[') && (*(p+1)=='1')) { symv[ivc][k].v=1; p=p+2; }
1401 else if ((*p=='[') && (*(p+1)=='2')) { symv[ivc][k].v=2; p=p+2; }
1402 else if ((*p==' ') && (*(p+1)=='[') && (*(p+2)=='1'))
1403 { symv[ivc][k].v=1; p=p+3; }
1404 else if ((*p==' ') && (*(p+1)=='[') && (*(p+2)=='2'))
1405 { symv[ivc][k].v=2; p=p+3; }
1406
1407 return 1;
1408 }
1409
1410 /* ----- parse_space: parse for whitespace ---- */
1411 int parse_space ()
1412 {
1413 int rc;
1414
1415 rc=0;
1416 while ((*p==' ')||(*p=='\t')) {
1417 rc=1;
1418 p++;
1419 }
1420 if (db>3) if (rc) printf (" parsed whitespace\n");
1421 return rc;
1422 }
1423
1424 /* ----- parse_esc: parse for escape sequence ----- */
1425 int parse_esc ()
1426 {
1427
1428 int nseq;
1429 char *pp;
1430
1431 if (*p == '\\') { /* try for \...\ sequence */
1432 p++;
1433 nseq=0;
1434 while ((*p!='\\') && (*p!=0)) {
1435 escseq[nseq]=*p;
1436 nseq++;
1437 p++;
1438 }
1439 if (*p == '\\') {
1440 p++;
1441 escseq[nseq]=0;
1442 if (db>3) printf (" parsed esc sequence <%s>\n", escseq);
1443 return ESCSEQ;
1444 }
1445 else {
1446 if (cfmt.breakall) return DUMMY;
1447 if (db>3) printf (" parsed esc to EOL.. continuation\n");
1448 }
1449 return CONTINUE;
1450 }
1451
1452 /* next, try for [..] sequence */
1453 if ((*p=='[') && (*(p+1)>='A') && (*(p+1)<='Z') && (*(p+2)==':')) {
1454 pp=p;
1455 p++;
1456 nseq=0;
1457 while ((*p!=']') && (*p!=0)) {
1458 escseq[nseq]=*p;
1459 nseq++;
1460 p++;
1461 }
1462 if (*p == ']') {
1463 p++;
1464 escseq[nseq]=0;
1465 if (db>3) printf (" parsed esc sequence <%s>\n", escseq);
1466 return ESCSEQ;
1467 }
1468 syntax ("Escape sequence [..] not closed", pp);
1469 return ESCSEQ;
1470 }
1471 return 0;
1472 }
1473
1474
1475 /* ----- parse_nl: parse for newline ----- */
1476 int parse_nl ()
1477 {
1478
1479 if ((*p == '\\')&&(*(p+1)=='\\')) {
1480 p+=2;
1481 return 1;
1482 }
1483 else
1484 return 0;
1485 }
1486
1487 /* ----- parse_gchord: parse guitar chord, save in buffer ----- */
1488 int parse_gchord ()
1489 {
1490 char *q;
1491 int n;
1492
1493 if (*p != '"') return 0;
1494
1495 q=p;
1496 p++;
1497 n=strlen(gch);
1498 if (n > 0) syntax ("Overwrite unused guitar chord", q);
1499
1500 while ((*p != '"') && (*p != 0)) {
1501 gch[n]=*p;
1502 n++;
1503 if (n >= 200) {
1504 syntax ("String for guitar chord too long", q);
1505 return 1;
1506 }
1507 p++;
1508 }
1509 if (*p == 0) {
1510 syntax ("EOL reached while parsing guitar chord", q);
1511 return 1;
1512 }
1513 p++;
1514 gch[n]=0;
1515 if (db>3) printf(" parse guitar chord <%s>\n", gch);
1516
1517 /*| gch_transpose (voice[ivc].key); |*/
1518
1519 return 1;
1520 }
1521
1522
1523 /* ----- parse_deco: parse for decoration on note ----- */
1524 int parse_deco (dtype)
1525 int dtype[10];
1526 {
1527 int deco,n;
1528
1529 n=0;
1530
1531 for (;;) {
1532 deco=0;
1533 if (*p == '~') {
1534 if (DECO_IS_ROLL) deco=D_ROLL;
1535 else deco=D_GRACE;
1536 }
1537 if (*p == '.') deco=D_STACC;
1538 if (*p == 'J') deco=D_SLIDE;
1539 if (*p == 'M') deco=D_EMBAR;
1540 if (*p == 'H') deco=D_HOLD;
1541 if (*p == 'R') deco=D_ROLL;
1542 if (*p == 'T') deco=D_TRILL;
1543 if (*p == 'u') deco=D_UPBOW;
1544 if (*p == 'v') deco=D_DOWNBOW;
1545 if (*p == 'K') deco=D_HAT;
1546 if (*p == 'k') deco=D_ATT;
1547
1548 if (deco) {
1549 p++;
1550 dtype[n]=deco;
1551 n++;
1552 }
1553 else
1554 break;
1555 }
1556
1557 return n;
1558 }
1559
1560
1561 /* ----- parse_length: parse length specifer for note or rest --- */
1562 int parse_length ()
1563 {
1564 int len,fac;
1565
1566 len=voice[ivc].meter.dlen; /* start with default length */
1567
1568 if (len<=0) printf ("!!! parse_len: got len=%d\n", len);
1569
1570
1571 if (isdig(*p)) { /* multiply note length */
1572 fac=parse_uint ();
1573 if (fac==0) fac=1;
1574 len *= fac;
1575 }
1576
1577 if (*p=='/') { /* divide note length */
1578 while (*p=='/') {
1579 p++;
1580 if (isdig(*p))
1581 fac=parse_uint();
1582 else
1583 fac=2;
1584 if (len%fac) {
1585 syntax ("Bad length divisor", p-1);
1586 return len;
1587 }
1588 len=len/fac;
1589 }
1590 }
1591
1592 return len;
1593
1594 }
1595
1596 /* ----- parse_grace_sequence --------- */
1597 int parse_grace_sequence (pgr,agr)
1598 int pgr[],agr[];
1599 {
1600
1601 char *p0;
1602 int n,len;
1603
1604 p0=p;
1605 if (*p != '{') return 0;
1606 p++;
1607
1608 n=0;
1609 while (*p != '}') {
1610 if (*p == '\0') {
1611 syntax ("Unbalanced grace note sequence", p0);
1612 return 0;
1613 }
1614 if (!isnote(*p)) {
1615 syntax ("Unexpected symbol in grace note sequence", p);
1616 p++;
1617 }
1618 agr[n]=0;
1619 if (*p == '=') agr[n]=A_NT;
1620 if (*p == '^') {
1621 if (*(p+1)=='^') { agr[n]=A_DS; p++; }
1622 else agr[n]=A_SH;
1623 }
1624 if (*p == '_') {
1625 if (*(p+1)=='_') { agr[n]=A_DF; p++; }
1626 else agr[n]=A_FT;
1627 }
1628 if (agr[n]) p++;
1629
1630 pgr[n] = numeric_pitch(*p);
1631 p++;
1632 while (*p == '\'') { pgr[n] += 7; p++; }
1633 while (*p == ',') { pgr[n] -= 7; p++; }
1634
1635 do_transpose (voice[ivc].key, &pgr[n], &agr[n]);
1636
1637 len=parse_length (); /* ignore any length specifier */
1638 n++;
1639 }
1640
1641 p++;
1642 return n;
1643 }
1644
1645
1646 /* ----- idfy_note: set head type, dots, flags for one note --- */
1647 int idfy_note (s)
1648 struct SYMBOL *s;
1649 {
1650 int head,base,len,flags,dots;
1651
1652 if (s->len==0) s->len=s->lens[0];
1653 len=s->len;
1654
1655 base=WHOLE;
1656 if (len>=WHOLE) base=WHOLE;
1657 else if (len>=HALF) base=HALF;
1658 else if (len>=QUARTER) base=QUARTER;
1659 else if (len>=EIGHTH) base=EIGHTH;
1660 else if (len>=SIXTEENTH) base=SIXTEENTH;
1661 else if (len>=THIRTYSECOND) base=THIRTYSECOND;
1662 else if (len>=SIXTYFOURTH) base=SIXTYFOURTH;
1663 else return 1;
1664
1665 if (base==WHOLE) head=H_OVAL;
1666 else if (base==HALF) head=H_EMPTY;
1667 else head=H_FULL;
1668
1669 if (base==SIXTYFOURTH) flags=4;
1670 else if (base==THIRTYSECOND) flags=3;
1671 else if (base==SIXTEENTH) flags=2;
1672 else if (base==EIGHTH) flags=1;
1673 else flags=0;
1674
1675 dots=0;
1676 if (len==base) dots=0;
1677 else if (2*len==3*base) dots=1;
1678 else if (4*len==7*base) dots=2;
1679 else if (8*len==15*base) dots=3;
1680 else return 2;
1681
1682 /*| printf ("idfy_note: length %d gives head %d, dots %d, flags %d\n",…
1683 /*| len,head,dots,flags); |*/
1684
1685 s->head=head;
1686 s->dots=dots;
1687 s->flags=flags;
1688 return 0;
1689 }
1690
1691
1692
1693 /* ----- identify_note ----- */
1694 void identify_note (s,q)
1695 struct SYMBOL *s;
1696 char *q;
1697 {
1698 int rc;
1699
1700 rc = idfy_note (s);
1701 if (rc==1) syntax("Cannot identify head for note",q);
1702 if (rc==2) syntax("Cannot handle note length for note",q);
1703
1704 /* set flag if duration equals length of one measure */
1705 if (nvoice>0) {
1706 if (s->len==(WHOLE*voice[ivc].meter.meter1)/voice[ivc].meter.meter2)
1707 s->fullmes=1;
1708 }
1709 }
1710
1711
1712 /* ----- double_note: change note length for > or < char --- */
1713 /* Note: if symv[ivc][i] is a chord, the length shifted to the following
1714 note is taken from the first note head. Problem: the crazy syntax
1715 permits different lengths within a chord. */
1716 void double_note (i,num,sign,q)
1717 int i,num,sign;
1718 char *q;
1719 {
1720 int m,shift,j,len;
1721
1722 if ((symv[ivc][i].type!=NOTE) && (symv[ivc][i].type!=REST))
1723 bug("sym is not NOTE or REST in double_note", 1);
1724
1725 shift=0;
1726 len=symv[ivc][i].lens[0];
1727 for (j=0;j<num;j++) {
1728 len=len/2;
1729 shift -= sign*len;
1730 symv[ivc][i].len += sign*len;
1731 for (m=0;m<symv[ivc][i].npitch;m++) symv[ivc][i].lens[m] += sign*len;
1732 }
1733 identify_note (&symv[ivc][i],q);
1734 carryover += shift;
1735 }
1736
1737 /* ----- parse_basic_note: parse note or rest with pitch and length --*/
1738 int parse_basic_note (pitch,length,accidental)
1739 int *pitch,*length,*accidental;
1740 {
1741 int pit,len,acc;
1742
1743 acc=pit=0; /* look for accidental sign */
1744 if (*p == '=') acc=A_NT;
1745 if (*p == '^') {
1746 if (*(p+1)=='^') { acc=A_DS; p++; }
1747 else acc=A_SH;
1748 }
1749 if (*p == '_') {
1750 if (*(p+1)=='_') { acc=A_DF; p++; }
1751 else acc=A_FT;
1752 }
1753
1754 if (acc) {
1755 p++;
1756 if (!strchr("CDEFGABcdefgab",*p)) {
1757 syntax("Missing note after accidental", p-1);
1758 return 0;
1759 }
1760 }
1761 if (!isnote(*p)) {
1762 syntax ("Expecting note", p);
1763 p++;
1764 return 0;
1765 }
1766
1767 pit= numeric_pitch(*p); /* basic pitch */
1768 p++;
1769
1770 while (*p == '\'') { /* eat up following ' chars */
1771 pit += 7;
1772 p++;
1773 }
1774
1775 while (*p == ',') { /* eat up following , chars */
1776 pit -= 7;
1777 p++;
1778 }
1779
1780 len=parse_length();
1781
1782 do_transpose (voice[ivc].key, &pit, &acc);
1783
1784 *pitch=pit;
1785 *length=len;
1786 *accidental=acc;
1787
1788 if (db>3) printf (" parsed basic note,"
1789 "length %d/%d = 1/%d, pitch %d\n",
1790 len,BASE,BASE/len,pit);
1791
1792 return 1;
1793
1794 }
1795
1796
1797 /* ----- parse_note: parse for one note or rest with all trimmings --- */
1798 int parse_note ()
1799 {
1800 int k,deco,i,chord,m,type,rc,sl1,sl2,j;
1801 int pitch,length,accidental,invis;
1802 int ngr,pgr[30],agr[30],dtype[30];
1803 char *q,*q0;
1804
1805 ngr=parse_grace_sequence(pgr,agr); /* grace notes */
1806
1807 parse_gchord(); /* permit chord after graces */
1808
1809 deco=parse_deco(dtype); /* decorations */
1810
1811 parse_gchord(); /* permit chord after deco */
1812
1813 chord=0; /* determine if chord */
1814 q=p;
1815 if ((*p=='+') || (*p=='[')) { chord=1; p++; }
1816
1817 type=invis=0;
1818 if (isnote(*p)) type=NOTE;
1819 if (chord && (*p=='(')) type=NOTE;
1820 if (chord && (*p==')')) type=NOTE; /* this just for better error msg…
1821 if ((*p=='z')||(*p=='Z')) type=REST;
1822 if ((*p=='x')||(*p=='X')) {type=REST; invis=1; }
1823 if (!type) return 0;
1824
1825 k=add_sym(type); /* add new symbol to list */
1826
1827
1828 symv[ivc][k].dc.n=deco; /* copy over pre-parsed stuff */
1829 for (i=0;i<deco;i++)
1830 symv[ivc][k].dc.t[i]=dtype[i];
1831 symv[ivc][k].gr.n=ngr;
1832 for (i=0;i<ngr;i++) {
1833 symv[ivc][k].gr.p[i]=pgr[i];
1834 symv[ivc][k].gr.a[i]=agr[i];
1835 }
1836 if (strlen(gch)>0) {
1837 gch_transpose (voice[ivc].key);
1838 strcpy (symv[ivc][k].text, gch);
1839 strcpy (gch, "");
1840 }
1841
1842 q0=p;
1843 if (type==REST) {
1844 p++;
1845 symv[ivc][k].lens[0] = parse_length();
1846 symv[ivc][k].npitch=1;
1847 symv[ivc][k].invis=invis;
1848 if (db>3) printf (" parsed rest, length %d/%d = 1/%d\n",
1849 symv[ivc][k].lens[0],BASE,BASE/symv[ivc][k].lens[0…
1850 }
1851 else {
1852 m=0; /* get pitch and length */
1853 sl1=sl2=0;
1854 for (;;) {
1855 if (chord && (*p=='(')) {
1856 sl1++;
1857 symv[ivc][k].sl1[m]=sl1;
1858 p++;
1859 }
1860 deco=parse_deco(dtype); /* for extra decorations within chord …
1861 for (i=0;i<deco;i++) symv[ivc][k].dc.t[i+symv[ivc][k].dc.n]=dtype[…
1862 symv[ivc][k].dc.n += deco;
1863
1864 rc=parse_basic_note (&pitch,&length,&accidental);
1865 if (rc==0) { voice[ivc].nsym--; return 0; }
1866 symv[ivc][k].pits[m] = pitch;
1867 symv[ivc][k].lens[m] = length;
1868 symv[ivc][k].accs[m] = accidental;
1869 symv[ivc][k].ti1[m] = symv[ivc][k].ti2[m] = 0;
1870 for (j=0;j<ntinext;j++)
1871 if (tinext[j]==symv[ivc][k].pits[m]) symv[ivc][k].ti2[m]=1;
1872
1873 if (chord && (*p=='-')) {symv[ivc][k].ti1[m]=1; p++;}
1874
1875 if (chord && (*p==')')) {
1876 sl2++;
1877 symv[ivc][k].sl2[m]=sl2;
1878 p++;
1879 }
1880
1881 if (chord && (*p=='-')) {symv[ivc][k].ti1[m]=1; p++;}
1882
1883 m++;
1884
1885 if (!chord) break;
1886 if ((*p=='+')||(*p==']')) {
1887 p++;
1888 break;
1889 }
1890 if (*p=='\0') {
1891 if (chord) syntax ("Chord not closed", q);
1892 return type;
1893 }
1894 }
1895 ntinext=0;
1896 for (j=0;j<m;j++)
1897 if (symv[ivc][k].ti1[j]) {
1898 tinext[ntinext]=symv[ivc][k].pits[j];
1899 ntinext++;
1900 }
1901 symv[ivc][k].npitch=m;
1902 }
1903
1904 for (m=0;m<symv[ivc][k].npitch;m++) { /* add carryover from > or < */
1905 if (symv[ivc][k].lens[m]+carryover<=0) {
1906 syntax("> leads to zero or negative note length",q0);
1907 }
1908 else
1909 symv[ivc][k].lens[m] += carryover;
1910 }
1911 carryover=0;
1912
1913 if (db>3) printf (" parsed note, decos %d, text <%s>\n",
1914 symv[ivc][k].dc.n, symv[ivc][k].text);
1915
1916
1917 symv[ivc][k].yadd=0;
1918 if (voice[ivc].key.ktype==BASS) symv[ivc][k].yadd=-6;
1919 if (voice[ivc].key.ktype==ALTO) symv[ivc][k].yadd=-3;
1920 identify_note (&symv[ivc][k],q0);
1921 return type;
1922 }
1923
1924
1925 /* ----- parse_sym: parse a symbol and return its type -------- */
1926 int parse_sym ()
1927 {
1928 int i;
1929
1930 if (parse_gchord()) return GCHORD;
1931 if (parse_bar()) return BAR;
1932 if (parse_space()) return SPACE;
1933 if (parse_nl()) return NEWLINE;
1934 if ((i=parse_esc())) return i;
1935 if ((i=parse_note())) return i;
1936 if (parse_nl()) return NEWLINE;
1937 return 0;
1938 }
1939
1940 /* ----- add_wd ----- */
1941 char *add_wd(str)
1942 char str[];
1943 {
1944 char *rp;
1945 int l;
1946
1947 l=strlen(str);
1948 if (l==0) return 0;
1949 if (nwpool+l+1>NWPOOL)
1950 rx ("Overflow while parsing vocals; increase NWPOOL and recompile.",…
1951
1952 strcpy(wpool+nwpool, str);
1953 rp=wpool+nwpool;
1954 nwpool=nwpool+l+1;
1955 return rp;
1956 }
1957
1958 /* ----- parse_vocals: parse words below a line of music ----- */
1959 /* Use '^' to mark a '-' between syllables - hope nobody needs '^' ! */
1960 int parse_vocals (line)
1961 char line[];
1962 {
1963 int isym;
1964 char *c,*c1,*w;
1965 char word[81];
1966
1967 if ((line[0]!='w') || (line[1]!=':')) return 0;
1968 p0=line;
1969
1970 isym=nsym0-1;
1971 c=line+2;
1972 for (;;) {
1973 while(*c==' ') c++;
1974 if (*c=='\0') break;
1975 c1=c;
1976 if ((*c=='_') || (*c=='*') || (*c=='|') || (*c=='-')) {
1977 word[0]=*c;
1978 if (*c=='-') word[0]='^';
1979 word[1]='\0';
1980 c++;
1981 }
1982 else {
1983 w=word;
1984 *w='\0';
1985 while ((*c!=' ') && (*c!='\0')) {
1986 if ((*c=='_') || (*c=='*') || (*c=='|')) break;
1987 if (*c=='-') {
1988 if (*(c-1) != '\\') break;
1989 w--;
1990 *w='-';
1991 }
1992 *w=*c; w++; c++;
1993 }
1994 if (*c=='-') { *w='^' ; w++; c++; }
1995 *w='\0';
1996 }
1997
1998 /* now word contains a word, possibly with trailing '^',
1999 or one of the special characters * | _ - */
2000
2001 if (!strcmp(word,"|")) { /* skip forward to next bar */
2002 isym++;
2003 while ((symv[ivc][isym].type!=BAR) && (isym<voice[ivc].nsym)) isym…
2004 if (isym>=voice[ivc].nsym)
2005 { syntax("Not enough bar lines for |",c1); break; }
2006 }
2007
2008 else { /* store word in next note */
2009 w=word;
2010 while (*w!='\0') { /* replace * and ~ by space */
2011 if ((*w=='*') || (*w=='~')) *w=' ';
2012 w++;
2013 }
2014 isym++;
2015 while ((symv[ivc][isym].type!=NOTE) && (isym<voice[ivc].nsym)) isy…
2016 if (isym>=voice[ivc].nsym)
2017 { syntax ("Not enough notes for words",c1); break; }
2018 symv[ivc][isym].wordp[nwline]=add_wd(word);
2019 }
2020
2021 if (*c=='\0') break;
2022 }
2023
2024 nwline++;
2025 return 1;
2026 }
2027
2028
2029 /* ----- parse_music_line: parse a music line into symbols ----- */
2030 int parse_music_line (line)
2031 char line[];
2032 {
2033 int type,num,nbr,n,itype,i,nsym00;
2034 char msg[81];
2035 char *p1,*pmx;
2036
2037 if (nvoice==0) ivc=switch_voice (DEFVOICE);
2038 if (ivc>=nvoice) bug ("Trying to parse undefined voice",1);
2039
2040 nwline=0;
2041 nsym0=voice[ivc].nsym;
2042 nsym00=nsym0;
2043
2044 nbr=0;
2045 p=p0=line;
2046 pmx=p+strlen(p);
2047
2048 while (*p != 0) {
2049 if (p>pmx) break; /* emergency exit */
2050 type=parse_sym();
2051 n=voice[ivc].nsym;
2052 i=n-1;
2053 if ((db>4) && type)
2054 printf (" sym[%d] code (%d,%d)\n",
2055 n-1,symv[ivc][n-1].type,symv[ivc][n-1].u);
2056
2057 if (type==NEWLINE) {
2058 if ((n>0) && !cfmt.continueall && !cfmt.barsperstaff) {
2059 symv[ivc][i].eoln=1;
2060 if (word) {
2061 symv[ivc][last_note].word_end=1;
2062 word=0;
2063 }
2064 }
2065 }
2066
2067 if (type==ESCSEQ) {
2068 if (db>3)
2069 printf ("Handle escape sequence <%s>\n", escseq);
2070 itype=info_field (escseq);
2071 handle_inside_field (itype);
2072 }
2073
2074 if (type==REST) {
2075 if (pplet) { /* n-plet can start on rest */
2076 symv[ivc][i].p_plet=pplet;
2077 symv[ivc][i].q_plet=qplet;
2078 symv[ivc][i].r_plet=rplet;
2079 pplet=0;
2080 }
2081 last_note=i; /* need this so > and < work */
2082 p1=p;
2083 }
2084
2085 if (type==NOTE) {
2086 if (!word) {
2087 symv[ivc][i].word_st=1;
2088 word=1;
2089 }
2090 symv[ivc][i].slur_st+=nbr;
2091 nbr=0;
2092 if (voice[ivc].end_slur) symv[ivc][i].slur_end++;
2093 voice[ivc].end_slur=0;
2094
2095 if (pplet) { /* start of n-plet */
2096 symv[ivc][i].p_plet=pplet;
2097 symv[ivc][i].q_plet=qplet;
2098 symv[ivc][i].r_plet=rplet;
2099 pplet=0;
2100 }
2101 last_note=last_real_note=i;
2102 p1=p;
2103 }
2104
2105 if (word && ((type==BAR)||(type==SPACE))) {
2106 if (last_real_note>=0) symv[ivc][last_real_note].word_end=1;
2107 word=0;
2108 }
2109
2110 if (!type) {
2111
2112 if (*p == '-') { /* a-b tie */
2113 symv[ivc][last_note].slur_st++;
2114 voice[ivc].end_slur=1;
2115 p++;
2116 }
2117
2118 else if (*p == '(') {
2119 p++;
2120 if (isdig(*p)) {
2121 pplet=*p-'0'; qplet=0; rplet=pplet;
2122 p++;
2123 if (*p == ':') {
2124 p++;
2125 if (isdig(*p)) { qplet=*p-'0'; p++; }
2126 if (*p == ':') {
2127 p++;
2128 if (isdig(*p)) { rplet=*p-'0'; p++; }
2129 }
2130 }
2131 }
2132 else {
2133 nbr++;
2134 }
2135 }
2136 else if (*p == ')') {
2137 if (last_note>0)
2138 symv[ivc][last_note].slur_end++;
2139 else
2140 syntax ("Unexpected symbol",p);
2141 p++;
2142 }
2143 else if (*p == '>') {
2144 num=1;
2145 p++;
2146 while (*p == '>') { num++; p++; }
2147 if (last_note<0)
2148 syntax ("No note before > sign", p);
2149 else
2150 double_note (last_note, num, 1, p1);
2151 }
2152 else if (*p == '<') {
2153 num=1;
2154 p++;
2155 while (*p == '<') { num++; p++; }
2156 if (last_note<0)
2157 syntax ("No note before < sign", p);
2158 else
2159 double_note (last_note, num, -1, p1);
2160 }
2161 else if (*p == '*') /* ignore stars for now */
2162 p++;
2163 else if (*p == '!') /* ditto for '!' */
2164 p++;
2165 else {
2166 if (*p != '\0')
2167 sprintf (msg, "Unexpected symbol \'%c\'", *p);
2168 else
2169 sprintf (msg, "Unexpected end of line");
2170 syntax (msg, p);
2171 p++;
2172 }
2173 }
2174 }
2175
2176 /* maybe set end-of-line marker, if symbols were added */
2177 n=voice[ivc].nsym;
2178
2179 if (n>nsym0) {
2180 symv[ivc][n-1].eoln=1;
2181 if (type==CONTINUE) symv[ivc][n-1].eoln=0;
2182 if (cfmt.barsperstaff) symv[ivc][n-1].eoln=0;
2183 if (cfmt.continueall) symv[ivc][n-1].eoln=0;
2184 }
2185
2186
2187
2188 /* break words at end of line */
2189 if (word && (symv[ivc][n-1].eoln==1)) {
2190 symv[ivc][last_note].word_end=1;
2191 word=0;
2192 }
2193
2194 if (vb>9)
2195 printf ("Parsed music symbols %d to %d for voice %d\n",
2196 nsym00,voice[ivc].nsym-1,ivc);
2197
2198 return MUSIC;
2199
2200 }
2201
2202 /* ----- is_selected: check selection for current info fields ---- */
2203 int is_selected (xref_str,npat,pat,select_all,search_field)
2204 int npat,select_all,search_field;
2205 char xref_str[],pat[][STRL1];
2206 {
2207 int i,j,a,b,m;
2208
2209 /* true if select_all or if no selectors given */
2210 if (select_all) return 1;
2211 if (str_isblank(xref_str) && (npat==0)) return 1;
2212
2213 for (i=0;i<npat;i++) { /*patterns */
2214 if (search_field==S_COMPOSER) {
2215 for (j=0;j<info.ncomp;j++) {
2216 if (!m) m=match(info.comp[j],pat[i]);
2217 }
2218 }
2219 else if (search_field==S_SOURCE)
2220 m=match(info.src,pat[i]);
2221 else if (search_field==S_RHYTHM)
2222 m=match(info.rhyth,pat[i]);
2223 else {
2224 m=match(info.title,pat[i]);
2225 if ((!m) && (numtitle>=2)) m=match(info.title2,pat[i]);
2226 if ((!m) && (numtitle>=3)) m=match(info.title3,pat[i]);
2227 }
2228 if (m) return 1;
2229 }
2230
2231 /* check xref against string of numbers */
2232 p=xref_str;
2233 while (*p != 0) {
2234 parse_space();
2235 a=parse_uint();
2236 if (!a) return 0; /* can happen if invalid chars in string …
2237 parse_space();
2238 if (*p == '-') {
2239 p++;
2240 parse_space();
2241 b=parse_uint();
2242 if (!b) {
2243 if (xrefnum>=a) return 1;
2244 }
2245 else
2246 for (i=a;i<=b;i++) if (xrefnum==i) return 1;
2247 }
2248 else {
2249 if (xrefnum==a) return 1;
2250 }
2251 if (*p == ',') p++;
2252 }
2253
2254 return 0;
2255
2256 }
2257
2258 /* ----- rehash_selectors: split selectors into patterns and xrefs -- */
2259 int rehash_selectors (sel_str, xref_str, pat)
2260 char sel_str[], xref_str[];
2261 char pat[][STRL1];
2262 {
2263 char *q;
2264 char arg[501];
2265 int i,npat;
2266
2267 npat=0;
2268 strcpy (xref_str, "");
2269 q=sel_str;
2270
2271 i=0;
2272 while (1) {
2273 if ((*q==' ') || (*q=='\0')) {
2274 arg[i]='\0';
2275 i=0;
2276 if (!str_isblank(arg)) {
2277 if (arg[0]=='-') /* skip any flags */
2278 ;
2279 else if (is_xrefstr(arg)) {
2280 strcat(xref_str, arg);
2281 strcat(xref_str, " ");
2282 }
2283 else { /* pattern with * or + */
2284 if ((strchr(arg,'*')) || (strchr(arg,'+'))) {
2285 strcpy(pat[npat],arg);
2286 }
2287 else { /* simple pattern */
2288 strcpy(pat[npat],"*");
2289 strcat(pat[npat],arg);
2290 strcat(pat[npat],"*");
2291 }
2292 npat++;
2293 }
2294 }
2295 }
2296 else {
2297 arg[i]=*q;
2298 i++;
2299 }
2300 if (*q=='\0') break;
2301 q++;
2302 }
2303 return npat;
2304 }
2305
2306
2307 /* ----- decomment_line: cut off after % ----- */
2308 void decomment_line (ln)
2309 char ln[];
2310 {
2311 int i;
2312
2313 for (i=0;i<strlen(ln);i++) if (ln[i]=='%') ln[i]='\0';
2314
2315 }
2316
2317
2318 /* ----- get_line: read line, do first operations on it ----- */
2319 int get_line (fp,ln)
2320 FILE *fp;
2321 char ln[];
2322 {
2323 int l;
2324
2325 strcpy (ln, "");
2326 if (feof(fp)) return 0;
2327
2328 abc2ps_getline(ln, BSIZE, fp);
2329 /*| fgets(ln, BSIZE, fp); |*/
2330 linenum++;
2331 l=strlen(ln);
2332 if (l>STRL) {
2333 if (verbose<=2) printf ("\n");
2334 printf ("+++ Line %d too long, truncate from %d to %d chars\n",
2335 linenum, l, STRL);
2336 l=STRL-1;
2337 ln[l]='\0';
2338 }
2339 if (is_end_line(ln)) return 0;
2340 if (ln[l-1]=='\n') ln[l-1]='\0';
2341
2342 if ((verbose>=7) || (vb>=10) ) printf ("%3d %s \n", linenum, ln);
2343
2344 return 1;
2345
2346 }
2347
2348
2349 /* ----- read_line: returns type of line scanned --- */
2350 int read_line (fp,line)
2351 FILE *fp;
2352 char line[BSIZE];
2353 {
2354 int type,nsym0;
2355
2356 if (!get_line(fp,line)) return E_O_F;
2357
2358 if (str_isblank(line)) return BLANK;
2359 if (is_pseudocomment(line)) return PSCOMMENT;
2360 if (is_comment(line)) return COMMENT;
2361 decomment_line (line);
2362
2363 if ((type=info_field(line))) {
2364 /* skip after history field. Nightmarish syntax, that. */
2365 if (type != HISTORY)
2366 return type;
2367 else {
2368 for (;;) {
2369 if (! get_line(fp,line)) return E_O_F;
2370 if (str_isblank(line)) return BLANK;
2371 if (is_info_field(line)) break;
2372 add_text (line, TEXT_H);
2373 }
2374 type=info_field (line);
2375 return type;
2376 }
2377 }
2378
2379 if (do_this_tune) {
2380 if (parse_vocals(line)) return MWORDS;
2381 }
2382
2383 return MUSIC;
2384
2385 }
2386
2387 /* ----- do_index: print index of abc file ------ */
2388 void do_index(fp,xref_str,npat,pat,select_all,search_field)
2389 FILE *fp;
2390 int npat,select_all,search_field;
2391 char xref_str[],pat[][STRL1];
2392 {
2393 int type,within_tune;
2394 char line[BSIZE];
2395
2396 linenum=0;
2397 verbose=vb;
2398 numtitle=0;
2399 write_history=0;
2400 within_tune=within_block=do_this_tune=0;
2401 reset_info (&default_info);
2402 info=default_info;
2403
2404 for (;;) {
2405 if (!get_line(fp,line)) break;
2406 if (is_comment(line)) continue;
2407 decomment_line (line);
2408 type=info_field (line);
2409
2410 switch (type) {
2411
2412 case XREF:
2413 if (within_block)
2414 printf ("+++ Tune %d not closed properly \n", xrefnum);
2415 numtitle=0;
2416 within_tune=0;
2417 within_block=1;
2418 ntext=0;
2419 break;
2420
2421 case KEY:
2422 if (!within_block) break;
2423 if (!within_tune) {
2424 tnum2++;
2425 if (is_selected (xref_str,npat,pat,select_all,search_field)) {
2426 printf (" %-4d %-5s %-4s", xrefnum, info.key, info.meter);
2427 if (search_field==S_SOURCE) printf (" %-15s", info.src…
2428 else if (search_field==S_RHYTHM) printf (" %-8s", info.rhy…
2429 else if (search_field==S_COMPOSER) printf (" %-15s", info.com…
2430 if (numtitle==3)
2431 printf (" %s - %s - %s", info.title,info.title2,info.title3…
2432 if (numtitle==2) printf (" %s - %s", info.title, info.title2);
2433 if (numtitle==1) printf (" %s", info.title);
2434
2435 printf ("\n");
2436 tnum1++;
2437 }
2438 within_tune=1;
2439 }
2440 break;
2441
2442 }
2443
2444 if (str_isblank(line)) {
2445 if (within_block && !within_tune)
2446 printf ("+++ Header not closed in tune %d\n", xrefnum);
2447 within_tune=0;
2448 within_block=0;
2449 info=default_info;
2450 }
2451 }
2452 if (within_block && !within_tune)
2453 printf ("+++ Header not closed in for tune %d\n", xrefnum);
2454
2455 }
2456
2457
2458
2459
2460
You are viewing proxied material from vernunftzentrum.de. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.