14aaebc40Srrh #include <stdio.h>
24aaebc40Srrh #include <ctype.h>
34aaebc40Srrh #include "pic.h"
44aaebc40Srrh #include "y.tab.h"
54aaebc40Srrh
64aaebc40Srrh extern FILE *yyin;
74aaebc40Srrh extern int lineno;
84aaebc40Srrh extern char *filename;
94aaebc40Srrh extern int synerr;
104aaebc40Srrh
definition(s)114aaebc40Srrh definition(s) /* collect definition for s and install */
124aaebc40Srrh char *s; /* definitions picked up lexically */
134aaebc40Srrh {
14*7914cea4Srrh char buf[4000], *p, *tostring();
154aaebc40Srrh int c, delim;
164aaebc40Srrh struct symtab *stp;
174aaebc40Srrh
184aaebc40Srrh while ((delim = input()) == ' ' || delim == '\t')
194aaebc40Srrh ;
204aaebc40Srrh for (p = buf; (c = input()) != delim; ) {
214aaebc40Srrh if (p >= buf + sizeof(buf)) {
224aaebc40Srrh yyerror("definition of %s is too long", s);
234aaebc40Srrh exit(1);
244aaebc40Srrh }
254aaebc40Srrh if (c == EOF) {
264aaebc40Srrh yyerror("end of file while defining %s", s);
274aaebc40Srrh exit(1);
284aaebc40Srrh }
294aaebc40Srrh *p++ = c;
304aaebc40Srrh }
314aaebc40Srrh *p = '\0';
324aaebc40Srrh p = tostring(buf);
334aaebc40Srrh stp = lookup(s);
344aaebc40Srrh if (stp != NULL) { /* it's there before */
354aaebc40Srrh if (stp->s_type != DEFNAME) {
364aaebc40Srrh yyerror("%s used as variable and definition\n", s);
374aaebc40Srrh return;
384aaebc40Srrh }
394aaebc40Srrh free(stp->s_val.p);
404aaebc40Srrh stp->s_val.p = p;
414aaebc40Srrh } else {
424aaebc40Srrh YYSTYPE u;
434aaebc40Srrh u.p = p;
444aaebc40Srrh makevar(tostring(s), DEFNAME, u);
454aaebc40Srrh }
464aaebc40Srrh dprintf("installing %s as `%s'\n", s, p);
474aaebc40Srrh }
484aaebc40Srrh
494aaebc40Srrh char *argstk[10]; /* pointers to actual arguments in argval */
504aaebc40Srrh char argval[1000]; /* arguments stored here end to end */
514aaebc40Srrh char *argp; /* current position in argval */
524aaebc40Srrh int argcnt; /* number of arguments seen so far */
534aaebc40Srrh
544aaebc40Srrh dodef(stp) /* collect args and push back defn for name in table slot n */
554aaebc40Srrh struct symtab *stp;
564aaebc40Srrh {
574aaebc40Srrh int i, c, len;
584aaebc40Srrh char *p;
594aaebc40Srrh
604aaebc40Srrh argcnt = 0;
614aaebc40Srrh if (input() != '(')
624aaebc40Srrh yyerror("disaster in dodef\n");
634aaebc40Srrh for (argp = argval; (len = getarg(argp)) != -1; argp += len) {
644aaebc40Srrh argstk[argcnt++] = argp;
654aaebc40Srrh if (input() == ')')
664aaebc40Srrh break;
674aaebc40Srrh }
684aaebc40Srrh for (i = argcnt; i < 10; i++)
694aaebc40Srrh argstk[i] = "";
704aaebc40Srrh if (dbg) {
714aaebc40Srrh for (i = 0; i < argcnt; i++)
724aaebc40Srrh printf("arg %d = %s\n", i, argstk[i]);
734aaebc40Srrh }
744aaebc40Srrh
754aaebc40Srrh /* push them back */
764aaebc40Srrh for (p = stp->s_val.p; *p; p++)
774aaebc40Srrh ; /* find the end */
784aaebc40Srrh for (--p; p >= stp->s_val.p; p--) {
794aaebc40Srrh if (*(p-1) == '$') {
804aaebc40Srrh if (isdigit(*p)) {
814aaebc40Srrh pbstr(argstk[*p - '0' - 1]);
824aaebc40Srrh p--;
834aaebc40Srrh }
844aaebc40Srrh else
854aaebc40Srrh unput(*p);
864aaebc40Srrh } else {
874aaebc40Srrh unput(*p);
884aaebc40Srrh }
894aaebc40Srrh }
904aaebc40Srrh }
914aaebc40Srrh
getarg(p)924aaebc40Srrh getarg(p) /* pick up single argument, store in p, return length */
934aaebc40Srrh char *p;
944aaebc40Srrh {
954aaebc40Srrh int n, c, npar;
964aaebc40Srrh
974aaebc40Srrh n = npar = 0;
984aaebc40Srrh for ( ;; ) {
994aaebc40Srrh c = input();
1004aaebc40Srrh if (c == EOF)
1014aaebc40Srrh yyerror("end of file in getarg!\n");
1024aaebc40Srrh if (npar == 0 && (c == ',' || c == ')'))
1034aaebc40Srrh break;
1044aaebc40Srrh if (c == '"') /* copy quoted stuff intact */
1054aaebc40Srrh do {
1064aaebc40Srrh *p++ = c;
1074aaebc40Srrh n++;
1084aaebc40Srrh } while ((c = input()) != '"' && c != EOF);
1094aaebc40Srrh else if (c == '(')
1104aaebc40Srrh npar++;
1114aaebc40Srrh else if (c == ')')
1124aaebc40Srrh npar--;
1134aaebc40Srrh n++;
1144aaebc40Srrh *p++ = c;
1154aaebc40Srrh }
1164aaebc40Srrh *p = 0;
1174aaebc40Srrh unput(c);
1184aaebc40Srrh return(n + 1);
1194aaebc40Srrh }
1204aaebc40Srrh
121*7914cea4Srrh #define PBSIZE 4000
1224aaebc40Srrh char pbuf[PBSIZE]; /* pushback buffer */
1234aaebc40Srrh char *pb = pbuf-1; /* next pushed back character */
1244aaebc40Srrh
1254aaebc40Srrh char ebuf[200]; /* collect input here for error reporting */
1264aaebc40Srrh char *ep = ebuf;
1274aaebc40Srrh
input()1284aaebc40Srrh input()
1294aaebc40Srrh {
1304aaebc40Srrh register int c;
1314aaebc40Srrh
1324aaebc40Srrh if (pb >= pbuf) {
1334aaebc40Srrh c = *pb--;
1344aaebc40Srrh } else {
1354aaebc40Srrh c = getc(yyin);
1364aaebc40Srrh if (c == '\n')
1374aaebc40Srrh lineno++;
1384aaebc40Srrh else if (c == EOF) {
1394aaebc40Srrh yyerror("end of file inside .PS/.PE");
1404aaebc40Srrh exit(1);
1414aaebc40Srrh }
1424aaebc40Srrh }
1434aaebc40Srrh if (ep >= ebuf + sizeof ebuf)
1444aaebc40Srrh ep = ebuf;
1454aaebc40Srrh return (*ep++ = c);
1464aaebc40Srrh }
1474aaebc40Srrh
unput(c)1484aaebc40Srrh unput(c)
1494aaebc40Srrh {
1504aaebc40Srrh if (++pb >= pbuf + sizeof pbuf) {
1514aaebc40Srrh yyerror("pushback overflow\n");
1524aaebc40Srrh exit(1);
1534aaebc40Srrh }
1544aaebc40Srrh if (--ep < ebuf)
1554aaebc40Srrh ep = ebuf + sizeof(ebuf) - 1;
1564aaebc40Srrh return(*pb = c);
1574aaebc40Srrh }
1584aaebc40Srrh
pbstr(s)1594aaebc40Srrh pbstr(s)
1604aaebc40Srrh char *s;
1614aaebc40Srrh {
1624aaebc40Srrh int n;
1634aaebc40Srrh
1644aaebc40Srrh n = strlen(s);
1654aaebc40Srrh while (--n >= 0)
1664aaebc40Srrh unput(s[n]);
1674aaebc40Srrh }
1684aaebc40Srrh
yyerror(s,s1,s2,s3,s4)1694aaebc40Srrh yyerror(s, s1, s2, s3, s4)
1704aaebc40Srrh char *s, *s1, *s2, *s3, *s4;
1714aaebc40Srrh {
1724aaebc40Srrh if (synerr)
1734aaebc40Srrh return;
1744aaebc40Srrh fprintf(stderr, "pic: ");
1754aaebc40Srrh fprintf(stderr, s, s1, s2, s3, s4);
1764aaebc40Srrh fprintf(stderr, " near line %d, file %s\n", lineno, filename);
1774aaebc40Srrh eprint();
1784aaebc40Srrh synerr = 1;
1794aaebc40Srrh }
1804aaebc40Srrh
eprint()1814aaebc40Srrh eprint() /* try to print context around error */
1824aaebc40Srrh {
1834aaebc40Srrh char *p, *q;
1844aaebc40Srrh int c;
1854aaebc40Srrh
1864aaebc40Srrh p = ep - 1;
1874aaebc40Srrh if (p > ebuf && *p == '\n')
1884aaebc40Srrh p--;
1894aaebc40Srrh for ( ; p >= ebuf && *p != '\n'; p--)
1904aaebc40Srrh ;
1914aaebc40Srrh while (*p == '\n')
1924aaebc40Srrh p++;
1934aaebc40Srrh fprintf(stderr, " context is\n\t");
1944aaebc40Srrh while (p < ep)
1954aaebc40Srrh putc(*p++, stderr);
1964aaebc40Srrh fprintf(stderr, " ^ ");
1974aaebc40Srrh while (pb >= pbuf)
1984aaebc40Srrh putc(*pb--, stderr);
1994aaebc40Srrh fgets(ebuf, sizeof ebuf, yyin);
2004aaebc40Srrh fprintf(stderr, "%s", ebuf);
2014aaebc40Srrh pbstr(".PE\n"); /* safety first */
2024aaebc40Srrh ep = ebuf;
2034aaebc40Srrh }
2044aaebc40Srrh
yywrap()2054aaebc40Srrh yywrap() {;}
206