xref: /onnv-gate/usr/src/cmd/eqn/lex.c (revision 413:1d1413a1c800)
1364Sceastha /*
2364Sceastha  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
3364Sceastha  * Use is subject to license terms.
4364Sceastha  */
5364Sceastha 
60Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
70Sstevel@tonic-gate /*	  All Rights Reserved  	*/
80Sstevel@tonic-gate 
90Sstevel@tonic-gate /*
100Sstevel@tonic-gate  * Copyright (c) 1980 Regents of the University of California.
110Sstevel@tonic-gate  * All rights reserved. The Berkeley software License Agreement
120Sstevel@tonic-gate  * specifies the terms and conditions for redistribution.
130Sstevel@tonic-gate  */
14364Sceastha 
15364Sceastha #pragma ident	"%Z%%M%	%I%	%E% SMI"
160Sstevel@tonic-gate 
170Sstevel@tonic-gate #include "e.h"
180Sstevel@tonic-gate #include "e.def"
190Sstevel@tonic-gate #include <locale.h>
200Sstevel@tonic-gate 
210Sstevel@tonic-gate #define	SSIZE	400
220Sstevel@tonic-gate char	token[SSIZE];
230Sstevel@tonic-gate int	sp;
240Sstevel@tonic-gate #define	putbak(c)	*ip++ = c;
250Sstevel@tonic-gate #define	PUSHBACK	300	/* maximum pushback characters */
260Sstevel@tonic-gate char	ibuf[PUSHBACK+SSIZE];	/* pushback buffer for definitions, etc. */
270Sstevel@tonic-gate char	*ip	= ibuf;
280Sstevel@tonic-gate 
29*413Sceastha extern tbl *keytbl[];
30*413Sceastha extern tbl *deftbl[];
31*413Sceastha 
32364Sceastha void define(int);
33364Sceastha void delim(void);
34364Sceastha void getstr(char *, int);
35364Sceastha void include(void);
36364Sceastha int openinfile(void);
37364Sceastha void pbstr(char *);
38364Sceastha void space(void);
39364Sceastha 
40364Sceastha int
gtc(void)41364Sceastha gtc(void)
42364Sceastha {
43364Sceastha loop:
440Sstevel@tonic-gate 	if (ip > ibuf)
45364Sceastha 		return (*--ip);	/* already present */
460Sstevel@tonic-gate 	lastchar = getc(curfile);
47364Sceastha 	if (lastchar == '\n')
480Sstevel@tonic-gate 		linect++;
490Sstevel@tonic-gate 	if (lastchar != EOF)
50364Sceastha 		return (lastchar);
510Sstevel@tonic-gate 	if (++ifile > svargc) {
52364Sceastha 		return (EOF);
530Sstevel@tonic-gate 	}
54364Sceastha 	(void) fclose(curfile);
550Sstevel@tonic-gate 	linect = 1;
560Sstevel@tonic-gate 	if (openinfile() == 0)
570Sstevel@tonic-gate 		goto loop;
58364Sceastha 	return (EOF);
590Sstevel@tonic-gate }
600Sstevel@tonic-gate /*
610Sstevel@tonic-gate  *	open file indexed by ifile in svargv, return non zero if fail
620Sstevel@tonic-gate  */
63364Sceastha int
openinfile(void)64364Sceastha openinfile(void)
650Sstevel@tonic-gate {
66364Sceastha 	if (strcmp(svargv[ifile], "-") == 0) {
670Sstevel@tonic-gate 		curfile = stdin;
68364Sceastha 		return (0);
69364Sceastha 	} else if ((curfile = fopen(svargv[ifile], "r")) != NULL) {
70364Sceastha 		return (0);
710Sstevel@tonic-gate 	}
720Sstevel@tonic-gate 	error(FATAL, gettext("can't open file %s"), svargv[ifile]);
73364Sceastha 	return (1);
740Sstevel@tonic-gate }
750Sstevel@tonic-gate 
76364Sceastha void
pbstr(char * str)77364Sceastha pbstr(char *str)
780Sstevel@tonic-gate {
79364Sceastha 	char *p;
800Sstevel@tonic-gate 
810Sstevel@tonic-gate 	p = str;
82364Sceastha 	while (*p++)
83364Sceastha 		;
840Sstevel@tonic-gate 	--p;
850Sstevel@tonic-gate 	if (ip >= &ibuf[PUSHBACK])
86364Sceastha 		error(FATAL, gettext("pushback overflow"));
870Sstevel@tonic-gate 	while (p > str)
880Sstevel@tonic-gate 		putbak(*--p);
890Sstevel@tonic-gate }
900Sstevel@tonic-gate 
91364Sceastha int
yylex(void)92364Sceastha yylex(void)
93364Sceastha {
94364Sceastha 	int c;
950Sstevel@tonic-gate 	tbl *tp, *lookup();
960Sstevel@tonic-gate 
97364Sceastha beg:
98364Sceastha 	while ((c = gtc()) == ' ' || c == '\n')
990Sstevel@tonic-gate 		;
100364Sceastha 	yylval = c;
101364Sceastha 	switch (c) {
1020Sstevel@tonic-gate 
1030Sstevel@tonic-gate 	case EOF:
104364Sceastha 		return (EOF);
1050Sstevel@tonic-gate 	case '~':
106364Sceastha 		return (SPACE);
1070Sstevel@tonic-gate 	case '^':
108364Sceastha 		return (THIN);
1090Sstevel@tonic-gate 	case '\t':
110364Sceastha 		return (TAB);
1110Sstevel@tonic-gate 	case '{':
112364Sceastha 		return ('{');
1130Sstevel@tonic-gate 	case '}':
114364Sceastha 		return ('}');
1150Sstevel@tonic-gate 	case '"':
116364Sceastha 		for (sp = 0; (c = gtc()) != '"' && c != '\n'; ) {
1170Sstevel@tonic-gate 			if (c == '\\')
1180Sstevel@tonic-gate 				if ((c = gtc()) != '"')
1190Sstevel@tonic-gate 					token[sp++] = '\\';
1200Sstevel@tonic-gate 			token[sp++] = c;
121364Sceastha 			if (sp >= SSIZE)
122364Sceastha 				error(FATAL, gettext(
123364Sceastha 				    "quoted string %.20s... too long"), token);
1240Sstevel@tonic-gate 		}
125364Sceastha 		token[sp] = '\0';
126364Sceastha 		yylval = (int)&token[0];
1270Sstevel@tonic-gate 		if (c == '\n')
1280Sstevel@tonic-gate 			error(!FATAL, gettext("missing \" in %.20s"), token);
129364Sceastha 		return (QTEXT);
1300Sstevel@tonic-gate 	}
131364Sceastha 	if (c == righteq)
132364Sceastha 		return (EOF);
1330Sstevel@tonic-gate 
1340Sstevel@tonic-gate 	putbak(c);
1350Sstevel@tonic-gate 	getstr(token, SSIZE);
136364Sceastha 	if (dbg) printf(".\tlex token = |%s|\n", token);
137364Sceastha 	if ((tp = lookup(deftbl, token, NULL)) != NULL) {
1380Sstevel@tonic-gate 		putbak(' ');
1390Sstevel@tonic-gate 		pbstr(tp->defn);
1400Sstevel@tonic-gate 		putbak(' ');
1410Sstevel@tonic-gate 		if (dbg)
1420Sstevel@tonic-gate 			printf(".\tfound %s|=%s|\n", token, tp->defn);
143364Sceastha 	} else if ((tp = lookup(keytbl, token, NULL)) == NULL) {
144364Sceastha 		if (dbg) printf(".\t%s is not a keyword\n", token);
145364Sceastha 		return (CONTIG);
146364Sceastha 	} else if (tp->defn == (char *)DEFINE ||
147364Sceastha 	    tp->defn == (char *)NDEFINE || tp->defn == (char *)TDEFINE)
148364Sceastha 		define((int)tp->defn);
149364Sceastha 	else if (tp->defn == (char *)DELIM)
1500Sstevel@tonic-gate 		delim();
151364Sceastha 	else if (tp->defn == (char *)GSIZE)
1520Sstevel@tonic-gate 		globsize();
153364Sceastha 	else if (tp->defn == (char *)GFONT)
1540Sstevel@tonic-gate 		globfont();
155364Sceastha 	else if (tp->defn == (char *)INCLUDE)
1560Sstevel@tonic-gate 		include();
157364Sceastha 	else if (tp->defn == (char *)SPACE)
1580Sstevel@tonic-gate 		space();
1590Sstevel@tonic-gate 	else {
160364Sceastha 		return ((int)tp->defn);
1610Sstevel@tonic-gate 	}
1620Sstevel@tonic-gate 	goto beg;
1630Sstevel@tonic-gate }
1640Sstevel@tonic-gate 
165364Sceastha void
getstr(char * s,int n)166364Sceastha getstr(char *s, int n)
167364Sceastha {
168364Sceastha 	int c;
169364Sceastha 	char *p;
1700Sstevel@tonic-gate 
1710Sstevel@tonic-gate 	p = s;
1720Sstevel@tonic-gate 	while ((c = gtc()) == ' ' || c == '\n')
1730Sstevel@tonic-gate 		;
1740Sstevel@tonic-gate 	if (c == EOF) {
1750Sstevel@tonic-gate 		*s = 0;
1760Sstevel@tonic-gate 		return;
1770Sstevel@tonic-gate 	}
178364Sceastha 	while (c != ' ' && c != '\t' && c != '\n' && c != '{' && c != '}' &&
179364Sceastha 	    c != '"' && c != '~' && c != '^' && c != righteq) {
1800Sstevel@tonic-gate 		if (c == '\\')
1810Sstevel@tonic-gate 			if ((c = gtc()) != '"')
1820Sstevel@tonic-gate 				*p++ = '\\';
1830Sstevel@tonic-gate 		*p++ = c;
1840Sstevel@tonic-gate 		if (--n <= 0)
1850Sstevel@tonic-gate 			error(FATAL, gettext("token %.20s... too long"), s);
1860Sstevel@tonic-gate 		c = gtc();
1870Sstevel@tonic-gate 	}
188364Sceastha 	if (c == '{' || c == '}' || c == '"' || c == '~' || c == '^' ||
189364Sceastha 	    c == '\t' || c == righteq)
1900Sstevel@tonic-gate 		putbak(c);
1910Sstevel@tonic-gate 	*p = '\0';
192364Sceastha 	yylval = (int)s;
1930Sstevel@tonic-gate }
1940Sstevel@tonic-gate 
195364Sceastha int
cstr(char * s,int quote,int maxs)196364Sceastha cstr(char *s, int quote, int maxs)
197364Sceastha {
1980Sstevel@tonic-gate 	int del, c, i;
1990Sstevel@tonic-gate 
2000Sstevel@tonic-gate 	s[0] = 0;
201364Sceastha 	while ((del = gtc()) == ' ' || del == '\t')
202364Sceastha 		;
203364Sceastha 	if (quote) {
204364Sceastha 		for (i = 0; (c = gtc()) != del && c != EOF; ) {
2050Sstevel@tonic-gate 			s[i++] = c;
2060Sstevel@tonic-gate 			if (i >= maxs)
207364Sceastha 				return (1);	/* disaster */
2080Sstevel@tonic-gate 		}
209364Sceastha 	} else {
2100Sstevel@tonic-gate 		if (del == '\n')
2110Sstevel@tonic-gate 			return (1);
2120Sstevel@tonic-gate 		s[0] = del;
213364Sceastha 		for (i = 1; (c = gtc()) != ' ' && c != '\t' &&
214364Sceastha 		    c != '\n' && c != EOF; /* empty */) {
215364Sceastha 			s[i++] = c;
2160Sstevel@tonic-gate 			if (i >= maxs)
217364Sceastha 				return (1);	/* disaster */
2180Sstevel@tonic-gate 		}
2190Sstevel@tonic-gate 	}
2200Sstevel@tonic-gate 	s[i] = '\0';
2210Sstevel@tonic-gate 	if (c == EOF)
2220Sstevel@tonic-gate 		error(FATAL, gettext("Unexpected end of input at %.20s"), s);
223364Sceastha 	return (0);
2240Sstevel@tonic-gate }
2250Sstevel@tonic-gate 
226364Sceastha void
define(int type)227364Sceastha define(int type)
228364Sceastha {
2290Sstevel@tonic-gate 	char *strsave(), *p1, *p2;
2300Sstevel@tonic-gate 	tbl *lookup();
2310Sstevel@tonic-gate 
2320Sstevel@tonic-gate 	getstr(token, SSIZE);	/* get name */
2330Sstevel@tonic-gate 	if (type != DEFINE) {
234364Sceastha 		(void) cstr(token, 1, SSIZE);	/* skip the definition too */
2350Sstevel@tonic-gate 		return;
2360Sstevel@tonic-gate 	}
2370Sstevel@tonic-gate 	p1 = strsave(token);
2380Sstevel@tonic-gate 	if (cstr(token, 1, SSIZE))
239364Sceastha 		error(FATAL, gettext(
240364Sceastha 		    "Unterminated definition at %.20s"), token);
2410Sstevel@tonic-gate 	p2 = strsave(token);
242364Sceastha 	lookup(deftbl, p1, p2);
243364Sceastha 	if (dbg) printf(".\tname %s defined as %s\n", p1, p2);
2440Sstevel@tonic-gate }
2450Sstevel@tonic-gate 
2460Sstevel@tonic-gate char    *spaceval   = NULL;
2470Sstevel@tonic-gate 
248364Sceastha void
space(void)249364Sceastha space(void) /* collect line of form "space amt" to replace \x in output */
2500Sstevel@tonic-gate {
2510Sstevel@tonic-gate 	char *strsave();
2520Sstevel@tonic-gate 
2530Sstevel@tonic-gate 	getstr(token, SSIZE);
2540Sstevel@tonic-gate 	spaceval = strsave(token);
2550Sstevel@tonic-gate 	if (dbg) printf(".\tsetting space to %s\n", token);
2560Sstevel@tonic-gate }
2570Sstevel@tonic-gate 
2580Sstevel@tonic-gate 
259364Sceastha char *
strsave(char * s)260364Sceastha strsave(char *s)
2610Sstevel@tonic-gate {
2620Sstevel@tonic-gate 	char *malloc();
263364Sceastha 	char *q;
2640Sstevel@tonic-gate 
2650Sstevel@tonic-gate 	q = malloc(strlen(s)+1);
2660Sstevel@tonic-gate 	if (q == NULL)
2670Sstevel@tonic-gate 		error(FATAL, gettext("out of space in strsave on %s"), s);
2680Sstevel@tonic-gate 	strcpy(q, s);
269364Sceastha 	return (q);
2700Sstevel@tonic-gate }
2710Sstevel@tonic-gate 
272364Sceastha void
include(void)273364Sceastha include(void)
274364Sceastha {
2750Sstevel@tonic-gate 	error(!FATAL, gettext("Include not yet implemented"));
2760Sstevel@tonic-gate }
2770Sstevel@tonic-gate 
278364Sceastha void
delim(void)279364Sceastha delim(void)
280364Sceastha {
2810Sstevel@tonic-gate 	yyval = eqnreg = 0;
2820Sstevel@tonic-gate 	if (cstr(token, 0, SSIZE))
2830Sstevel@tonic-gate 		error(FATAL, gettext("Bizarre delimiters at %.20s"), token);
2840Sstevel@tonic-gate 	lefteq = token[0];
2850Sstevel@tonic-gate 	righteq = token[1];
2860Sstevel@tonic-gate 	if (lefteq == 'o' && righteq == 'f')
2870Sstevel@tonic-gate 		lefteq = righteq = '\0';
2880Sstevel@tonic-gate }
289