274 lines · 5.4 KB · C
RawDownload
/*  * This file is part of the UCB release of Plan 9. It is subject to the license * terms in the LICENSE file found in the top-level directory of this * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No * part of the UCB release of Plan 9, including this file, may be copied, * modified, propagated, or distributed except according to the terms contained * in the LICENSE file. */ #include "e.h"#include "y.tab.h"#include <ctype.h> #define	SSIZE	1000char	token[SSIZE];int	sp; void	space(void);void	dodef(tbl *);void	define(int);void	ifdef(void);void	include(void);void	delim(void); yylex(void){	register int c;	tbl *tp;   begin:	while ((c = input()) == ' ' || c == '\n' || c == '\t')		;	yylval = c;	switch (c) {	case EOF:		ERROR "unexpected end of input inside equation" WARNING;		return(EOF);	case '~':		return(SPACE);	case '^':		return(THIN);	/* case '\t':		return(TAB);	*/	case '{':		return('{');	case '}':		return('}');	case '"':		for (sp = 0; (c=input())!='"' && c != '\n'; ) {			if (c == '\\')				if ((c = input()) != '"')					token[sp++] = '\\';			token[sp++] = c;			if (sp >= SSIZE)				ERROR "quoted string %.20s... too long", token FATAL;		}		token[sp] = '\0';		yylval = (int) &token[0];		if (c == '\n')			ERROR "missing \" in %.20s", token WARNING;		return(QTEXT);	}	if (!display && c == righteq)		return(EOF); 	unput(c);	getstr(token, SSIZE);	dprintf(".\tlex token = |%s|\n", token);	if ((tp = lookup(deftbl, token)) != NULL) {	/* defined term */		c = input();		unput(c);		if (c == '(')	/* macro with args */			dodef(tp);		else {		/* no args */			unput(' ');			pbstr(tp->cval);			dprintf(".\tfound %s|=%s|\n", token, tp->cval);		}		goto begin;	} 	if ((tp = lookup(keytbl, token)) == NULL)	/* not a keyword */		return CONTIG; 	switch (tp->ival) {		/* some kind of keyword */	case DEFINE: case TDEFINE: case NDEFINE:		define(tp->ival);		break;	case IFDEF:		ifdef();		break;	case DELIM:		delim();		break;	case GSIZE:		globsize();		break;	case GFONT:		globfont();		break;	case INCLUDE:		include();		break;	case SPACE:		space();		break;	case DOTEQ:			/* .EQ inside equation -- should warn if at bottom level */		break;	case DOTEN:		if (curfile == infile)			return EOF;		/* else ignore nested .EN */		break;	default:		return tp->ival;	}	goto begin;} void getstr(char *s, int n){	register int c;	register char *p; 	p = s;	while ((c = input()) == ' ' || c == '\n')		;	if (c == EOF) {		*s = 0;		return;	}	while (c != ' ' && c != '\t' && c != '\n' && c != '{' && c != '}'	    && c != '"' && c != '~' && c != '^') {		if (!display && c == righteq)			break;		if (c == '(' && p > s) {	/* might be defined(...) */			*p = '\0';			if (lookup(deftbl, s) != NULL)				break;		}		if (c == '\\')			if ((c = input()) != '"')				*p++ = '\\';		*p++ = c;		if (--n <= 0)			ERROR "token %.20s... too long", s FATAL;		c = input();	}	unput(c);	*p = '\0';	yylval = (int) s;} cstr(char *s, int quote, int maxs){	int del, c, i; 	s[0] = 0;	while ((del=input()) == ' ' || del == '\t')		;	if (quote)		for (i=0; (c=input()) != del && c != EOF;) {			s[i++] = c;			if (i >= maxs)				return(1);	/* disaster */		}	else {		if (del == '\n')			return(1);		s[0] = del;		for (i=1; (c=input())!=' ' && c!= '\t' && c!='\n' && c!=EOF;) {			s[i++] = c;			if (i >= maxs)				return(1);	/* disaster */		}	}	s[i] = '\0';	if (c == EOF)		ERROR "Unexpected end of input at %.20s", s FATAL;	return(0);} void define(int type){	char *p1, *p2;	extern int ftune(char *, char *); 	getstr(token, SSIZE);	/* get name */	if (type != DEFINE) {		cstr(token, 1, SSIZE);	/* skip the definition too */		return;	}	p1 = strsave(token);	if (cstr(token, 1, SSIZE))		ERROR "Unterminated definition at %.20s", token FATAL;	if (lookup(ftunetbl, p1) != NULL) {	/* double tuning param */		dprintf(".\ttune %s %s\n", p1, token);		ftune(p1, token);	} else {		p2 = strsave(token);		install(deftbl, p1, p2, 0);		dprintf(".\tname %s defined as %s\n", p1, p2);	}} void ifdef(void)		/* do body if name is defined */{	char name[100], *p; 	getstr(name, sizeof(name));	/* get name */	cstr(token, 1, SSIZE);		/* and body */	if (lookup(deftbl, name) != NULL) {	/* found it */		p = strsave(token);		pushsrc(Free, p);		pushsrc(String, p);	}} char	*spaceval	= NULL; void space(void)	/* collect line of form "space amt" to replace \x in output */{	getstr(token, SSIZE);	spaceval = strsave(token);	dprintf(".\tsetting spaceval to %s\n", token);} char *strsave(char *s){	register char *q; 	q = malloc(strlen(s)+1);	if (q == NULL)		ERROR "out of space in strsave on %s", s FATAL;	strcpy(q, s);	return(q);} void include(void){	char name[100];	FILE *fin;	int c;	extern int errno; 	while ((c = input()) == ' ')		;	unput(c);	cstr(name, c == '"', sizeof(name));	/* gets it quoted or not */	if ((fin = fopen(name, "r")) == NULL)		ERROR "can't open file %s", name FATAL;	errno = 0;	curfile++;	curfile->fin = fin;	curfile->fname = strsave(name);	curfile->lineno = 0;	printf(".lf 1 %s\n", curfile->fname);	pushsrc(File, curfile->fname);} void delim(void){	yyval = eqnreg = 0;	if (cstr(token, 0, SSIZE))		ERROR "Bizarre delimiters" FATAL;	lefteq = token[0];	righteq = token[1];        if (!isprint(lefteq) || !isprint(righteq))		ERROR "Bizarre delimiters" FATAL;	if (lefteq == 'o' && righteq == 'f')		lefteq = righteq = '\0';}