Bell 32V development
authorTom London <tbl@research.uucp>
Mon, 6 Nov 1978 04:31:41 +0000 (23:31 -0500)
committerTom London <tbl@research.uucp>
Mon, 6 Nov 1978 04:31:41 +0000 (23:31 -0500)
Work on file usr/src/cmd/m4/m4.c
Work on file usr/src/cmd/m4/m4y.y

Co-Authored-By: John Reiser <jfr@research.uucp>
Synthesized-from: 32v

usr/src/cmd/m4/m4.c [new file with mode: 0644]
usr/src/cmd/m4/m4y.y [new file with mode: 0644]

diff --git a/usr/src/cmd/m4/m4.c b/usr/src/cmd/m4/m4.c
new file mode 100644 (file)
index 0000000..3e6ce5b
--- /dev/null
@@ -0,0 +1,899 @@
+#include <stdio.h>
+#include <signal.h>
+
+#define ERROR NULL
+#define        READ    "r"
+#define        WRITE   "w"
+
+#define        EOS     0
+int    lpar    = '(';
+#define        LPAR    lpar
+#define        RPAR    ')'
+#define        COMMA   ','
+#define        GRAVE   '`'
+#define        ACUTE   '\''
+#define LBRAK  '['
+#define RBRAK  ']'
+#ifdef  M4
+char   lquote  LBRAK;
+char   rquote  RBRAK;
+#endif
+#ifndef M4
+char   lquote  = GRAVE;
+char   rquote  = ACUTE;
+#endif
+#define        COMMENT '#'
+#define        ALPH    1
+#define        DIG     2
+
+#define        HSHSIZ  199     /* prime */
+#define        STACKS  50
+#define        SAVS    4096
+#define        TOKS    128
+
+#define        putbak(c)       *ip++ = c;
+#define        getchr()        (ip>cur_ip?*--ip: getc(infile[infptr]))
+#define        putchr(c)       if (cp==NULL) {if (curfile)putc(c,curfile);} else *op++ = c
+char   type[] = {
+       0,      0,      0,      0,      0,      0,      0,      0,
+       0,      0,      0,      0,      0,      0,      0,      0,
+       0,      0,      0,      0,      0,      0,      0,      0,
+       0,      0,      0,      0,      0,      0,      0,      0,
+       0,      0,      0,      0,      0,      0,      0,      0,
+       0,      0,      0,      0,      0,      0,      0,      0,
+       DIG,    DIG,    DIG,    DIG,    DIG,    DIG,    DIG,    DIG,
+       DIG,    DIG,    0,      0,      0,      0,      0,      0,
+       0,      ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,
+       ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,
+       ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,
+       ALPH,   ALPH,   ALPH,   0,      0,      0,      0,      ALPH,
+       0,      ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,
+       ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,
+       ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,   ALPH,
+       ALPH,   ALPH,   ALPH,   0,      0,      0,      0,      0,
+};
+
+char   token[TOKS];
+char   eoa[]   = "\0";
+struct nlist {
+       char    *name;
+       char    *def;
+       struct  nlist *next;
+};
+
+struct nlist   *hshtab[HSHSIZ];
+char   ibuf[SAVS+TOKS];
+char   obuf[SAVS+TOKS];
+char   *op     = obuf;
+char   *ip     = ibuf;
+char *ip_stk[10] = {ibuf};
+char *cur_ip = ibuf;
+struct call {
+       char    **argp;
+       int     plev;
+};
+struct call    *cp = NULL;
+
+char   *makeloc;
+char   *ifdefloc;
+char   *lenloc;
+char   *undefloc;
+char   *shiftloc;
+char   *cqloc;
+char   *defloc;
+char   *evaloc;
+char   *incrloc;
+char   *substrloc;
+char   *indexloc;
+char   *transloc;
+char   *ifloc;
+char   *divloc;
+char   *divnumloc;
+char   *undivloc;
+char   *dnlloc;
+char   *inclloc;
+char   *sinclloc;
+char   *syscmdloc;
+char   *dumploc;
+char   *errploc;
+
+char   *tempname;
+struct nlist   *lookup();
+char   *install();
+char   *malloc();
+char   *mktemp();
+char   *copy();
+long   ctol();
+int    hshval;
+FILE   *olist[11] = { stdout };
+int    okret;
+int    curout  = 0;
+FILE   *curfile = { stdout };
+FILE   *infile[10] = { stdin };
+int    infptr  = 0;
+
+main(argc, argv)
+char **argv;
+{
+       char *argstk[STACKS+10];
+       struct call callst[STACKS];
+       register char *tp, **ap;
+       int delexit(), catchsig();
+       register t;
+       int i;
+
+#ifdef gcos
+#ifdef M4
+       install("GCOS", eoa);
+#endif
+#ifndef M4
+       install("gcos", eoa);
+#endif
+#endif
+#ifdef unix
+#ifdef M4
+       install("UNIX", eoa);
+#endif
+#ifndef M4
+       install("unix", eoa);
+#endif
+#endif
+
+#ifdef M4
+       makeloc = install("MAKETEMP", eoa);
+       ifdefloc = install("IFDEF", eoa);
+       lenloc = install("LEN", eoa);
+       undefloc = install("UNDEFINE", eoa);
+       shiftloc = install("SHIFT", eoa);
+       cqloc = install("CHANGEQUOTE", eoa);
+       defloc = install("DEFINE", eoa);
+       evaloc = install("EVAL", eoa);
+       inclloc = install("INCLUDE", eoa);
+       sinclloc = install("SINCLUDE", eoa);
+       syscmdloc = install("SYSCMD", eoa);
+       dumploc = install("DUMPDEF", eoa);
+       errploc = install("ERRPRINT", eoa);
+       incrloc = install("INCR", eoa);
+       substrloc = install("SUBSTR", eoa);
+       indexloc = install("INDEX", eoa);
+       transloc = install("TRANSLIT", eoa);
+       ifloc = install("IFELSE", eoa);
+       divloc = install("DIVERT", eoa);
+       divnumloc = install("DIVNUM", eoa);
+       undivloc = install("UNDIVERT", eoa);
+       dnlloc = install("DNL", eoa);
+#endif
+
+#ifndef M4
+       makeloc = install("maketemp", eoa);
+       ifdefloc = install("ifdef", eoa);
+       lenloc = install("len", eoa);
+       undefloc = install("undefine", eoa);
+       shiftloc = install("shift", eoa);
+       cqloc = install("changequote", eoa);
+       defloc = install("define", eoa);
+       evaloc = install("eval", eoa);
+       inclloc = install("include", eoa);
+       sinclloc = install("sinclude", eoa);
+       syscmdloc = install("syscmd", eoa);
+       dumploc = install("dumpdef", eoa);
+       errploc = install("errprint", eoa);
+       incrloc = install("incr", eoa);
+       substrloc = install("substr", eoa);
+       indexloc = install("index", eoa);
+       transloc = install("translit", eoa);
+       ifloc = install("ifelse", eoa);
+       divloc = install("divert", eoa);
+       divnumloc = install("divnum", eoa);
+       undivloc = install("undivert", eoa);
+       dnlloc = install("dnl", eoa);
+#endif
+       ap = argstk;
+#ifndef gcos
+       if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
+               signal(SIGHUP, catchsig);
+       if (signal(SIGINT, SIG_IGN) != SIG_IGN)
+               signal(SIGINT, catchsig);
+       tempname = mktemp("/tmp/m4aXXXXX");
+       close(creat(tempname, 0));
+#endif
+#ifdef gcos
+       tempname = "m4.tempa";
+#endif
+       if (argc>1)
+               putbak(0);
+       for (;;) {
+               tp = token;
+               *tp++ = t = getchr();
+               *tp = EOS;
+               if (t<=0) {
+                       if (infptr > 0) {
+                               fclose(infile[infptr]);
+                               infptr--;
+                               cur_ip = ip_stk[infptr];
+                               continue;
+                       }
+                       if (argc<=1)
+                               break;
+                       argc--;
+                       argv++;
+                       if (infile[infptr]!=stdin)
+                               fclose(infile[infptr]);
+                       if (**argv=='-')
+                               infile[infptr] = stdin;
+                       else if ((infile[infptr]=fopen(argv[0], READ))==ERROR) {
+                               fprintf(stderr, "m4: file not found: %s\n", argv[0]);
+                               delexit();
+                       }
+                       continue;
+               }
+               if (type[t]==ALPH) {
+                       while ((t=type[*tp++=getchr()])==ALPH||t==DIG);
+                       putbak(*--tp);
+                       *tp = EOS;
+                       if (*ap = lookup(token)->def) {
+                               if (++ap >= &argstk[STACKS]) {
+                                       fprintf(stderr, "m4: arg stack overflow\n");
+                                       delexit();
+                               }
+                               if (cp==NULL)
+                                       cp = callst;
+                               else if (++cp > &callst[STACKS]) {
+                                       fprintf(stderr, "m4: call stack overflow\n");
+                                       delexit();
+                               }
+                               cp->argp = ap;
+                               *ap++ = op;
+                               puttok();
+                               *op++ = '\0';
+                               t = getchr();
+                               putbak(t);
+                               if (t!=LPAR) {
+                                       /* if (t!=' ' && t!='\t') */
+                                               putbak(')');
+                                       putbak('(');
+                               }
+                               else    /* try to fix arg count */
+                                       *ap++ = op;
+                               cp->plev = 0;
+                       } else
+                               puttok();
+               } else if (t==lquote) {
+                       i = 1;
+                       for (;;) {
+                               t = getchr();
+                               if (t==rquote) {
+                                       i--;
+                                       if (i==0)
+                                               break;
+                               } else if (t==lquote)
+                                       i++;
+                               else if (t<0) {
+                                       fprintf(stderr, "m4: EOF in string\n");
+                                       delexit();
+                               }
+                               putchr(t);
+                       }
+               } else if (t==COMMENT) {
+                       putbak(t);
+                       while ((t = getchr())!='\n'&& t>=0)
+                               if (cp==NULL)
+                                       putchr(t);
+                       putbak(t);
+               } else if (cp==NULL) {
+                       puttok();
+               } else if (t==LPAR) {
+                       if (cp->plev)
+                               *op++ = t;
+                       cp->plev++;
+                       while ( (t=getchr())==' ' || t=='\t' || t=='\n')
+                               ;       /* skip leading white space during arg collection */
+                       putbak(t);
+/*
+               } else if (t==' ' || t=='\t' || t=='\n') {
+                       continue;
+*/
+               } else if (t==RPAR) {
+                       cp->plev--;
+                       if (cp->plev==0) {
+                               *op++ = '\0';
+                               expand(cp->argp, ap-cp->argp-1);
+                               op = *cp->argp;
+                               ap = cp->argp-1;
+                               cp--;
+                               if (cp < callst)
+                                       cp = NULL;
+                       } else
+                               *op++ = t;
+               } else if (t==COMMA && cp->plev<=1) {
+                       *op++ = '\0';
+                       *ap++ = op;
+                       while ((t=getchr())==' ' || t=='\t' || t=='\n')
+                               ;       /* skip leading white space during arg collection */
+                       putbak(t);
+               } else
+                       *op++ = t;
+       }
+       if (cp!=NULL) {
+               fprintf(stderr, "m4: unexpected EOF\n");
+               delexit();
+       }
+       okret = 1;
+       delexit();
+}
+
+catchsig()
+{
+       okret = 0;
+       delexit();
+}
+
+delexit()
+{
+       register FILE *fp;
+       register i, c;
+
+       if (!okret) {
+               signal(SIGHUP, SIG_IGN);
+               signal(SIGINT, SIG_IGN);
+       }
+       for (i=1; i<10; i++) {
+               if (olist[i]==NULL)
+                       continue;
+               fclose(olist[i]);
+               tempname[7] = 'a'+i;
+               if (okret) {
+                       fp = fopen(tempname, READ);
+                       while ((c = getc(fp)) > 0)
+                               putchar(c);
+                       fclose(fp);
+               }
+               unlink(tempname);
+       }
+       tempname[7] = 'a';
+       unlink(tempname);
+       exit(1-okret);
+}
+
+puttok()
+{
+       register char *tp;
+
+       tp = token;
+       if (cp) {
+               if (op >= &obuf[SAVS]) {
+                       fprintf(stderr, "m4: argument overflow\n");
+                       delexit();
+               }
+               while (*tp)
+                       *op++ = *tp++;
+       } else if (curfile)
+               while (*tp)
+                       putc(*tp++, curfile);
+}
+
+pbstr(str)
+register char *str;
+{
+       register char *p;
+
+       p = str;
+       while (*p++);
+       --p;
+       if (ip >= &ibuf[SAVS]) {
+               fprintf(stderr, "m4: pushback overflow\n");
+               delexit();
+       }
+       while (p > str)
+               putbak(*--p);
+}
+
+expand(a1, c)
+register char **a1;
+{
+       register char *dp;
+       register n;
+
+       dp = a1[-1];
+       if (dp==defloc)
+               dodef(a1, c);
+       else if (dp==evaloc)
+               doeval(a1, c);
+       else if (dp==inclloc)
+               doincl(a1, c, 1);
+       else if (dp==sinclloc)
+               doincl(a1, c, 0);
+       else if (dp==makeloc)
+               domake(a1, c);
+       else if (dp==syscmdloc)
+               dosyscmd(a1, c);
+       else if (dp==incrloc)
+               doincr(a1, c);
+       else if (dp==substrloc)
+               dosubstr(a1, c);
+       else if (dp==indexloc)
+               doindex(a1, c);
+       else if (dp==transloc)
+               dotransl(a1, c);
+       else if (dp==ifloc)
+               doif(a1, c);
+       else if (dp==divloc)
+               dodiv(a1, c);
+       else if (dp==divnumloc)
+               dodivnum(a1, c);
+       else if (dp==undivloc)
+               doundiv(a1, c);
+       else if (dp==dnlloc)
+               dodnl(a1, c);
+       else if (dp==dumploc)
+               dodump(a1, c);
+       else if (dp==errploc)
+               doerrp(a1, c);
+       else if (dp==lenloc)
+               dolen(a1, c);
+       else if (dp==ifdefloc)
+               doifdef(a1, c);
+       else if (dp==undefloc)
+               doundef(a1, c);
+       else if (dp==shiftloc)
+               doshift(a1, c);
+       else if (dp==cqloc)
+               docq(a1, c);
+       else {
+               while (*dp++);
+               for (dp--; dp>a1[-1]; ) {
+                       if (--dp>a1[-1] && dp[-1]=='$') {
+                               n = *dp-'0';
+                               if (n>=0 && n<=9) {
+                                       if (n <= c)
+                                               pbstr(a1[n]);
+                                       dp--;
+                               } else
+                                       putbak(*dp);
+                       } else
+                               putbak(*dp);
+               }
+       }
+}
+
+struct nlist *lookup(str)
+char *str;
+{
+       register char *s1, *s2;
+       register struct nlist *np;
+       static struct nlist nodef;
+
+       s1 = str;
+       for (hshval = 0; *s1; )
+               hshval += *s1++;
+       hshval %= HSHSIZ;
+       for (np = hshtab[hshval]; np!=NULL; np = np->next) {
+               s1 = str;
+               s2 = np->name;
+               while (*s1++ == *s2)
+                       if (*s2++ == EOS)
+                               return(np);
+       }
+       return(&nodef);
+}
+
+char *install(nam, val)
+char *nam, *val;
+{
+       register struct nlist *np;
+
+       if ((np = lookup(nam))->name == NULL) {
+               np = (struct nlist *)malloc(sizeof(*np));
+               if (np == NULL) {
+                       fprintf(stderr, "m4: no space for alloc\n");
+                       exit(1);
+               }
+               np->name = copy(nam);
+               np->def = copy(val);
+               np->next = hshtab[hshval];
+               hshtab[hshval] = np;
+               return(np->def);
+       }
+       free(np->def);
+       np->def = copy(val);
+       return(np->def);
+}
+
+doundef(ap, c)
+char **ap;
+{
+       register struct nlist *np, *tnp;
+
+       if (c < 1 || (np = lookup(ap[1]))->name == NULL)
+               return;
+       tnp = hshtab[hshval];   /* lookup sets hshval */
+       if (tnp == np)  /* it's in first place */
+               hshtab[hshval] = np->next;
+       else {
+               for ( ; tnp->next != np; tnp = tnp->next)
+                       ;
+               tnp->next = np->next;
+       }
+       free(np->name);
+       free(np->def);
+       free((char *)np);
+}
+
+char *copy(s)
+register char *s;
+{
+       register char *p, *s1;
+
+       p = s1 = malloc((unsigned)strlen(s)+1);
+       if (p == NULL) {
+               fprintf(stderr, "m4: no space for alloc\n");
+               exit(1);
+       }
+       while (*s1++ = *s++);
+       return(p);
+}
+
+dodef(ap, c)
+char **ap;
+{
+       if (c >= 2) {
+               if (strcmp(ap[1], ap[2]) == 0) {
+                       fprintf(stderr, "m4: %s defined as itself\n", ap[1]);
+                       delexit();
+               }
+               install(ap[1], ap[2]);
+       }
+       else if (c == 1)
+               install(ap[1], "");
+}
+
+doifdef(ap, c)
+char **ap;
+{
+       register struct nlist *np;
+
+       if (c < 2)
+               return;
+       if (lookup(ap[1])->name != NULL)
+               pbstr(ap[2]);
+       else if (c >= 3)
+               pbstr(ap[3]);
+}
+
+dolen(ap, c)
+char **ap;
+{
+       putnum((long) strlen(ap[1]));
+}
+
+docq(ap, c)
+char **ap;
+{
+       if (c > 1) {
+               lquote = *ap[1];
+               rquote = *ap[2];
+       } else if (c == 1) {
+               lquote = rquote = *ap[1];
+       } else {
+#ifndef M4
+               lquote = GRAVE;
+               rquote = ACUTE;
+#endif
+#ifdef M4
+               lquote = LBRAK;
+               rquote = RBRAK;
+#endif
+       }
+}
+
+doshift(ap, c)
+char **ap;
+{
+       fprintf(stderr, "m4: shift not yet implemented\n");
+}
+
+dodump(ap, c)
+char **ap;
+{
+       int i;
+       register struct nlist *np;
+
+       if (c > 0)
+               while (c--) {
+                       if ((np = lookup(*++ap))->name != NULL)
+                               fprintf(stderr, "`%s'   `%s'\n", np->name, np->def);
+               }
+       else
+               for (i=0; i<HSHSIZ; i++)
+                       for (np=hshtab[i]; np!=NULL; np=np->next)
+                               fprintf(stderr, "`%s'   `%s'\n", np->name, np->def);
+}
+
+doerrp(ap, c)
+char **ap;
+{
+       if (c > 0) {
+               fprintf(stderr, ap[1], ap[2], ap[3], ap[4], ap[5], ap[6]);
+               fprintf(stderr, "\n");
+       }
+}
+
+
+long   evalval;        /* return value from yacc stuff */
+char   *pe;    /* used by grammar */
+
+doeval(ap, c)
+char **ap;
+{
+
+       if (c > 0) {
+               pe = ap[1];
+               if (yyparse() == 0)
+                       putnum(evalval);
+               else
+                       fprintf(stderr, "m4: invalid expression in eval: %s\n", ap[1]);
+       }
+}
+
+doincl(ap, c, noisy)
+char **ap;
+{
+       if (c > 0 && strlen(ap[1]) > 0) {
+               infptr++;
+               ip_stk[infptr] = cur_ip = ip;
+               if ((infile[infptr] = fopen(ap[1], READ))==ERROR) {
+                       if (noisy) {
+                               fprintf(stderr, "m4: file not found: %s\n", ap[1]);
+                               delexit();
+                       }
+                       else
+                               infptr--;
+               }
+       }
+}
+
+dosyscmd(ap, c)
+char **ap;
+{
+       if (c > 0)
+               system(ap[1]);
+}
+
+domake(ap, c)
+char **ap;
+{
+       if (c > 0)
+               pbstr(mktemp(ap[1]));
+}
+
+doincr(ap, c)
+char **ap;
+{
+       if (c >= 1)
+               putnum(ctol(ap[1])+1);
+}
+
+putnum(num)
+long num;
+{
+       register sign;
+
+       sign = (num < 0) ? '-' : '\0';
+       if (num < 0)
+               num = -num;
+       do {
+               putbak(num%10+'0');
+               num = num/10;
+       } while (num!=0);
+       if (sign == '-')
+               putbak('-');
+}
+
+dosubstr(ap, c)
+char **ap;
+{
+       int nc;
+       register char *sp, *fc;
+
+       if (c<2)
+               return;
+       if (c<3)
+               nc = TOKS;
+       else
+               nc = ctoi(ap[3]);
+       fc = ap[1] + max(0, min(ctoi(ap[2]), strlen(ap[1])));
+       sp = fc + min(nc, strlen(fc));
+       while (sp > fc)
+               putbak(*--sp);
+}
+
+doindex(ap, c)
+char **ap;
+{
+       if (c >= 2)
+               putnum((long) strindex(ap[1], ap[2]));
+}
+
+strindex(p1, p2)
+char *p1, *p2;
+{
+       register m;
+       register char *s, *t, *p;
+
+       for (p=p1; *p; p++) {
+               s = p;
+               m = 1;
+               for (t=p2; *t; )
+                       if (*t++ != *s++)
+                               m = 0;
+               if (m == 1)
+                       return(p-p1);
+       }
+       return(-1);
+}
+
+dotransl(ap, c)
+char **ap;
+{
+       register char *s, *fr, *to;
+
+       if (c <= 1) return;
+
+       if (c == 2) {
+               register int i;
+               to = ap[1];
+               for (s = ap[1]; *s; s++) {
+                       i = 0;
+                       for (fr = ap[2]; *fr; fr++)
+                               if (*s == *fr) {
+                                       i++;
+                                       break;
+                               }
+                       if (i == 0)
+                               *to++ = *s;
+               }
+               *to = '\0';
+       }
+
+       if (c >= 3) {
+               for (s = ap[1]; *s; s++)
+                       for (fr = ap[2], to = ap[3]; *fr && *to; fr++, to++)
+                               if (*s == *fr)
+                                       *s = *to;
+       }
+
+       pbstr(ap[1]);
+}
+
+doif(ap, c)
+register char **ap;
+{
+       if (c < 3)
+               return;
+       while (c >= 3) {
+               if (strcmp(ap[1], ap[2]) == 0) {
+                       pbstr(ap[3]);
+                       return;
+               }
+               c -= 3;
+               ap += 3;
+       }
+       if (c > 0)
+               pbstr(ap[1]);
+}
+
+dodiv(ap, c)
+register char **ap;
+{
+       register int f;
+
+       if (c<1)
+               f = 0;
+       else
+               f = ctoi(ap[1]);
+       if (f>=10 || f<0) {
+               curfile = NULL;
+               return;
+       }
+       tempname[7] = 'a' + f;
+       if (olist[f] || (olist[f]=fopen(tempname, WRITE))) {
+               curout = f;
+               curfile = olist[f];
+       }
+}
+
+doundiv(ap, c)
+char **ap;
+{
+       register FILE *fp;
+       register int i, ch;
+       int j;
+
+       if (c == 0) {
+               for (i=1; i<10; i++) {
+                       if (i==curout || olist[i]==NULL)
+                               continue;
+                       fclose(olist[i]);
+                       tempname[7] = 'a'+i;
+                       fp = fopen(tempname, READ);
+                       if (curfile != NULL)
+                               while ((ch = getc(fp)) > 0)
+                                       putc(ch, curfile);
+                       fclose(fp);
+                       unlink(tempname);
+                       olist[i] = NULL;
+               }
+
+       }
+       else {
+               for (j = 1; j <= c; j++) {
+                       i = ctoi(*++ap);
+                       if (i<1 || i>9 || i==curout || olist[i]==NULL)
+                               continue;
+                       fclose(olist[i]);
+                       tempname[7] = 'a'+i;
+                       fp = fopen(tempname, READ);
+                       if (curfile != NULL)
+                               while ((ch = getc(fp)) > 0)
+                                       putc(ch, curfile);
+                       fclose(fp);
+                       unlink(tempname);
+                       olist[i] = NULL;
+               }
+       }
+}
+
+dodivnum(ap, c)
+char **ap;
+{
+       putnum((long) curout);
+}
+
+dodnl(ap, c)
+char **ap;
+{
+       register t;
+
+       while ((t=getchr())!='\n' && t>=0)
+               ;
+}
+
+long ctol(str)
+register char *str;
+{
+       register sign;
+       long num;
+
+       while (*str==' ' || *str=='\t' || *str=='\n')
+               str++;
+       num = 0;
+       if (*str == '-') {
+               sign = -1;
+               str++;
+       }
+       else
+               sign = 1;
+       while (*str>='0' && *str<='9')
+               num = num*10 + *str++ - '0';
+       return(sign * num);
+}
+
+ctoi(s)
+char *s;
+{
+       return(ctol(s));
+}
+
+min(a, b)
+{
+       if (a>b)
+               return(b);
+       return(a);
+}
+
+max(a, b)
+{
+       if (a>b)
+               return(a);
+       return(b);
+}
diff --git a/usr/src/cmd/m4/m4y.y b/usr/src/cmd/m4/m4y.y
new file mode 100644 (file)
index 0000000..40f5a3b
--- /dev/null
@@ -0,0 +1,94 @@
+%{
+extern long    evalval;
+#define        YYSTYPE long
+%}
+
+%term DIGITS
+%left '|'
+%left '&'
+%right '!'
+%nonassoc GT GE LT LE NE EQ
+%left '+' '-'
+%left '*' '/' '%'
+%right POWER
+%right UMINUS
+%%
+
+s      : e     ={ evalval = $1; }
+       |       ={ evalval = 0; }
+       ;
+
+e      : e '|' e       ={ $$ = ($1!=0 || $3!=0) ? 1 : 0; }
+       | e '&' e       ={ $$ = ($1!=0 && $3!=0) ? 1 : 0; }
+       | '!' e         ={ $$ = $2 == 0; }
+       | e EQ e        ={ $$ = $1 == $3; }
+       | e NE e        ={ $$ = $1 != $3; }
+       | e GT e        ={ $$ = $1 > $3; }
+       | e GE e        ={ $$ = $1 >= $3; }
+       | e LT e        ={ $$ = $1 < $3; }
+       | e LE e        ={ $$ = $1 <= $3; }
+       | e '+' e       ={ $$ = ($1+$3); }
+       | e '-' e       ={ $$ = ($1-$3); }
+       | e '*' e       ={ $$ = ($1*$3); }
+       | e '/' e       ={ $$ = ($1/$3); }
+       | e '%' e       ={ $$ = ($1%$3); }
+       | '(' e ')'     ={ $$ = ($2); }
+       | e POWER e     ={ for ($$=1; $3-->0; $$ *= $1); }      
+       | '-' e %prec UMINUS    ={ $$ = $2-1; $$ = -$2; }
+       | '+' e %prec UMINUS    ={ $$ = $2-1; $$ = $2; }
+       | DIGITS        ={ $$ = evalval; }
+       ;
+
+%%
+
+yylex() {
+       extern char *pe;
+
+       while (*pe==' ' || *pe=='\t' || *pe=='\n')
+               pe++;
+       switch(*pe) {
+       case '\0':
+       case '+':
+       case '-':
+       case '/':
+       case '%':
+       case '(':
+       case ')':
+               return(*pe++);
+       case '^':
+               pe++;
+               return(POWER);
+       case '*':
+               return(peek('*', POWER, '*'));
+       case '>':
+               return(peek('=', GE, GT));
+       case '<':
+               return(peek('=', LE, LT));
+       case '=':
+               return(peek('=', EQ, EQ));
+       case '|':
+               return(peek('|', '|', '|'));
+       case '&':
+               return(peek('&', '&', '&'));
+       case '!':
+               return(peek('=', NE, '!'));
+       default:
+               evalval = 0;
+               while (*pe >= '0' && *pe <= '9')
+                       evalval = evalval*10 + *pe++ - '0';
+               return(DIGITS);
+       }
+}
+
+peek(c, r1, r2)
+{
+       if (*++pe != c)
+               return(r2);
+       ++pe;
+       return(r1);
+}
+
+yyerror(s)
+char *s;
+{
+}