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