xref: /titanic_53/usr/src/cmd/eqn/lex.c (revision 779fc935796a940997d18b31d64a9fec9c6b40f6)
1*779fc935Sceastha /*
2*779fc935Sceastha  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
3*779fc935Sceastha  * Use is subject to license terms.
4*779fc935Sceastha  */
5*779fc935Sceastha 
67c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
77c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
87c478bd9Sstevel@tonic-gate 
97c478bd9Sstevel@tonic-gate /*
107c478bd9Sstevel@tonic-gate  * Copyright (c) 1980 Regents of the University of California.
117c478bd9Sstevel@tonic-gate  * All rights reserved. The Berkeley software License Agreement
127c478bd9Sstevel@tonic-gate  * specifies the terms and conditions for redistribution.
137c478bd9Sstevel@tonic-gate  */
147c478bd9Sstevel@tonic-gate 
15*779fc935Sceastha #pragma ident	"%Z%%M%	%I%	%E% SMI"
167c478bd9Sstevel@tonic-gate 
177c478bd9Sstevel@tonic-gate #include "e.h"
187c478bd9Sstevel@tonic-gate #include "e.def"
197c478bd9Sstevel@tonic-gate #include <locale.h>
207c478bd9Sstevel@tonic-gate 
217c478bd9Sstevel@tonic-gate #define	SSIZE	400
227c478bd9Sstevel@tonic-gate char	token[SSIZE];
237c478bd9Sstevel@tonic-gate int	sp;
247c478bd9Sstevel@tonic-gate #define	putbak(c)	*ip++ = c;
257c478bd9Sstevel@tonic-gate #define	PUSHBACK	300	/* maximum pushback characters */
267c478bd9Sstevel@tonic-gate char	ibuf[PUSHBACK+SSIZE];	/* pushback buffer for definitions, etc. */
277c478bd9Sstevel@tonic-gate char	*ip	= ibuf;
287c478bd9Sstevel@tonic-gate 
29*779fc935Sceastha void define(int);
30*779fc935Sceastha void delim(void);
31*779fc935Sceastha void getstr(char *, int);
32*779fc935Sceastha void include(void);
33*779fc935Sceastha int openinfile(void);
34*779fc935Sceastha void pbstr(char *);
35*779fc935Sceastha void space(void);
36*779fc935Sceastha 
37*779fc935Sceastha int
38*779fc935Sceastha gtc(void)
39*779fc935Sceastha {
407c478bd9Sstevel@tonic-gate loop:
417c478bd9Sstevel@tonic-gate 	if (ip > ibuf)
427c478bd9Sstevel@tonic-gate 		return (*--ip);	/* already present */
437c478bd9Sstevel@tonic-gate 	lastchar = getc(curfile);
447c478bd9Sstevel@tonic-gate 	if (lastchar == '\n')
457c478bd9Sstevel@tonic-gate 		linect++;
467c478bd9Sstevel@tonic-gate 	if (lastchar != EOF)
477c478bd9Sstevel@tonic-gate 		return (lastchar);
487c478bd9Sstevel@tonic-gate 	if (++ifile > svargc) {
497c478bd9Sstevel@tonic-gate 		return (EOF);
507c478bd9Sstevel@tonic-gate 	}
51*779fc935Sceastha 	(void) fclose(curfile);
527c478bd9Sstevel@tonic-gate 	linect = 1;
537c478bd9Sstevel@tonic-gate 	if (openinfile() == 0)
547c478bd9Sstevel@tonic-gate 		goto loop;
557c478bd9Sstevel@tonic-gate 	return (EOF);
567c478bd9Sstevel@tonic-gate }
577c478bd9Sstevel@tonic-gate /*
587c478bd9Sstevel@tonic-gate  *	open file indexed by ifile in svargv, return non zero if fail
597c478bd9Sstevel@tonic-gate  */
60*779fc935Sceastha int
61*779fc935Sceastha openinfile(void)
627c478bd9Sstevel@tonic-gate {
637c478bd9Sstevel@tonic-gate 	if (strcmp(svargv[ifile], "-") == 0) {
647c478bd9Sstevel@tonic-gate 		curfile = stdin;
657c478bd9Sstevel@tonic-gate 		return (0);
667c478bd9Sstevel@tonic-gate 	} else if ((curfile = fopen(svargv[ifile], "r")) != NULL) {
677c478bd9Sstevel@tonic-gate 		return (0);
687c478bd9Sstevel@tonic-gate 	}
697c478bd9Sstevel@tonic-gate 	error(FATAL, gettext("can't open file %s"), svargv[ifile]);
707c478bd9Sstevel@tonic-gate 	return (1);
717c478bd9Sstevel@tonic-gate }
727c478bd9Sstevel@tonic-gate 
73*779fc935Sceastha void
74*779fc935Sceastha pbstr(char *str)
757c478bd9Sstevel@tonic-gate {
76*779fc935Sceastha 	char *p;
777c478bd9Sstevel@tonic-gate 
787c478bd9Sstevel@tonic-gate 	p = str;
79*779fc935Sceastha 	while (*p++)
80*779fc935Sceastha 		;
817c478bd9Sstevel@tonic-gate 	--p;
827c478bd9Sstevel@tonic-gate 	if (ip >= &ibuf[PUSHBACK])
837c478bd9Sstevel@tonic-gate 		error(FATAL, gettext("pushback overflow"));
847c478bd9Sstevel@tonic-gate 	while (p > str)
857c478bd9Sstevel@tonic-gate 		putbak(*--p);
867c478bd9Sstevel@tonic-gate }
877c478bd9Sstevel@tonic-gate 
88*779fc935Sceastha int
89*779fc935Sceastha yylex(void)
90*779fc935Sceastha {
91*779fc935Sceastha 	int c;
927c478bd9Sstevel@tonic-gate 	tbl *tp, *lookup();
937c478bd9Sstevel@tonic-gate 	extern tbl **keytbl, **deftbl;
947c478bd9Sstevel@tonic-gate 
957c478bd9Sstevel@tonic-gate beg:
967c478bd9Sstevel@tonic-gate 	while ((c = gtc()) == ' ' || c == '\n')
977c478bd9Sstevel@tonic-gate 		;
987c478bd9Sstevel@tonic-gate 	yylval = c;
997c478bd9Sstevel@tonic-gate 	switch (c) {
1007c478bd9Sstevel@tonic-gate 
1017c478bd9Sstevel@tonic-gate 	case EOF:
1027c478bd9Sstevel@tonic-gate 		return (EOF);
1037c478bd9Sstevel@tonic-gate 	case '~':
1047c478bd9Sstevel@tonic-gate 		return (SPACE);
1057c478bd9Sstevel@tonic-gate 	case '^':
1067c478bd9Sstevel@tonic-gate 		return (THIN);
1077c478bd9Sstevel@tonic-gate 	case '\t':
1087c478bd9Sstevel@tonic-gate 		return (TAB);
1097c478bd9Sstevel@tonic-gate 	case '{':
1107c478bd9Sstevel@tonic-gate 		return ('{');
1117c478bd9Sstevel@tonic-gate 	case '}':
1127c478bd9Sstevel@tonic-gate 		return ('}');
1137c478bd9Sstevel@tonic-gate 	case '"':
1147c478bd9Sstevel@tonic-gate 		for (sp = 0; (c = gtc()) != '"' && c != '\n'; ) {
1157c478bd9Sstevel@tonic-gate 			if (c == '\\')
1167c478bd9Sstevel@tonic-gate 				if ((c = gtc()) != '"')
1177c478bd9Sstevel@tonic-gate 					token[sp++] = '\\';
1187c478bd9Sstevel@tonic-gate 			token[sp++] = c;
1197c478bd9Sstevel@tonic-gate 			if (sp >= SSIZE)
120*779fc935Sceastha 				error(FATAL, gettext(
121*779fc935Sceastha 				    "quoted string %.20s... too long"), token);
1227c478bd9Sstevel@tonic-gate 		}
1237c478bd9Sstevel@tonic-gate 		token[sp] = '\0';
1247c478bd9Sstevel@tonic-gate 		yylval = (int)&token[0];
1257c478bd9Sstevel@tonic-gate 		if (c == '\n')
1267c478bd9Sstevel@tonic-gate 			error(!FATAL, gettext("missing \" in %.20s"), token);
1277c478bd9Sstevel@tonic-gate 		return (QTEXT);
1287c478bd9Sstevel@tonic-gate 	}
1297c478bd9Sstevel@tonic-gate 	if (c == righteq)
1307c478bd9Sstevel@tonic-gate 		return (EOF);
1317c478bd9Sstevel@tonic-gate 
1327c478bd9Sstevel@tonic-gate 	putbak(c);
1337c478bd9Sstevel@tonic-gate 	getstr(token, SSIZE);
1347c478bd9Sstevel@tonic-gate 	if (dbg) printf(".\tlex token = |%s|\n", token);
135*779fc935Sceastha 	if ((tp = lookup(deftbl, token, NULL)) != NULL) {
1367c478bd9Sstevel@tonic-gate 		putbak(' ');
1377c478bd9Sstevel@tonic-gate 		pbstr(tp->defn);
1387c478bd9Sstevel@tonic-gate 		putbak(' ');
1397c478bd9Sstevel@tonic-gate 		if (dbg)
1407c478bd9Sstevel@tonic-gate 			printf(".\tfound %s|=%s|\n", token, tp->defn);
141*779fc935Sceastha 	} else if ((tp = lookup(keytbl, token, NULL)) == NULL) {
1427c478bd9Sstevel@tonic-gate 		if (dbg) printf(".\t%s is not a keyword\n", token);
1437c478bd9Sstevel@tonic-gate 		return (CONTIG);
144*779fc935Sceastha 	} else if (tp->defn == (char *)DEFINE ||
145*779fc935Sceastha 	    tp->defn == (char *)NDEFINE || tp->defn == (char *)TDEFINE)
146*779fc935Sceastha 		define((int)tp->defn);
1477c478bd9Sstevel@tonic-gate 	else if (tp->defn == (char *)DELIM)
1487c478bd9Sstevel@tonic-gate 		delim();
1497c478bd9Sstevel@tonic-gate 	else if (tp->defn == (char *)GSIZE)
1507c478bd9Sstevel@tonic-gate 		globsize();
1517c478bd9Sstevel@tonic-gate 	else if (tp->defn == (char *)GFONT)
1527c478bd9Sstevel@tonic-gate 		globfont();
1537c478bd9Sstevel@tonic-gate 	else if (tp->defn == (char *)INCLUDE)
1547c478bd9Sstevel@tonic-gate 		include();
1557c478bd9Sstevel@tonic-gate 	else if (tp->defn == (char *)SPACE)
1567c478bd9Sstevel@tonic-gate 		space();
1577c478bd9Sstevel@tonic-gate 	else {
1587c478bd9Sstevel@tonic-gate 		return ((int)tp->defn);
1597c478bd9Sstevel@tonic-gate 	}
1607c478bd9Sstevel@tonic-gate 	goto beg;
1617c478bd9Sstevel@tonic-gate }
1627c478bd9Sstevel@tonic-gate 
163*779fc935Sceastha void
164*779fc935Sceastha getstr(char *s, int n)
165*779fc935Sceastha {
166*779fc935Sceastha 	int c;
167*779fc935Sceastha 	char *p;
1687c478bd9Sstevel@tonic-gate 
1697c478bd9Sstevel@tonic-gate 	p = s;
1707c478bd9Sstevel@tonic-gate 	while ((c = gtc()) == ' ' || c == '\n')
1717c478bd9Sstevel@tonic-gate 		;
1727c478bd9Sstevel@tonic-gate 	if (c == EOF) {
1737c478bd9Sstevel@tonic-gate 		*s = 0;
1747c478bd9Sstevel@tonic-gate 		return;
1757c478bd9Sstevel@tonic-gate 	}
176*779fc935Sceastha 	while (c != ' ' && c != '\t' && c != '\n' && c != '{' && c != '}' &&
177*779fc935Sceastha 	    c != '"' && c != '~' && c != '^' && c != righteq) {
1787c478bd9Sstevel@tonic-gate 		if (c == '\\')
1797c478bd9Sstevel@tonic-gate 			if ((c = gtc()) != '"')
1807c478bd9Sstevel@tonic-gate 				*p++ = '\\';
1817c478bd9Sstevel@tonic-gate 		*p++ = c;
1827c478bd9Sstevel@tonic-gate 		if (--n <= 0)
1837c478bd9Sstevel@tonic-gate 			error(FATAL, gettext("token %.20s... too long"), s);
1847c478bd9Sstevel@tonic-gate 		c = gtc();
1857c478bd9Sstevel@tonic-gate 	}
186*779fc935Sceastha 	if (c == '{' || c == '}' || c == '"' || c == '~' || c == '^' ||
187*779fc935Sceastha 	    c == '\t' || c == righteq)
1887c478bd9Sstevel@tonic-gate 		putbak(c);
1897c478bd9Sstevel@tonic-gate 	*p = '\0';
1907c478bd9Sstevel@tonic-gate 	yylval = (int)s;
1917c478bd9Sstevel@tonic-gate }
1927c478bd9Sstevel@tonic-gate 
193*779fc935Sceastha int
194*779fc935Sceastha cstr(char *s, int quote, int maxs)
195*779fc935Sceastha {
1967c478bd9Sstevel@tonic-gate 	int del, c, i;
1977c478bd9Sstevel@tonic-gate 
1987c478bd9Sstevel@tonic-gate 	s[0] = 0;
199*779fc935Sceastha 	while ((del = gtc()) == ' ' || del == '\t')
200*779fc935Sceastha 		;
201*779fc935Sceastha 	if (quote) {
2027c478bd9Sstevel@tonic-gate 		for (i = 0; (c = gtc()) != del && c != EOF; ) {
2037c478bd9Sstevel@tonic-gate 			s[i++] = c;
2047c478bd9Sstevel@tonic-gate 			if (i >= maxs)
2057c478bd9Sstevel@tonic-gate 				return (1);	/* disaster */
2067c478bd9Sstevel@tonic-gate 		}
207*779fc935Sceastha 	} else {
2087c478bd9Sstevel@tonic-gate 		if (del == '\n')
2097c478bd9Sstevel@tonic-gate 			return (1);
2107c478bd9Sstevel@tonic-gate 		s[0] = del;
211*779fc935Sceastha 		for (i = 1; (c = gtc()) != ' ' && c != '\t' &&
212*779fc935Sceastha 		    c != '\n' && c != EOF; /* empty */) {
2137c478bd9Sstevel@tonic-gate 			s[i++] = c;
2147c478bd9Sstevel@tonic-gate 			if (i >= maxs)
2157c478bd9Sstevel@tonic-gate 				return (1);	/* disaster */
2167c478bd9Sstevel@tonic-gate 		}
2177c478bd9Sstevel@tonic-gate 	}
2187c478bd9Sstevel@tonic-gate 	s[i] = '\0';
2197c478bd9Sstevel@tonic-gate 	if (c == EOF)
2207c478bd9Sstevel@tonic-gate 		error(FATAL, gettext("Unexpected end of input at %.20s"), s);
2217c478bd9Sstevel@tonic-gate 	return (0);
2227c478bd9Sstevel@tonic-gate }
2237c478bd9Sstevel@tonic-gate 
224*779fc935Sceastha void
225*779fc935Sceastha define(int type)
226*779fc935Sceastha {
2277c478bd9Sstevel@tonic-gate 	char *strsave(), *p1, *p2;
2287c478bd9Sstevel@tonic-gate 	tbl *lookup();
2297c478bd9Sstevel@tonic-gate 	extern tbl **deftbl;
2307c478bd9Sstevel@tonic-gate 
2317c478bd9Sstevel@tonic-gate 	getstr(token, SSIZE);	/* get name */
2327c478bd9Sstevel@tonic-gate 	if (type != DEFINE) {
233*779fc935Sceastha 		(void) cstr(token, 1, SSIZE);	/* skip the definition too */
2347c478bd9Sstevel@tonic-gate 		return;
2357c478bd9Sstevel@tonic-gate 	}
2367c478bd9Sstevel@tonic-gate 	p1 = strsave(token);
2377c478bd9Sstevel@tonic-gate 	if (cstr(token, 1, SSIZE))
238*779fc935Sceastha 		error(FATAL, gettext(
239*779fc935Sceastha 		    "Unterminated definition at %.20s"), token);
2407c478bd9Sstevel@tonic-gate 	p2 = strsave(token);
241*779fc935Sceastha 	lookup(deftbl, p1, p2);
2427c478bd9Sstevel@tonic-gate 	if (dbg) printf(".\tname %s defined as %s\n", p1, p2);
2437c478bd9Sstevel@tonic-gate }
2447c478bd9Sstevel@tonic-gate 
2457c478bd9Sstevel@tonic-gate char    *spaceval   = NULL;
2467c478bd9Sstevel@tonic-gate 
247*779fc935Sceastha void
248*779fc935Sceastha space(void) /* collect line of form "space amt" to replace \x in output */
2497c478bd9Sstevel@tonic-gate {
2507c478bd9Sstevel@tonic-gate 	char *strsave();
2517c478bd9Sstevel@tonic-gate 
2527c478bd9Sstevel@tonic-gate 	getstr(token, SSIZE);
2537c478bd9Sstevel@tonic-gate 	spaceval = strsave(token);
2547c478bd9Sstevel@tonic-gate 	if (dbg) printf(".\tsetting space to %s\n", token);
2557c478bd9Sstevel@tonic-gate }
2567c478bd9Sstevel@tonic-gate 
2577c478bd9Sstevel@tonic-gate 
258*779fc935Sceastha char *
259*779fc935Sceastha strsave(char *s)
2607c478bd9Sstevel@tonic-gate {
2617c478bd9Sstevel@tonic-gate 	char *malloc();
262*779fc935Sceastha 	char *q;
2637c478bd9Sstevel@tonic-gate 
2647c478bd9Sstevel@tonic-gate 	q = malloc(strlen(s)+1);
2657c478bd9Sstevel@tonic-gate 	if (q == NULL)
2667c478bd9Sstevel@tonic-gate 		error(FATAL, gettext("out of space in strsave on %s"), s);
2677c478bd9Sstevel@tonic-gate 	strcpy(q, s);
2687c478bd9Sstevel@tonic-gate 	return (q);
2697c478bd9Sstevel@tonic-gate }
2707c478bd9Sstevel@tonic-gate 
271*779fc935Sceastha void
272*779fc935Sceastha include(void)
273*779fc935Sceastha {
2747c478bd9Sstevel@tonic-gate 	error(!FATAL, gettext("Include not yet implemented"));
2757c478bd9Sstevel@tonic-gate }
2767c478bd9Sstevel@tonic-gate 
277*779fc935Sceastha void
278*779fc935Sceastha delim(void)
279*779fc935Sceastha {
2807c478bd9Sstevel@tonic-gate 	yyval = eqnreg = 0;
2817c478bd9Sstevel@tonic-gate 	if (cstr(token, 0, SSIZE))
2827c478bd9Sstevel@tonic-gate 		error(FATAL, gettext("Bizarre delimiters at %.20s"), token);
2837c478bd9Sstevel@tonic-gate 	lefteq = token[0];
2847c478bd9Sstevel@tonic-gate 	righteq = token[1];
2857c478bd9Sstevel@tonic-gate 	if (lefteq == 'o' && righteq == 'f')
2867c478bd9Sstevel@tonic-gate 		lefteq = righteq = '\0';
2877c478bd9Sstevel@tonic-gate }
288