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