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