diff options
author | rsc <devnull@localhost> | 2006-04-14 00:04:03 +0000 |
---|---|---|
committer | rsc <devnull@localhost> | 2006-04-14 00:04:03 +0000 |
commit | b6d98463b416e9d95bc88f948b4abdff6b24aede (patch) | |
tree | 6ae4dabb948c5b3c42a48b34964bdde7b0afa5c2 /src/cmd/tpic/main.c | |
parent | 434d1b41b61a9771f4cec2ca6c0a00b067a50fa0 (diff) | |
download | plan9port-b6d98463b416e9d95bc88f948b4abdff6b24aede.tar.gz plan9port-b6d98463b416e9d95bc88f948b4abdff6b24aede.tar.bz2 plan9port-b6d98463b416e9d95bc88f948b4abdff6b24aede.zip |
tpic
Diffstat (limited to 'src/cmd/tpic/main.c')
-rw-r--r-- | src/cmd/tpic/main.c | 277 |
1 files changed, 277 insertions, 0 deletions
diff --git a/src/cmd/tpic/main.c b/src/cmd/tpic/main.c new file mode 100644 index 00000000..ed310d5d --- /dev/null +++ b/src/cmd/tpic/main.c @@ -0,0 +1,277 @@ +#include <stdio.h> +#include <signal.h> +#include "pic.h" +#include "y.tab.h" + +obj **objlist = 0; /* store the elements here */ +int nobjlist = 0; /* size of objlist array */ +int nobj = 0; + +Attr *attr; /* attributes stored here as collected */ +int nattrlist = 0; +int nattr = 0; /* number of entries in attr_list */ + +Text *text = 0; /* text strings stored here as collected */ +int ntextlist = 0; /* size of text[] array */ +int ntext = 0; +int ntext1 = 0; /* record ntext here on entry to each figure */ + +double curx = 0; +double cury = 0; + +int hvmode = R_DIR; /* R => join left to right, D => top to bottom, etc. */ + +int codegen = 0; /* 1=>output for this picture; 0=>no output */ +int PEseen = 0; /* 1=> PE seen during parsing */ + +double deltx = 6; /* max x value in output, for scaling */ +double delty = 6; /* max y value in output, for scaling */ +int dbg = 0; +int lineno = 0; +char *filename = "-"; +int synerr = 0; +int anyerr = 0; /* becomes 1 if synerr ever 1 */ +char *cmdname; + +double xmin = 30000; /* min values found in actual data */ +double ymin = 30000; +double xmax = -30000; /* max */ +double ymax = -30000; + +int +main(int argc, char **argv) +{ + char buf[20]; + extern void fpecatch(int); + + signal(SIGFPE, fpecatch); + cmdname = argv[0]; + while (argc > 1 && *argv[1] == '-') { + switch (argv[1][1]) { + case 'd': + dbg = atoi(&argv[1][2]); + if (dbg == 0) + dbg = 1; + break; + } + argc--; + argv++; + } + setdefaults(); + objlist = (obj **) grow((char *)objlist, "objlist", nobjlist += 1000, sizeof(obj *)); + text = (Text *) grow((char *)text, "text", ntextlist += 1000, sizeof(Text)); + attr = (Attr *) grow((char *)attr, "attr", nattrlist += 100, sizeof(Attr)); + + sprintf(buf, "/%d/", getpid()); + pushsrc(String, buf); + definition("pid"); + + curfile = infile; + pushsrc(File, curfile->fname); + if (argc <= 1) { + curfile->fin = stdin; + curfile->fname = tostring("-"); + getdata(); + } else + while (argc-- > 1) { + if ((curfile->fin = fopen(*++argv, "r")) == NULL) { + fprintf(stderr, "%s: can't open %s\n", cmdname, *argv); + exit(1); + } + curfile->fname = tostring(*argv); + getdata(); + fclose(curfile->fin); + free(curfile->fname); + } + exit(anyerr); + return 0; +} + +void +fpecatch(int arg) +{ + ERROR "floating point exception" FATAL; +} + +char * +grow(char *ptr, char *name, int num, int size) /* make array bigger */ +{ + char *p; + + if (ptr == NULL) + p = malloc(num * size); + else + p = realloc(ptr, num * size); + if (p == NULL) + ERROR "can't grow %s to %d", name, num * size FATAL; + return p; +} + +static struct { + char *name; + double val; + short scalable; /* 1 => adjust when "scale" changes */ +} defaults[] ={ + "scale", SCALE, 1, + "lineht", HT, 1, + "linewid", HT, 1, + "moveht", HT, 1, + "movewid", HT, 1, + "dashwid", HT10, 1, + "boxht", HT, 1, + "boxwid", WID, 1, + "circlerad", HT2, 1, + "arcrad", HT2, 1, + "ellipseht", HT, 1, + "ellipsewid", WID, 1, + "arrowht", HT5, 1, + "arrowwid", HT10, 1, + "arrowhead", 2, 0, /* arrowhead style */ + "textht", 0.0, 1, /* 6 lines/inch is also a useful value */ + "textwid", 0.0, 1, + "maxpsht", MAXHT, 0, + "maxpswid", MAXWID, 0, + "fillval", 0.3, 0, /* gray value for filling boxes */ + NULL, 0, 0 +}; + +void +setdefaults(void) /* set default sizes for variables like boxht */ +{ + int i; + YYSTYPE v; + + for (i = 0; defaults[i].name != NULL; i++) { + v.f = defaults[i].val; + makevar(tostring(defaults[i].name), VARNAME, v); + } +} + +void +resetvar(void) /* reset variables listed */ +{ + int i, j; + + if (nattr == 0) { /* none listed, so do all */ + setdefaults(); + return; + } + for (i = 0; i < nattr; i++) { + for (j = 0; defaults[j].name != NULL; j++) + if (strcmp(defaults[j].name, attr[i].a_val.p) == 0) { + setfval(defaults[j].name, defaults[j].val); + free(attr[i].a_val.p); + break; + } + } +} + +void +checkscale(char *s) /* if s is "scale", adjust default variables */ +{ + int i; + double scale; + + if (strcmp(s, "scale") == 0) { + scale = getfval("scale"); + for (i = 1; defaults[i].name != NULL; i++) + if (defaults[i].scalable) + setfval(defaults[i].name, defaults[i].val * scale); + } +} + +void +getdata(void) +{ + char *p, buf[1000], buf1[100]; + int ln; + + curfile->lineno = 0; + printlf(1, curfile->fname); + while (fgets(buf, sizeof buf, curfile->fin) != NULL) { + curfile->lineno++; + if (*buf == '.' && *(buf+1) == 'P' && *(buf+2) == 'S') { + for (p = &buf[3]; *p == ' '; p++) + ; + if (*p++ == '<') { + Infile svfile; + svfile = *curfile; + sscanf(p, "%s", buf1); + if ((curfile->fin=fopen(buf1, "r")) == NULL) + ERROR "can't open %s", buf1 FATAL; + curfile->fname = tostring(buf1); + getdata(); + fclose(curfile->fin); + free(curfile->fname); + *curfile = svfile; + printlf(curfile->lineno, curfile->fname); + continue; + } + reset(); + yyparse(); + anyerr += synerr; + /* yylval.i now contains 'E' or 'F' from .PE or .PF */ + + deltx = (xmax - xmin) / getfval("scale"); + delty = (ymax - ymin) / getfval("scale"); + if (buf[3] == ' ') { /* next things are wid & ht */ + if (sscanf(&buf[4],"%lf %lf", &deltx, &delty) < 2) + delty = deltx * (ymax-ymin) / (xmax-xmin); + /* else { + /* double xfac, yfac; */ + /* xfac = deltx / (xmax-xmin); + /* yfac = delty / (ymax-ymin); + /* if (xfac <= yfac) + /* delty = xfac * (ymax-ymin); + /* else + /* deltx = yfac * (xmax-xmin); + /*} + */ + } + dprintf("deltx = %g, delty = %g\n", deltx, delty); + if (codegen && !synerr) { + openpl(); /* puts out .PS, with ht & wid stuck in */ + printlf(curfile->lineno+1, NULL); + print(); /* assumes \n at end */ + closepl(); /* does the .PE/F */ + } + printlf(curfile->lineno+1, NULL); + fflush(stdout); + } else if (buf[0] == '.' && buf[1] == 'l' && buf[2] == 'f') { + if (sscanf(buf+3, "%d %s", &ln, buf1) == 2) { + free(curfile->fname); + printlf(curfile->lineno = ln, curfile->fname = tostring(buf1)); + } else + printlf(curfile->lineno = ln, NULL); + } else + fputs(buf, stdout); + } +} + +void +reset(void) +{ + obj *op; + int i; + extern int nstack; + + for (i = 0; i < nobj; i++) { + op = objlist[i]; + if (op->o_type == BLOCK) + freesymtab(op->o_symtab); + free((char *)objlist[i]); + } + nobj = 0; + nattr = 0; + for (i = 0; i < ntext; i++) + if (text[i].t_val) + free(text[i].t_val); + ntext = ntext1 = 0; + codegen = synerr = 0; + nstack = 0; + curx = cury = 0; + PEseen = 0; + hvmode = R_DIR; + xmin = ymin = 30000; + xmax = ymax = -30000; +} |