#include #include #include #include #include #include "grap.h" #include "y.tab.h" double margin = MARGIN; /* extra space around edges */ extern double frame_ht, frame_wid, ticklen; extern int just, sizeop, tick_dir; extern double sizexpr, lab_up, lab_rt; char graphname[50] = "Graph"; char graphpos[200] = ""; void print(void) /* arrange final output */ { FILE *fd; Obj *p, *dfp; int c; double dx, dy, xfac, yfac; if (tfd != NULL) { fclose(tfd); /* end the temp file */ tfd = stdout; } if ((p=lookup("margin",0)) != NULL) margin = p->fval; if (frame_ht < 0) /* wasn't set explicitly, so use default */ frame_ht = getvar(lookup("frameht", 0)); if (frame_wid < 0) frame_wid = getvar(lookup("framewid", 0)); dfp = NULL; for (p = objlist; p; p = p->next) { dprintf("print: name = <%s>, type = %d\n", p->name, p->type); if (p->type == NAME) { Point pt, pt1; pt = p->pt; pt1 = p->pt1; fprintf(tfd, "\t# %s %g .. %g, %g .. %g\n", p->name, pt.x, pt1.x, pt.y, pt1.y); if (p->log & XFLAG) { if (pt.x <= 0.0) ERROR "can't take log of x coord %g", pt.x FATAL; logit(pt.x); logit(pt1.x); } if (p->log & YFLAG) { if (pt.y <= 0.0) ERROR "can't take log of y coord %g", pt.y FATAL; logit(pt.y); logit(pt1.y); } if (!(p->coord & XFLAG)) { dx = pt1.x - pt.x; pt.x -= margin * dx; pt1.x += margin * dx; } if (!(p->coord & YFLAG)) { dy = pt1.y - pt.y; pt.y -= margin * dy; pt1.y += margin * dy; } if (autoticks && strcmp(p->name, dflt_coord) == 0) { p->pt = pt; p->pt1 = pt1; if (p->log & XFLAG) { p->pt.x = pow(10.0, pt.x); p->pt1.x = pow(10.0, pt1.x); } if (p->log & YFLAG) { p->pt.y = pow(10.0, pt.y); p->pt1.y = pow(10.0, pt1.y); } dfp = setauto(); } dx = pt1.x - pt.x; dy = pt1.y - pt.y; xfac = dx > 0 ? frame_wid/dx : frame_wid/2; yfac = dy > 0 ? frame_ht/dy : frame_ht/2; fprintf(tfd, "define xy_%s @ ", p->name); if (dx > 0) fprintf(tfd, "\t(($1)-(%g))*%g", pt.x, xfac); else fprintf(tfd, "\t%g", xfac); if (dy > 0) fprintf(tfd, ", (($2)-(%g))*%g @\n", pt.y, yfac); else fprintf(tfd, ", %g @\n", yfac); fprintf(tfd, "define x_%s @ ", p->name); if (dx > 0) fprintf(tfd, "\t(($1)-(%g))*%g @\n", pt.x, xfac); else fprintf(tfd, "\t%g @\n", xfac); fprintf(tfd, "define y_%s @ ", p->name); if (dy > 0) fprintf(tfd, "\t(($1)-(%g))*%g @\n", pt.y, yfac); else fprintf(tfd, "\t%g @\n", yfac); } } if (codegen) frame(); if (codegen && autoticks && dfp) do_autoticks(dfp); if ((fd = fopen(tempfile, "r")) != NULL) { while ((c = getc(fd)) != EOF) putc(c, tfd); fclose(fd); } tfd = NULL; } void endstat(void) /* clean up after each statement */ { just = sizeop = 0; lab_up = lab_rt = 0.0; sizexpr = 0.0; nnum = 0; ntick = 0; tside = 0; tick_dir = OUT; ticklen = TICKLEN; } void graph(char *s) /* graph statement */ { char *p, *os; int c; if (codegen) { fprintf(stdout, "%s: [\n", graphname); print(); /* pump out previous graph */ fprintf(stdout, "\n] %s\n", graphpos); reset(); } if (s) { dprintf("into graph with <%s>\n", s); opentemp(); os = s; while ((c = *s) == ' ' || c == '\t') s++; if (c == '\0') ERROR "no name on graph statement" WARNING; if (!isupper(s[0])) ERROR "graph name %s must be capitalized", s WARNING; for (p=graphname; (c = *s) != ' ' && c != '\t' && c != '\0'; ) *p++ = *s++; *p = '\0'; strcpy(graphpos, s); dprintf("graphname = <%s>, graphpos = <%s>\n", graphname, graphpos); free(os); } } void setup(void) /* done at each .G1 */ { static int firstG1 = 0; reset(); opentemp(); frame_ht = frame_wid = -1; /* reset in frame() */ ticklen = getvar(lookup("ticklen", 0)); if (firstG1++ == 0) do_first(); codegen = synerr = 0; strcpy(graphname, "Graph"); strcpy(graphpos, ""); } void do_first(void) /* done at first .G1: definitions, etc. */ { extern int lib; extern char *lib_defines; char *file; static char buf[50], buf1[50]; /* static because pbstr uses them */ FILE *fp; extern int getpid(void); sprintf(buf, "define pid /%d/\n", getpid()); pbstr(buf); if (lib != 0) { file = unsharp(lib_defines); if ((fp = fopen(file, "r")) != NULL) { sprintf(buf1, "copy \"%s\"\n", file); pbstr(buf1); fclose(fp); } else { fprintf(stderr, "grap warning: can't open %s\n", lib_defines); } } } void reset(void) /* done at each "graph ..." statement */ { Obj *p, *np, *deflist; extern int tlist, toffside, autodir; curr_coord = dflt_coord; ncoord = auto_x = 0; autoticks = LEFT|BOT; autodir = 0; tside = tlist = toffside = 0; tick_dir = OUT; margin = MARGIN; deflist = NULL; for (p = objlist; p; p = np) { np = p->next; if (p->type == DEFNAME || p->type == VARNAME) { p->next = deflist; deflist = p; } else { free(p->name); freeattr(p->attr); free((char *) p); } } objlist = deflist; } void opentemp(void) { if (tfd != NULL) fclose(tfd); if (tfd != stdout) { if (tfd != NULL) fclose(tfd); if ((tfd = fopen(tempfile, "w")) == NULL) { fprintf(stderr, "grap: can't open %s\n", tempfile); exit(1); } } }