xref: /plan9/sys/src/cmd/grap/print.c (revision eba00c1180f26027fec6be9f76c54eccfce0d97b)
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 
print(void)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 
endstat(void)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 
graph(char * s)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 
setup(void)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 
do_first(void)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 
reset(void)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 
opentemp(void)224 void opentemp(void)
225 {
226 	if (tfd != stdout) {
227 		if (tfd != NULL)
228 			fclose(tfd);
229 		if ((tfd = fopen(tempfile, "w")) == NULL) {
230 			fprintf(stderr, "grap: can't open %s\n", tempfile);
231 			exit(1);
232 		}
233   	}
234 }
235