13e12c5d1SDavid du Colombier #include <stdio.h>
23e12c5d1SDavid du Colombier #include <signal.h>
33e12c5d1SDavid du Colombier #include <stdlib.h>
43e12c5d1SDavid du Colombier #include <string.h>
53e12c5d1SDavid du Colombier #include "pic.h"
63e12c5d1SDavid du Colombier #include "y.tab.h"
73e12c5d1SDavid du Colombier
8*7dd7cddfSDavid du Colombier char *version = "version July 5, 1993";
9*7dd7cddfSDavid du Colombier
103e12c5d1SDavid du Colombier obj **objlist = 0; /* store the elements here */
113e12c5d1SDavid du Colombier int nobjlist = 0; /* size of objlist array */
123e12c5d1SDavid du Colombier int nobj = 0;
133e12c5d1SDavid du Colombier
143e12c5d1SDavid du Colombier Attr *attr; /* attributes stored here as collected */
153e12c5d1SDavid du Colombier int nattrlist = 0;
163e12c5d1SDavid du Colombier int nattr = 0; /* number of entries in attr_list */
173e12c5d1SDavid du Colombier
183e12c5d1SDavid du Colombier Text *text = 0; /* text strings stored here as collected */
193e12c5d1SDavid du Colombier int ntextlist = 0; /* size of text[] array */
203e12c5d1SDavid du Colombier int ntext = 0;
213e12c5d1SDavid du Colombier int ntext1 = 0; /* record ntext here on entry to each figure */
223e12c5d1SDavid du Colombier
233e12c5d1SDavid du Colombier double curx = 0;
243e12c5d1SDavid du Colombier double cury = 0;
253e12c5d1SDavid du Colombier
263e12c5d1SDavid du Colombier int hvmode = R_DIR; /* R => join left to right, D => top to bottom, etc. */
273e12c5d1SDavid du Colombier
283e12c5d1SDavid du Colombier int codegen = 0; /* 1=>output for this picture; 0=>no output */
29*7dd7cddfSDavid du Colombier char *PEstring; /* "PS" or "PE" picked up by lexer */
303e12c5d1SDavid du Colombier
313e12c5d1SDavid du Colombier double deltx = 6; /* max x value in output, for scaling */
323e12c5d1SDavid du Colombier double delty = 6; /* max y value in output, for scaling */
333e12c5d1SDavid du Colombier int dbg = 0;
343e12c5d1SDavid du Colombier int lineno = 0;
353e12c5d1SDavid du Colombier char *filename = "-";
363e12c5d1SDavid du Colombier int synerr = 0;
373e12c5d1SDavid du Colombier int anyerr = 0; /* becomes 1 if synerr ever 1 */
383e12c5d1SDavid du Colombier char *cmdname;
393e12c5d1SDavid du Colombier
403e12c5d1SDavid du Colombier double xmin = 30000; /* min values found in actual data */
413e12c5d1SDavid du Colombier double ymin = 30000;
423e12c5d1SDavid du Colombier double xmax = -30000; /* max */
433e12c5d1SDavid du Colombier double ymax = -30000;
443e12c5d1SDavid du Colombier
45*7dd7cddfSDavid du Colombier void fpecatch(int);
463e12c5d1SDavid du Colombier void getdata(void), setdefaults(void);
473e12c5d1SDavid du Colombier void setfval(char *, double);
483e12c5d1SDavid du Colombier int getpid(void);
493e12c5d1SDavid du Colombier
main(int argc,char * argv[])503e12c5d1SDavid du Colombier main(int argc, char *argv[])
513e12c5d1SDavid du Colombier {
523e12c5d1SDavid du Colombier char buf[20];
533e12c5d1SDavid du Colombier
543e12c5d1SDavid du Colombier signal(SIGFPE, fpecatch);
553e12c5d1SDavid du Colombier cmdname = argv[0];
563e12c5d1SDavid du Colombier while (argc > 1 && *argv[1] == '-') {
573e12c5d1SDavid du Colombier switch (argv[1][1]) {
583e12c5d1SDavid du Colombier case 'd':
593e12c5d1SDavid du Colombier dbg = atoi(&argv[1][2]);
603e12c5d1SDavid du Colombier if (dbg == 0)
613e12c5d1SDavid du Colombier dbg = 1;
623e12c5d1SDavid du Colombier fprintf(stderr, "%s\n", version);
633e12c5d1SDavid du Colombier break;
64*7dd7cddfSDavid du Colombier case 'V':
65*7dd7cddfSDavid du Colombier fprintf(stderr, "%s\n", version);
66*7dd7cddfSDavid du Colombier return 0;
673e12c5d1SDavid du Colombier }
683e12c5d1SDavid du Colombier argc--;
693e12c5d1SDavid du Colombier argv++;
703e12c5d1SDavid du Colombier }
713e12c5d1SDavid du Colombier setdefaults();
723e12c5d1SDavid du Colombier objlist = (obj **) grow((char *)objlist, "objlist", nobjlist += 1000, sizeof(obj *));
733e12c5d1SDavid du Colombier text = (Text *) grow((char *)text, "text", ntextlist += 1000, sizeof(Text));
743e12c5d1SDavid du Colombier attr = (Attr *) grow((char *)attr, "attr", nattrlist += 100, sizeof(Attr));
753e12c5d1SDavid du Colombier
763e12c5d1SDavid du Colombier sprintf(buf, "/%d/", getpid());
773e12c5d1SDavid du Colombier pushsrc(String, buf);
783e12c5d1SDavid du Colombier definition("pid");
793e12c5d1SDavid du Colombier
803e12c5d1SDavid du Colombier curfile = infile;
813e12c5d1SDavid du Colombier pushsrc(File, curfile->fname);
823e12c5d1SDavid du Colombier if (argc <= 1) {
833e12c5d1SDavid du Colombier curfile->fin = stdin;
843e12c5d1SDavid du Colombier curfile->fname = tostring("-");
853e12c5d1SDavid du Colombier getdata();
863e12c5d1SDavid du Colombier } else
873e12c5d1SDavid du Colombier while (argc-- > 1) {
883e12c5d1SDavid du Colombier if ((curfile->fin = fopen(*++argv, "r")) == NULL) {
893e12c5d1SDavid du Colombier fprintf(stderr, "%s: can't open %s\n", cmdname, *argv);
903e12c5d1SDavid du Colombier exit(1);
913e12c5d1SDavid du Colombier }
923e12c5d1SDavid du Colombier curfile->fname = tostring(*argv);
933e12c5d1SDavid du Colombier getdata();
943e12c5d1SDavid du Colombier fclose(curfile->fin);
953e12c5d1SDavid du Colombier free(curfile->fname);
963e12c5d1SDavid du Colombier }
97*7dd7cddfSDavid du Colombier return anyerr;
983e12c5d1SDavid du Colombier }
993e12c5d1SDavid du Colombier
fpecatch(int n)100*7dd7cddfSDavid du Colombier void fpecatch(int n)
1013e12c5d1SDavid du Colombier {
102*7dd7cddfSDavid du Colombier ERROR "floating point exception %d", n FATAL;
1033e12c5d1SDavid du Colombier }
1043e12c5d1SDavid du Colombier
grow(char * ptr,char * name,int num,int size)1053e12c5d1SDavid du Colombier char *grow(char *ptr, char *name, int num, int size) /* make array bigger */
1063e12c5d1SDavid du Colombier {
1073e12c5d1SDavid du Colombier char *p;
1083e12c5d1SDavid du Colombier
1093e12c5d1SDavid du Colombier if (ptr == NULL)
1103e12c5d1SDavid du Colombier p = malloc(num * size);
1113e12c5d1SDavid du Colombier else
1123e12c5d1SDavid du Colombier p = realloc(ptr, num * size);
1133e12c5d1SDavid du Colombier if (p == NULL)
1143e12c5d1SDavid du Colombier ERROR "can't grow %s to %d", name, num * size FATAL;
1153e12c5d1SDavid du Colombier return p;
1163e12c5d1SDavid du Colombier }
1173e12c5d1SDavid du Colombier
1183e12c5d1SDavid du Colombier static struct {
1193e12c5d1SDavid du Colombier char *name;
1203e12c5d1SDavid du Colombier double val;
1213e12c5d1SDavid du Colombier short scalable; /* 1 => adjust when "scale" changes */
1223e12c5d1SDavid du Colombier } defaults[] ={
1233e12c5d1SDavid du Colombier "scale", SCALE, 1,
1243e12c5d1SDavid du Colombier "lineht", HT, 1,
1253e12c5d1SDavid du Colombier "linewid", HT, 1,
1263e12c5d1SDavid du Colombier "moveht", HT, 1,
1273e12c5d1SDavid du Colombier "movewid", HT, 1,
1283e12c5d1SDavid du Colombier "dashwid", HT10, 1,
1293e12c5d1SDavid du Colombier "boxht", HT, 1,
1303e12c5d1SDavid du Colombier "boxwid", WID, 1,
1313e12c5d1SDavid du Colombier "circlerad", HT2, 1,
1323e12c5d1SDavid du Colombier "arcrad", HT2, 1,
1333e12c5d1SDavid du Colombier "ellipseht", HT, 1,
1343e12c5d1SDavid du Colombier "ellipsewid", WID, 1,
1353e12c5d1SDavid du Colombier "arrowht", HT5, 1,
1363e12c5d1SDavid du Colombier "arrowwid", HT10, 1,
1373e12c5d1SDavid du Colombier "arrowhead", 2, 0, /* arrowhead style */
1383e12c5d1SDavid du Colombier "textht", 0.0, 1, /* 6 lines/inch is also a useful value */
1393e12c5d1SDavid du Colombier "textwid", 0.0, 1,
1403e12c5d1SDavid du Colombier "maxpsht", MAXHT, 0,
1413e12c5d1SDavid du Colombier "maxpswid", MAXWID, 0,
142*7dd7cddfSDavid du Colombier "fillval", 0.7, 0, /* gray value for filling boxes */
1433e12c5d1SDavid du Colombier NULL, 0, 0
1443e12c5d1SDavid du Colombier };
1453e12c5d1SDavid du Colombier
setdefaults(void)1463e12c5d1SDavid du Colombier void setdefaults(void) /* set default sizes for variables like boxht */
1473e12c5d1SDavid du Colombier {
1483e12c5d1SDavid du Colombier int i;
1493e12c5d1SDavid du Colombier YYSTYPE v;
1503e12c5d1SDavid du Colombier
1513e12c5d1SDavid du Colombier for (i = 0; defaults[i].name != NULL; i++) {
1523e12c5d1SDavid du Colombier v.f = defaults[i].val;
1533e12c5d1SDavid du Colombier makevar(tostring(defaults[i].name), VARNAME, v);
1543e12c5d1SDavid du Colombier }
1553e12c5d1SDavid du Colombier }
1563e12c5d1SDavid du Colombier
resetvar(void)1573e12c5d1SDavid du Colombier void resetvar(void) /* reset variables listed */
1583e12c5d1SDavid du Colombier {
1593e12c5d1SDavid du Colombier int i, j;
1603e12c5d1SDavid du Colombier
1613e12c5d1SDavid du Colombier if (nattr == 0) { /* none listed, so do all */
1623e12c5d1SDavid du Colombier setdefaults();
1633e12c5d1SDavid du Colombier return;
1643e12c5d1SDavid du Colombier }
1653e12c5d1SDavid du Colombier for (i = 0; i < nattr; i++) {
1663e12c5d1SDavid du Colombier for (j = 0; defaults[j].name != NULL; j++)
1673e12c5d1SDavid du Colombier if (strcmp(defaults[j].name, attr[i].a_val.p) == 0) {
1683e12c5d1SDavid du Colombier setfval(defaults[j].name, defaults[j].val);
1693e12c5d1SDavid du Colombier free(attr[i].a_val.p);
1703e12c5d1SDavid du Colombier break;
1713e12c5d1SDavid du Colombier }
1723e12c5d1SDavid du Colombier }
1733e12c5d1SDavid du Colombier }
1743e12c5d1SDavid du Colombier
checkscale(char * s)1753e12c5d1SDavid du Colombier void checkscale(char *s) /* if s is "scale", adjust default variables */
1763e12c5d1SDavid du Colombier {
1773e12c5d1SDavid du Colombier int i;
1783e12c5d1SDavid du Colombier double scale;
1793e12c5d1SDavid du Colombier
1803e12c5d1SDavid du Colombier if (strcmp(s, "scale") == 0) {
1813e12c5d1SDavid du Colombier scale = getfval("scale");
1823e12c5d1SDavid du Colombier for (i = 1; defaults[i].name != NULL; i++)
1833e12c5d1SDavid du Colombier if (defaults[i].scalable)
1843e12c5d1SDavid du Colombier setfval(defaults[i].name, defaults[i].val * scale);
1853e12c5d1SDavid du Colombier }
1863e12c5d1SDavid du Colombier }
1873e12c5d1SDavid du Colombier
getdata(void)1883e12c5d1SDavid du Colombier void getdata(void)
1893e12c5d1SDavid du Colombier {
1903e12c5d1SDavid du Colombier char *p, buf[1000], buf1[100];
1913e12c5d1SDavid du Colombier int ln;
192*7dd7cddfSDavid du Colombier void reset(void), openpl(char *), closepl(char *), print(void);
1933e12c5d1SDavid du Colombier int yyparse(void);
1943e12c5d1SDavid du Colombier
1953e12c5d1SDavid du Colombier curfile->lineno = 0;
1963e12c5d1SDavid du Colombier printlf(1, curfile->fname);
1973e12c5d1SDavid du Colombier while (fgets(buf, sizeof buf, curfile->fin) != NULL) {
1983e12c5d1SDavid du Colombier curfile->lineno++;
1993e12c5d1SDavid du Colombier if (*buf == '.' && *(buf+1) == 'P' && *(buf+2) == 'S') {
2003e12c5d1SDavid du Colombier for (p = &buf[3]; *p == ' '; p++)
2013e12c5d1SDavid du Colombier ;
2023e12c5d1SDavid du Colombier if (*p++ == '<') {
2033e12c5d1SDavid du Colombier Infile svfile;
2043e12c5d1SDavid du Colombier svfile = *curfile;
2053e12c5d1SDavid du Colombier sscanf(p, "%s", buf1);
2063e12c5d1SDavid du Colombier if ((curfile->fin=fopen(buf1, "r")) == NULL)
2073e12c5d1SDavid du Colombier ERROR "can't open %s", buf1 FATAL;
2083e12c5d1SDavid du Colombier curfile->fname = tostring(buf1);
2093e12c5d1SDavid du Colombier getdata();
2103e12c5d1SDavid du Colombier fclose(curfile->fin);
2113e12c5d1SDavid du Colombier free(curfile->fname);
2123e12c5d1SDavid du Colombier *curfile = svfile;
2133e12c5d1SDavid du Colombier printlf(curfile->lineno, curfile->fname);
2143e12c5d1SDavid du Colombier continue;
2153e12c5d1SDavid du Colombier }
2163e12c5d1SDavid du Colombier reset();
2173e12c5d1SDavid du Colombier yyparse();
2183e12c5d1SDavid du Colombier anyerr += synerr;
2193e12c5d1SDavid du Colombier deltx = (xmax - xmin) / getfval("scale");
2203e12c5d1SDavid du Colombier delty = (ymax - ymin) / getfval("scale");
2213e12c5d1SDavid du Colombier if (buf[3] == ' ') { /* next things are wid & ht */
2223e12c5d1SDavid du Colombier if (sscanf(&buf[4],"%lf %lf", &deltx, &delty) < 2)
2233e12c5d1SDavid du Colombier delty = deltx * (ymax-ymin) / (xmax-xmin);
2243e12c5d1SDavid du Colombier /* else {
2253e12c5d1SDavid du Colombier /* double xfac, yfac; */
2263e12c5d1SDavid du Colombier /* xfac = deltx / (xmax-xmin);
2273e12c5d1SDavid du Colombier /* yfac = delty / (ymax-ymin);
2283e12c5d1SDavid du Colombier /* if (xfac <= yfac)
2293e12c5d1SDavid du Colombier /* delty = xfac * (ymax-ymin);
2303e12c5d1SDavid du Colombier /* else
2313e12c5d1SDavid du Colombier /* deltx = yfac * (xmax-xmin);
2323e12c5d1SDavid du Colombier /*}
2333e12c5d1SDavid du Colombier */
2343e12c5d1SDavid du Colombier }
2353e12c5d1SDavid du Colombier dprintf("deltx = %g, delty = %g\n", deltx, delty);
2363e12c5d1SDavid du Colombier if (codegen && !synerr) {
2373e12c5d1SDavid du Colombier openpl(&buf[3]); /* puts out .PS, with ht & wid stuck in */
2383e12c5d1SDavid du Colombier printlf(curfile->lineno+1, NULL);
2393e12c5d1SDavid du Colombier print(); /* assumes \n at end */
240*7dd7cddfSDavid du Colombier closepl(PEstring); /* does the .PE/F */
241*7dd7cddfSDavid du Colombier free(PEstring);
2423e12c5d1SDavid du Colombier }
2433e12c5d1SDavid du Colombier printlf(curfile->lineno+1, NULL);
2443e12c5d1SDavid du Colombier fflush(stdout);
2453e12c5d1SDavid du Colombier } else if (buf[0] == '.' && buf[1] == 'l' && buf[2] == 'f') {
2463e12c5d1SDavid du Colombier if (sscanf(buf+3, "%d %s", &ln, buf1) == 2) {
2473e12c5d1SDavid du Colombier free(curfile->fname);
2483e12c5d1SDavid du Colombier printlf(curfile->lineno = ln, curfile->fname = tostring(buf1));
2493e12c5d1SDavid du Colombier } else
2503e12c5d1SDavid du Colombier printlf(curfile->lineno = ln, NULL);
2513e12c5d1SDavid du Colombier } else
2523e12c5d1SDavid du Colombier fputs(buf, stdout);
2533e12c5d1SDavid du Colombier }
2543e12c5d1SDavid du Colombier }
2553e12c5d1SDavid du Colombier
reset(void)2563e12c5d1SDavid du Colombier void reset(void)
2573e12c5d1SDavid du Colombier {
2583e12c5d1SDavid du Colombier obj *op;
2593e12c5d1SDavid du Colombier int i;
2603e12c5d1SDavid du Colombier extern int nstack;
2613e12c5d1SDavid du Colombier extern void freesymtab(struct symtab *);
2623e12c5d1SDavid du Colombier
2633e12c5d1SDavid du Colombier for (i = 0; i < nobj; i++) {
2643e12c5d1SDavid du Colombier op = objlist[i];
2653e12c5d1SDavid du Colombier if (op->o_type == BLOCK)
2663e12c5d1SDavid du Colombier freesymtab(op->o_symtab);
2673e12c5d1SDavid du Colombier free((char *)objlist[i]);
2683e12c5d1SDavid du Colombier }
2693e12c5d1SDavid du Colombier nobj = 0;
2703e12c5d1SDavid du Colombier nattr = 0;
2713e12c5d1SDavid du Colombier for (i = 0; i < ntext; i++)
2723e12c5d1SDavid du Colombier if (text[i].t_val)
2733e12c5d1SDavid du Colombier free(text[i].t_val);
2743e12c5d1SDavid du Colombier ntext = ntext1 = 0;
2753e12c5d1SDavid du Colombier codegen = synerr = 0;
2763e12c5d1SDavid du Colombier nstack = 0;
2773e12c5d1SDavid du Colombier curx = cury = 0;
278*7dd7cddfSDavid du Colombier PEstring = 0;
2793e12c5d1SDavid du Colombier hvmode = R_DIR;
2803e12c5d1SDavid du Colombier xmin = ymin = 30000;
2813e12c5d1SDavid du Colombier xmax = ymax = -30000;
2823e12c5d1SDavid du Colombier }
283