1 #include <stdio.h> 2 #include <signal.h> 3 #include <stdlib.h> 4 #include <string.h> 5 #include "pic.h" 6 #include "y.tab.h" 7 8 obj **objlist = 0; /* store the elements here */ 9 int nobjlist = 0; /* size of objlist array */ 10 int nobj = 0; 11 12 Attr *attr; /* attributes stored here as collected */ 13 int nattrlist = 0; 14 int nattr = 0; /* number of entries in attr_list */ 15 16 Text *text = 0; /* text strings stored here as collected */ 17 int ntextlist = 0; /* size of text[] array */ 18 int ntext = 0; 19 int ntext1 = 0; /* record ntext here on entry to each figure */ 20 21 double curx = 0; 22 double cury = 0; 23 24 int hvmode = R_DIR; /* R => join left to right, D => top to bottom, etc. */ 25 26 int codegen = 0; /* 1=>output for this picture; 0=>no output */ 27 int PEseen = 0; /* 1=> PE seen during parsing */ 28 29 double deltx = 6; /* max x value in output, for scaling */ 30 double delty = 6; /* max y value in output, for scaling */ 31 int dbg = 0; 32 int lineno = 0; 33 char *filename = "-"; 34 int synerr = 0; 35 int anyerr = 0; /* becomes 1 if synerr ever 1 */ 36 char *cmdname; 37 38 double xmin = 30000; /* min values found in actual data */ 39 double ymin = 30000; 40 double xmax = -30000; /* max */ 41 double ymax = -30000; 42 43 char *version = "version May 7, 1990"; 44 45 void fpecatch(long); 46 void getdata(void), setdefaults(void); 47 void setfval(char *, double); 48 int getpid(void); 49 50 main(int argc, char *argv[]) 51 { 52 char buf[20]; 53 54 signal(SIGFPE, fpecatch); 55 cmdname = argv[0]; 56 while (argc > 1 && *argv[1] == '-') { 57 switch (argv[1][1]) { 58 case 'd': 59 dbg = atoi(&argv[1][2]); 60 if (dbg == 0) 61 dbg = 1; 62 fprintf(stderr, "%s\n", version); 63 break; 64 } 65 argc--; 66 argv++; 67 } 68 setdefaults(); 69 objlist = (obj **) grow((char *)objlist, "objlist", nobjlist += 1000, sizeof(obj *)); 70 text = (Text *) grow((char *)text, "text", ntextlist += 1000, sizeof(Text)); 71 attr = (Attr *) grow((char *)attr, "attr", nattrlist += 100, sizeof(Attr)); 72 73 sprintf(buf, "/%d/", getpid()); 74 pushsrc(String, buf); 75 definition("pid"); 76 77 curfile = infile; 78 pushsrc(File, curfile->fname); 79 if (argc <= 1) { 80 curfile->fin = stdin; 81 curfile->fname = tostring("-"); 82 getdata(); 83 } else 84 while (argc-- > 1) { 85 if ((curfile->fin = fopen(*++argv, "r")) == NULL) { 86 fprintf(stderr, "%s: can't open %s\n", cmdname, *argv); 87 exit(1); 88 } 89 curfile->fname = tostring(*argv); 90 getdata(); 91 fclose(curfile->fin); 92 free(curfile->fname); 93 } 94 exit(anyerr); 95 } 96 97 void fpecatch(long n) 98 { 99 ERROR "floating point exception" FATAL; 100 } 101 102 char *grow(char *ptr, char *name, int num, int size) /* make array bigger */ 103 { 104 char *p; 105 106 if (ptr == NULL) 107 p = malloc(num * size); 108 else 109 p = realloc(ptr, num * size); 110 if (p == NULL) 111 ERROR "can't grow %s to %d", name, num * size FATAL; 112 return p; 113 } 114 115 static struct { 116 char *name; 117 double val; 118 short scalable; /* 1 => adjust when "scale" changes */ 119 } defaults[] ={ 120 "scale", SCALE, 1, 121 "lineht", HT, 1, 122 "linewid", HT, 1, 123 "moveht", HT, 1, 124 "movewid", HT, 1, 125 "dashwid", HT10, 1, 126 "boxht", HT, 1, 127 "boxwid", WID, 1, 128 "circlerad", HT2, 1, 129 "arcrad", HT2, 1, 130 "ellipseht", HT, 1, 131 "ellipsewid", WID, 1, 132 "arrowht", HT5, 1, 133 "arrowwid", HT10, 1, 134 "arrowhead", 2, 0, /* arrowhead style */ 135 "textht", 0.0, 1, /* 6 lines/inch is also a useful value */ 136 "textwid", 0.0, 1, 137 "maxpsht", MAXHT, 0, 138 "maxpswid", MAXWID, 0, 139 "fillval", 0.3, 0, /* gray value for filling boxes */ 140 NULL, 0, 0 141 }; 142 143 void setdefaults(void) /* set default sizes for variables like boxht */ 144 { 145 int i; 146 YYSTYPE v; 147 148 for (i = 0; defaults[i].name != NULL; i++) { 149 v.f = defaults[i].val; 150 makevar(tostring(defaults[i].name), VARNAME, v); 151 } 152 } 153 154 void resetvar(void) /* reset variables listed */ 155 { 156 int i, j; 157 158 if (nattr == 0) { /* none listed, so do all */ 159 setdefaults(); 160 return; 161 } 162 for (i = 0; i < nattr; i++) { 163 for (j = 0; defaults[j].name != NULL; j++) 164 if (strcmp(defaults[j].name, attr[i].a_val.p) == 0) { 165 setfval(defaults[j].name, defaults[j].val); 166 free(attr[i].a_val.p); 167 break; 168 } 169 } 170 } 171 172 void checkscale(char *s) /* if s is "scale", adjust default variables */ 173 { 174 int i; 175 double scale; 176 177 if (strcmp(s, "scale") == 0) { 178 scale = getfval("scale"); 179 for (i = 1; defaults[i].name != NULL; i++) 180 if (defaults[i].scalable) 181 setfval(defaults[i].name, defaults[i].val * scale); 182 } 183 } 184 185 void getdata(void) 186 { 187 char *p, buf[1000], buf1[100]; 188 int ln; 189 void reset(void), openpl(char *), closepl(int), print(void); 190 int yyparse(void); 191 192 curfile->lineno = 0; 193 printlf(1, curfile->fname); 194 while (fgets(buf, sizeof buf, curfile->fin) != NULL) { 195 curfile->lineno++; 196 if (*buf == '.' && *(buf+1) == 'P' && *(buf+2) == 'S') { 197 for (p = &buf[3]; *p == ' '; p++) 198 ; 199 if (*p++ == '<') { 200 Infile svfile; 201 svfile = *curfile; 202 sscanf(p, "%s", buf1); 203 if ((curfile->fin=fopen(buf1, "r")) == NULL) 204 ERROR "can't open %s", buf1 FATAL; 205 curfile->fname = tostring(buf1); 206 getdata(); 207 fclose(curfile->fin); 208 free(curfile->fname); 209 *curfile = svfile; 210 printlf(curfile->lineno, curfile->fname); 211 continue; 212 } 213 reset(); 214 yyparse(); 215 anyerr += synerr; 216 /* yylval.i now contains 'E' or 'F' from .PE or .PF */ 217 218 deltx = (xmax - xmin) / getfval("scale"); 219 delty = (ymax - ymin) / getfval("scale"); 220 if (buf[3] == ' ') { /* next things are wid & ht */ 221 if (sscanf(&buf[4],"%lf %lf", &deltx, &delty) < 2) 222 delty = deltx * (ymax-ymin) / (xmax-xmin); 223 /* else { 224 /* double xfac, yfac; */ 225 /* xfac = deltx / (xmax-xmin); 226 /* yfac = delty / (ymax-ymin); 227 /* if (xfac <= yfac) 228 /* delty = xfac * (ymax-ymin); 229 /* else 230 /* deltx = yfac * (xmax-xmin); 231 /*} 232 */ 233 } 234 dprintf("deltx = %g, delty = %g\n", deltx, delty); 235 if (codegen && !synerr) { 236 openpl(&buf[3]); /* puts out .PS, with ht & wid stuck in */ 237 printlf(curfile->lineno+1, NULL); 238 print(); /* assumes \n at end */ 239 closepl(yylval.i); /* does the .PE/F */ 240 } 241 printlf(curfile->lineno+1, NULL); 242 fflush(stdout); 243 } else if (buf[0] == '.' && buf[1] == 'l' && buf[2] == 'f') { 244 if (sscanf(buf+3, "%d %s", &ln, buf1) == 2) { 245 free(curfile->fname); 246 printlf(curfile->lineno = ln, curfile->fname = tostring(buf1)); 247 } else 248 printlf(curfile->lineno = ln, NULL); 249 } else 250 fputs(buf, stdout); 251 } 252 } 253 254 void reset(void) 255 { 256 obj *op; 257 int i; 258 extern int nstack; 259 extern void freesymtab(struct symtab *); 260 261 for (i = 0; i < nobj; i++) { 262 op = objlist[i]; 263 if (op->o_type == BLOCK) 264 freesymtab(op->o_symtab); 265 free((char *)objlist[i]); 266 } 267 nobj = 0; 268 nattr = 0; 269 for (i = 0; i < ntext; i++) 270 if (text[i].t_val) 271 free(text[i].t_val); 272 ntext = ntext1 = 0; 273 codegen = synerr = 0; 274 nstack = 0; 275 curx = cury = 0; 276 PEseen = 0; 277 hvmode = R_DIR; 278 xmin = ymin = 30000; 279 xmax = ymax = -30000; 280 } 281