Blob


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