plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

print.c (5275B)


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