plan9port

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

main.c (6509B)


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