Blob


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"
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;
14 char graphname[50] = "Graph";
15 char graphpos[200] = "";
17 void print(void) /* arrange final output */
18 {
19 FILE *fd;
20 Obj *p, *dfp;
21 int c;
22 double dx, dy, xfac, yfac;
24 if (tfd != NULL) {
25 fclose(tfd); /* end the temp file */
26 tfd = stdout;
27 }
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;
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);
105 if (codegen)
106 frame();
107 if (codegen && autoticks && dfp)
108 do_autoticks(dfp);
110 if ((fd = fopen(tempfile, "r")) != NULL) {
111 while ((c = getc(fd)) != EOF)
112 putc(c, tfd);
113 fclose(fd);
115 tfd = NULL;
118 void endstat(void) /* clean up after each statement */
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;
131 void graph(char *s) /* graph statement */
133 char *p, *os;
134 int c;
136 if (codegen) {
137 fprintf(stdout, "%s: [\n", graphname);
138 print(); /* pump out previous graph */
139 fprintf(stdout, "\n] %s\n", graphpos);
140 reset();
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);
161 void setup(void) /* done at each .G1 */
163 static int firstG1 = 0;
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, "");
176 void do_first(void) /* done at first .G1: definitions, etc. */
178 extern int lib;
179 extern char *lib_defines;
180 static char buf[100], buf1[100]; /* static because pbstr uses them */
181 FILE *fp;
182 extern int getpid(void);
184 snprintf(buf, sizeof buf, "define pid /%d/\n", getpid());
185 pbstr(buf);
186 if (lib != 0) {
187 if ((fp = fopen(lib_defines, "r")) != NULL) {
188 snprintf(buf1, sizeof buf, "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);
197 void reset(void) /* done at each "graph ..." statement */
199 Obj *p, *np, *deflist;
200 extern int tlist, toffside, autodir;
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);
221 objlist = deflist;
224 void opentemp(void)
226 if (tfd != NULL)
227 fclose(tfd);
228 if (tfd != stdout) {
229 if (tfd != NULL)
230 fclose(tfd);
231 if ((tfd = fopen(tempfile, "w")) == NULL) {
232 fprintf(stderr, "grap: can't open %s\n", tempfile);
233 exit(1);