/* ** MPP -- Music PreProcessor ** psl 8/88 */ #include #include #define MAXRPT 8 /* how deep repeats can nest */ struct rptstr { int num; /* number of repeats total */ int rpt; /* number of current repeat */ int wrongr; /* is current repeat being output? */ long addr; /* where (in file) repeat starts */ } Rpts[MAXRPT]; int Rdepth = 0; /* how many repeats are stacked up */ main(argc, argv) char *argv[]; { char *infile = (char *) 0, *cp, buf[1024], ifbuf[32]; int fsect, lsect, i, fh, cflg; FILE *ifp; cflg = 0; /* ignore comments (default) */ infile = (char *) 0; for (i = 1; i < argc; i++) { if (argv[i][0] == '-') { switch (argv[i][1]) { case 'c': /* don't strip comments */ cflg++; break; case 's': /* specify which section(s) */ break; /* (processed later) */ default: goto syntax; } } else if (infile == (char *) 0) infile = argv[i]; else goto syntax; } if (!infile) { sprintf(infile = ifbuf, "/tmp/mpp%d", getpid()); if ((fh = creat(infile, 0644)) < 0) { perror(infile); exit(1); } while ((i = read(0, buf, sizeof buf)) > 0) write(fh, buf, i); close(fh); } if (!(ifp = fopen(infile, "r"))) { perror(infile); syntax: fprintf(stderr, "Usage: %s [-c] [-s#] [file or stdin]\n", argv[0]); fprintf(stderr, " or: %s [-c] -s### file\n", argv[0]); fprintf(stderr, "where # is a single section number"); fprintf(stderr, " and ### is a list of section numbers\n"); fprintf(stderr, "using ',' to separate numbers"); fprintf(stderr, " and '-' for ranges; e.g. -s1,4-6,1\n"); exit(2); } fsect = lsect = -1; for (i = 1; i < argc; i++) { if (argv[i][0] != '-' || argv[i][1] != 's') continue; for (cp = &argv[i][2]; *cp; ) { fsect = lsect = atoi(cp); for (; *cp && *cp != ',' && *cp != '-'; cp++); if (*cp == '-') { lsect = atoi(++cp); for (; *cp && *cp != ','; cp++); } if (*cp == ',') cp++; else *cp = '\0'; for (i = fsect; i <= lsect; i++) { fseek(ifp, 0L, 0); proc(ifp, i, cflg); } } } if (fsect == -1) /* no sections specified */ proc(ifp, 1, cflg); if (infile == ifbuf) /* temp file created */ unlink(infile); exit(0); } proc(ifp, sect, cflg) FILE *ifp; { char buf[512], a[16][128]; int skip, wrongs, i, nf, nr; FILE *iifp; extern long ftell(); skip = wrongs = 0; for (nr = 1; fgets(buf, sizeof buf, ifp) != NULL; nr++) { nf = sscanf(buf, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]); if (nf <= 0 || strcmp(a[0], "#") == 0) { if (cflg) fputs(buf, stdout); continue; } for (i = 16; --i >= nf; a[i][0] = '\0'); if (a[0][0] == '#') { if (skip && strcmp(a[0], "#ENDSKIP") != 0) continue; if (strcmp(a[0], "#ALLSECTS") == 0) { wrongs = 0; continue; } if (strcmp(a[0], "#NOTSECT") == 0) { wrongs = 0; for (i = 1; i < nf; i++) if (atoi(a[i]) == sect) wrongs = 1; continue; } if (strcmp(a[0], "#ONLYSECT") == 0) { wrongs = 1; for (i = 1; i < nf; i++) if (atoi(a[i]) == sect) wrongs = 0; continue; } if (wrongs) continue; if (strcmp(a[0], "#ENDSKIP") == 0) { skip = 0; continue; } if (strcmp(a[0], "#SECT") == 0) { sect = atoi(a[1]); continue; } if (strcmp(a[0], "#SKIP") == 0) { skip++; continue; } if (strcmp(a[0], "#INCLUDE") == 0) { if (!(iifp = fopen(a[1], "r"))) perror(a[1]); else { proc(iifp, sect, cflg); fclose(iifp); } continue; } if (strcmp(a[0], "#REPEAT") == 0) { if (Rdepth >= MAXRPT) { fprintf(stderr, "Max repeat nesting depth is %d\n", MAXRPT); exit(1); } Rpts[Rdepth].num = atoi(a[1]); Rpts[Rdepth].rpt = 1; Rpts[Rdepth].wrongr = 0; Rpts[Rdepth++].addr = ftell(ifp); continue; } if (strcmp(a[0], "#ALLRPTS") == 0) { if (Rdepth > 0) Rpts[Rdepth - 1].wrongr = 0; continue; } if (strcmp(a[0], "#NOTRPT") == 0) { if (Rdepth > 0) { Rpts[Rdepth - 1].wrongr = 0; for (i = 1; i < nf; i++) if (atoi(a[i]) == Rpts[Rdepth - 1].rpt) Rpts[Rdepth - 1].wrongr = 1; } continue; } if (strcmp(a[0], "#ONLYRPT") == 0) { if (Rdepth > 0) { Rpts[Rdepth - 1].wrongr = 1; for (i = 1; i < nf; i++) if (atoi(a[i]) == Rpts[Rdepth - 1].rpt) Rpts[Rdepth - 1].wrongr = 0; } continue; } if (strcmp(a[0], "#ENDRPT") == 0) { if (Rdepth > 0) { Rpts[Rdepth - 1].wrongr = 0; if (Rpts[Rdepth - 1].rpt++ < Rpts[Rdepth - 1].num) fseek(ifp, Rpts[Rdepth - 1].addr, 0); else --Rdepth; } continue; } } if (!skip && !wrongs && !wrongrpt()) fputs(buf, stdout); } if (Rdepth == 1) fprintf(stderr, "Unterminated repeat\n"); else if (Rdepth > 0) fprintf(stderr, "Unterminated repeats (%d)\n", Rdepth); } wrongrpt() { register int i = Rdepth; while (--i >= 0) if (Rpts[i].wrongr) return(1); return(0); }