/* ** CC2GC -- Chord Chart to Guitar Chord conversion ** psl 12/85 */ #include #define MAXCH 256 #define NAMELEN 16 #define MINOCT -1 #define MAXOCT 9 char noteval[] = { 9, 11, 0, 2, 4, 5, 7, }; char Ebuf[128]; int Numchords = 1; /* "-" already defined */ struct chstr { char name[NAMELEN]; char chord[64]; } Ch[MAXCH] = { { "-", "- - - - - - - -\n", }, /* to allow "-" to be used as a rest */ }; char *peel(), *copy(); main(argc, argv) char *argv[]; { register int i; FILE *ifp; if (argc == 1) process(stdin); else { for (i = 1; i < argc; i++) { if ((ifp = fopen(argv[i], "r")) == NULL) perror(argv[i]); else { process(ifp); fclose(ifp); } } } } process(ifp) FILE *ifp; { char *bp, *cp; register int chnum, lastchnum, n; char buf[512]; FILE *fp; while (fgets(bp = buf, sizeof buf, ifp) != NULL) { cp = peel(&bp); if (*cp == '\n' || *cp == '#') { printf("%s %s", cp, bp); continue; } else if (wrdcmp(cp, "Include") == 0) { if (*bp++ != '"') syntax("Include must use quotes (\")"); for (cp = bp; *cp && *cp != '"'; cp++); if (*cp != '"') syntax("Include must use quotes (\")"); *cp = '\0'; if ((fp = fopen(bp, "r")) == NULL) { perror(bp); exit(1); } process(fp); fclose(fp); } else if (wrdcmp(cp, "Style") == 0) { if (wrdcmp(bp, "staccato") == 0) printf("#ARTIC\t0.25\n"); else if (wrdcmp(bp, "normal") == 0) printf("#ARTIC\t0.8\n"); else if (wrdcmp(bp, "legato") == 0) printf("#ARTIC\t1\n"); else syntax("Unrecognized \"Style\" arg"); } else if (wrdcmp(cp, "Quantum") == 0) { if (wrdcmp(bp, "whole") == 0) n = 1; else if (wrdcmp(bp, "half") == 0) n = 2; else if (wrdcmp(bp, "quarter") == 0) n = 4; else if (wrdcmp(bp, "eighth") == 0) n = 8; else if (wrdcmp(bp, "sixteenth") == 0) n = 16; else { syntax("Unrecognized quantum arg"); continue; } printf("#SPEED\t%d\n", n); } else if (wrdcmp(cp, "Chord") == 0) { if ((chnum = Numchords++) >= MAXCH) syntax("Too many chords defined"); copy(peel(&bp), Ch[chnum].name); copy(bp, Ch[chnum].chord); } else { lastchnum = -1; while (*cp) { if (*cp == '/') { if ((chnum = lastchnum) == -1) syntax("Line beginning with '/'"); } else { if ((chnum = find(cp)) < 0) { sprintf(Ebuf, "Undefined chord: %s", cp); syntax(Ebuf); } } printf("%s", Ch[chnum].chord); lastchnum = chnum; cp = peel(&bp); } } } } wrdcmp(ap, bp) char *ap, *bp; { while (*bp && *ap == *bp) { ap++; bp++; } return ((*ap <= ' ' && *bp == '\0')? 0 : *ap - *bp); } syntax(msg) char *msg; { fprintf(stderr, "Chord chart syntax error: %s\n", msg); exit(1); } char * peel(spp) char **spp; { register char *bp, *sp; bp = sp = *spp; while (*bp > ' ') bp++; if (*bp != '\0') { *bp++ = '\0'; while (*bp && *bp <= ' ') bp++; } *spp = bp; return(sp); } find(name) char *name; { register int i; for (i = 0; i < Numchords; i++) if (wrdcmp(name, Ch[i].name) == 0) return(i); return(-1); } char * copy(f, t) register char *f, *t; { while (*t++ = *f++); return(--t); }