1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <math.h> 5 #include <ctype.h> 6 #include "grap.h" 7 #include "y.tab.h" 8 9 double margin = MARGIN; /* extra space around edges */ 10 extern double frame_ht, frame_wid, ticklen; 11 extern int just, sizeop, tick_dir; 12 extern double sizexpr, lab_up, lab_rt; 13 14 char graphname[50] = "Graph"; 15 char graphpos[200] = ""; 16 17 void print(void) /* arrange final output */ 18 { 19 FILE *fd; 20 Obj *p, *dfp; 21 int c; 22 double dx, dy, xfac, yfac; 23 24 if (tfd != NULL) { 25 fclose(tfd); /* end the temp file */ 26 tfd = stdout; 27 } 28 29 if ((p=lookup("margin",0)) != NULL) 30 margin = p->fval; 31 if (frame_ht < 0) /* wasn't set explicitly, so use default */ 32 frame_ht = getvar(lookup("frameht", 0)); 33 if (frame_wid < 0) 34 frame_wid = getvar(lookup("framewid", 0)); 35 dfp = NULL; 36 for (p = objlist; p; p = p->next) { 37 dprintf("print: name = <%s>, type = %d\n", p->name, p->type); 38 if (p->type == NAME) { 39 Point pt, pt1; 40 pt = p->pt; 41 pt1 = p->pt1; 42 fprintf(tfd, "\t# %s %g .. %g, %g .. %g\n", 43 p->name, pt.x, pt1.x, pt.y, pt1.y); 44 if (p->log & XFLAG) { 45 if (pt.x <= 0.0) 46 ERROR "can't take log of x coord %g", pt.x FATAL; 47 logit(pt.x); 48 logit(pt1.x); 49 } 50 if (p->log & YFLAG) { 51 if (pt.y <= 0.0) 52 ERROR "can't take log of y coord %g", pt.y FATAL; 53 logit(pt.y); 54 logit(pt1.y); 55 } 56 if (!(p->coord & XFLAG)) { 57 dx = pt1.x - pt.x; 58 pt.x -= margin * dx; 59 pt1.x += margin * dx; 60 } 61 if (!(p->coord & YFLAG)) { 62 dy = pt1.y - pt.y; 63 pt.y -= margin * dy; 64 pt1.y += margin * dy; 65 } 66 if (autoticks && strcmp(p->name, dflt_coord) == 0) { 67 p->pt = pt; 68 p->pt1 = pt1; 69 if (p->log & XFLAG) { 70 p->pt.x = pow(10.0, pt.x); 71 p->pt1.x = pow(10.0, pt1.x); 72 } 73 if (p->log & YFLAG) { 74 p->pt.y = pow(10.0, pt.y); 75 p->pt1.y = pow(10.0, pt1.y); 76 } 77 dfp = setauto(); 78 } 79 dx = pt1.x - pt.x; 80 dy = pt1.y - pt.y; 81 xfac = dx > 0 ? frame_wid/dx : frame_wid/2; 82 yfac = dy > 0 ? frame_ht/dy : frame_ht/2; 83 84 fprintf(tfd, "define xy_%s @ ", p->name); 85 if (dx > 0) 86 fprintf(tfd, "\t(($1)-(%g))*%g", pt.x, xfac); 87 else 88 fprintf(tfd, "\t%g", xfac); 89 if (dy > 0) 90 fprintf(tfd, ", (($2)-(%g))*%g @\n", pt.y, yfac); 91 else 92 fprintf(tfd, ", %g @\n", yfac); 93 fprintf(tfd, "define x_%s @ ", p->name); 94 if (dx > 0) 95 fprintf(tfd, "\t(($1)-(%g))*%g @\n", pt.x, xfac); 96 else 97 fprintf(tfd, "\t%g @\n", xfac); 98 fprintf(tfd, "define y_%s @ ", p->name); 99 if (dy > 0) 100 fprintf(tfd, "\t(($1)-(%g))*%g @\n", pt.y, yfac); 101 else 102 fprintf(tfd, "\t%g @\n", yfac); 103 } 104 } 105 if (codegen) 106 frame(); 107 if (codegen && autoticks && dfp) 108 do_autoticks(dfp); 109 110 if ((fd = fopen(tempfile, "r")) != NULL) { 111 while ((c = getc(fd)) != EOF) 112 putc(c, tfd); 113 fclose(fd); 114 } 115 tfd = NULL; 116 } 117 118 void endstat(void) /* clean up after each statement */ 119 { 120 121 just = sizeop = 0; 122 lab_up = lab_rt = 0.0; 123 sizexpr = 0.0; 124 nnum = 0; 125 ntick = 0; 126 tside = 0; 127 tick_dir = OUT; 128 ticklen = TICKLEN; 129 } 130 131 void graph(char *s) /* graph statement */ 132 { 133 char *p, *os; 134 int c; 135 136 if (codegen) { 137 fprintf(stdout, "%s: [\n", graphname); 138 print(); /* pump out previous graph */ 139 fprintf(stdout, "\n] %s\n", graphpos); 140 reset(); 141 } 142 if (s) { 143 dprintf("into graph with <%s>\n", s); 144 opentemp(); 145 os = s; 146 while ((c = *s) == ' ' || c == '\t') 147 s++; 148 if (c == '\0') 149 ERROR "no name on graph statement" WARNING; 150 if (!isupper(s[0])) 151 ERROR "graph name %s must be capitalized", s WARNING; 152 for (p=graphname; (c = *s) != ' ' && c != '\t' && c != '\0'; ) 153 *p++ = *s++; 154 *p = '\0'; 155 strcpy(graphpos, s); 156 dprintf("graphname = <%s>, graphpos = <%s>\n", graphname, graphpos); 157 free(os); 158 } 159 } 160 161 void setup(void) /* done at each .G1 */ 162 { 163 static int firstG1 = 0; 164 165 reset(); 166 opentemp(); 167 frame_ht = frame_wid = -1; /* reset in frame() */ 168 ticklen = getvar(lookup("ticklen", 0)); 169 if (firstG1++ == 0) 170 do_first(); 171 codegen = synerr = 0; 172 strcpy(graphname, "Graph"); 173 strcpy(graphpos, ""); 174 } 175 176 void do_first(void) /* done at first .G1: definitions, etc. */ 177 { 178 extern int lib; 179 extern char *lib_defines; 180 static char buf[50], buf1[50]; /* static because pbstr uses them */ 181 FILE *fp; 182 extern int getpid(void); 183 184 sprintf(buf, "define pid /%d/\n", getpid()); 185 pbstr(buf); 186 if (lib != 0) { 187 if ((fp = fopen(lib_defines, "r")) != NULL) { 188 sprintf(buf1, "copy \"%s\"\n", lib_defines); 189 pbstr(buf1); 190 fclose(fp); 191 } else { 192 fprintf(stderr, "grap warning: can't open %s\n", lib_defines); 193 } 194 } 195 } 196 197 void reset(void) /* done at each "graph ..." statement */ 198 { 199 Obj *p, *np, *deflist; 200 extern int tlist, toffside, autodir; 201 202 curr_coord = dflt_coord; 203 ncoord = auto_x = 0; 204 autoticks = LEFT|BOT; 205 autodir = 0; 206 tside = tlist = toffside = 0; 207 tick_dir = OUT; 208 margin = MARGIN; 209 deflist = NULL; 210 for (p = objlist; p; p = np) { 211 np = p->next; 212 if (p->type == DEFNAME || p->type == VARNAME) { 213 p->next = deflist; 214 deflist = p; 215 } else { 216 free(p->name); 217 freeattr(p->attr); 218 free((char *) p); 219 } 220 } 221 objlist = deflist; 222 } 223 224 void opentemp(void) 225 { 226 if (tfd != NULL) 227 fclose(tfd); 228 if (tfd != stdout) { 229 if (tfd != NULL) 230 fclose(tfd); 231 if ((tfd = fopen(tempfile, "w")) == NULL) { 232 fprintf(stderr, "grap: can't open %s\n", tempfile); 233 exit(1); 234 } 235 } 236 } 237