diff options
author | Petter Rodhelind <petter.rodhelind@gmail.com> | 2017-07-03 20:55:47 +0200 |
---|---|---|
committer | Petter Rodhelind <petter.rodhelind@gmail.com> | 2017-07-03 20:55:47 +0200 |
commit | 7d0663b7c023cd7dd2764cb232798f8bc1309c20 (patch) | |
tree | e5b8eca2f1b0e825f115fb1b73c3ccb0103b9f39 /src/cmd/svgpic/main.c | |
parent | 5e176c5794de5124b67d3ac4ea7afe2f210b6d84 (diff) | |
parent | 711336c348ac9b98cd22464496e6b7e9a109c3a9 (diff) | |
download | plan9port-7d0663b7c023cd7dd2764cb232798f8bc1309c20.tar.gz plan9port-7d0663b7c023cd7dd2764cb232798f8bc1309c20.tar.bz2 plan9port-7d0663b7c023cd7dd2764cb232798f8bc1309c20.zip |
Merge remote-tracking branch 'upstream/master'
Diffstat (limited to 'src/cmd/svgpic/main.c')
-rw-r--r-- | src/cmd/svgpic/main.c | 283 |
1 files changed, 283 insertions, 0 deletions
diff --git a/src/cmd/svgpic/main.c b/src/cmd/svgpic/main.c new file mode 100644 index 00000000..1c7f5f65 --- /dev/null +++ b/src/cmd/svgpic/main.c @@ -0,0 +1,283 @@ +#include <stdio.h> +#include <signal.h> +#include <stdlib.h> +#include <string.h> +#include "pic.h" +#include "y.tab.h" + +char *version = "version July 5, 1993"; + +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 */ +char *PEstring; /* "PS" or "PE" picked up by lexer */ + +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; + +void fpecatch(int); +void getdata(void), setdefaults(void); +void setfval(char *, double); +int getpid(void); + +int +main(int argc, char *argv[]) +{ + char buf[20]; + + 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; + fprintf(stderr, "%s\n", version); + break; + case 'V': + fprintf(stderr, "%s\n", version); + return 0; + } + 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); + } + return anyerr; +} + +void fpecatch(int n) +{ + ERROR "floating point exception %d", n 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.7, 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; + void reset(void), openpl(char *), closepl(char *), print(void); + int yyparse(void); + + 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; + 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(&buf[3]); /* puts out .PS, with ht & wid stuck in */ + printlf(curfile->lineno+1, NULL); + print(); /* assumes \n at end */ + closepl(PEstring); /* does the .PE/F */ + free(PEstring); + } + 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; + extern void freesymtab(struct symtab *); + + 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; + PEstring = 0; + hvmode = R_DIR; + xmin = ymin = 30000; + xmax = ymax = -30000; +} |