plan9port

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

main.c (6813B)


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