plan9port

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

lex.c (5098B)


      1 #include "e.h"
      2 #include "y.tab.h"
      3 #include <ctype.h>
      4 #include <errno.h>
      5 
      6 #define	SSIZE	1000
      7 char	token[SSIZE];
      8 int	sp;
      9 
     10 void	space(void);
     11 void	dodef(tbl *);
     12 void	define(int);
     13 void	ifdef(void);
     14 void	include(void);
     15 void	delim(void);
     16 
     17 int
     18 yylex(void)
     19 {
     20 	register int c;
     21 	tbl *tp;
     22 
     23 begin:
     24 	while ((c = input()) == ' ' || c == '\n' || c == '\t')
     25 		;
     26 	yylval = c;
     27 	switch (c) {
     28 	case EOF:
     29 		ERROR "unexpected end of input inside equation" WARNING;
     30 		return(EOF);
     31 	case '~':
     32 		return(SPACE);
     33 	case '^':
     34 		return(THIN);
     35 	/* case '\t':
     36 		return(TAB);
     37 	*/
     38 	case '{':
     39 		return('{');
     40 	case '}':
     41 		return('}');
     42 	case '"':
     43 		for (sp = 0; (c=input())!='"' && c != '\n'; ) {
     44 			if (c == '\\')
     45 				if ((c = input()) != '"')
     46 					token[sp++] = '\\';
     47 			token[sp++] = c;
     48 			if (sp >= SSIZE)
     49 				ERROR "quoted string %.20s... too long", token FATAL;
     50 		}
     51 		token[sp] = '\0';
     52 		yylval = (intptr_t)&token[0];
     53 		if (c == '\n')
     54 			ERROR "missing \" in %.20s", token WARNING;
     55 		return(QTEXT);
     56 	}
     57 	if (!display && c == righteq)
     58 		return(EOF);
     59 
     60 	unput(c);
     61 	getstr(token, SSIZE);
     62 	dprintf(".\tlex token = |%s|\n", token);
     63 	if ((tp = lookup(deftbl, token)) != NULL) {	/* defined term */
     64 		c = input();
     65 		unput(c);
     66 		if (c == '(')	/* macro with args */
     67 			dodef(tp);
     68 		else {		/* no args */
     69 			unput(' ');
     70 			pbstr(tp->cval);
     71 			dprintf(".\tfound %s|=%s|\n", token, tp->cval);
     72 		}
     73 		goto begin;
     74 	}
     75 
     76 	if ((tp = lookup(keytbl, token)) == NULL)	/* not a keyword */
     77 		return CONTIG;
     78 
     79 	switch (tp->ival) {		/* some kind of keyword */
     80 	case DEFINE: case TDEFINE: case NDEFINE:
     81 		define(tp->ival);
     82 		break;
     83 	case IFDEF:
     84 		ifdef();
     85 		break;
     86 	case DELIM:
     87 		delim();
     88 		break;
     89 	case GSIZE:
     90 		globsize();
     91 		break;
     92 	case GFONT:
     93 		globfont();
     94 		break;
     95 	case INCLUDE:
     96 		include();
     97 		break;
     98 	case SPACE:
     99 		space();
    100 		break;
    101 	case DOTEQ:
    102 			/* .EQ inside equation -- should warn if at bottom level */
    103 		break;
    104 	case DOTEN:
    105 		if (curfile == infile)
    106 			return EOF;
    107 		/* else ignore nested .EN */
    108 		break;
    109 	default:
    110 		return tp->ival;
    111 	}
    112 	goto begin;
    113 }
    114 
    115 void getstr(char *s, int n)
    116 {
    117 	register int c;
    118 	register char *p;
    119 
    120 	p = s;
    121 	while ((c = input()) == ' ' || c == '\n')
    122 		;
    123 	if (c == EOF) {
    124 		*s = 0;
    125 		return;
    126 	}
    127 	while (c != ' ' && c != '\t' && c != '\n' && c != '{' && c != '}'
    128 	    && c != '"' && c != '~' && c != '^') {
    129 		if (!display && c == righteq)
    130 			break;
    131 		if (c == '(' && p > s) {	/* might be defined(...) */
    132 			*p = '\0';
    133 			if (lookup(deftbl, s) != NULL)
    134 				break;
    135 		}
    136 		if (c == '\\')
    137 			if ((c = input()) != '"')
    138 				*p++ = '\\';
    139 		*p++ = c;
    140 		if (--n <= 0)
    141 			ERROR "token %.20s... too long", s FATAL;
    142 		c = input();
    143 	}
    144 	unput(c);
    145 	*p = '\0';
    146 	yylval = (uintptr_t)s;
    147 }
    148 
    149 int
    150 cstr(char *s, int quote, int maxs)
    151 {
    152 	int del, c, i;
    153 
    154 	s[0] = 0;
    155 	while ((del=input()) == ' ' || del == '\t')
    156 		;
    157 	if (quote)
    158 		for (i=0; (c=input()) != del && c != EOF;) {
    159 			s[i++] = c;
    160 			if (i >= maxs)
    161 				return(1);	/* disaster */
    162 		}
    163 	else {
    164 		if (del == '\n')
    165 			return(1);
    166 		s[0] = del;
    167 		for (i=1; (c=input())!=' ' && c!= '\t' && c!='\n' && c!=EOF;) {
    168 			s[i++] = c;
    169 			if (i >= maxs)
    170 				return(1);	/* disaster */
    171 		}
    172 	}
    173 	s[i] = '\0';
    174 	if (c == EOF)
    175 		ERROR "Unexpected end of input at %.20s", s FATAL;
    176 	return(0);
    177 }
    178 
    179 void define(int type)
    180 {
    181 	char *p1, *p2;
    182 	extern int ftune(char *, char *);
    183 
    184 	getstr(token, SSIZE);	/* get name */
    185 	if (type != DEFINE) {
    186 		cstr(token, 1, SSIZE);	/* skip the definition too */
    187 		return;
    188 	}
    189 	p1 = strsave(token);
    190 	if (cstr(token, 1, SSIZE))
    191 		ERROR "Unterminated definition at %.20s", token FATAL;
    192 	if (lookup(ftunetbl, p1) != NULL) {	/* double tuning param */
    193 		dprintf(".\ttune %s %s\n", p1, token);
    194 		ftune(p1, token);
    195 	} else {
    196 		p2 = strsave(token);
    197 		install(deftbl, p1, p2, 0);
    198 		dprintf(".\tname %s defined as %s\n", p1, p2);
    199 	}
    200 }
    201 
    202 void ifdef(void)		/* do body if name is defined */
    203 {
    204 	char name[100], *p;
    205 
    206 	getstr(name, sizeof(name));	/* get name */
    207 	cstr(token, 1, SSIZE);		/* and body */
    208 	if (lookup(deftbl, name) != NULL) {	/* found it */
    209 		p = strsave(token);
    210 		pushsrc(Free, p);
    211 		pushsrc(String, p);
    212 	}
    213 }
    214 
    215 char	*spaceval	= NULL;
    216 
    217 void space(void)	/* collect line of form "space amt" to replace \x in output */
    218 {
    219 	getstr(token, SSIZE);
    220 	spaceval = strsave(token);
    221 	dprintf(".\tsetting spaceval to %s\n", token);
    222 }
    223 
    224 char *strsave(char *s)
    225 {
    226 	register char *q;
    227 
    228 	q = malloc(strlen(s)+1);
    229 	if (q == NULL)
    230 		ERROR "out of space in strsave on %s", s FATAL;
    231 	strcpy(q, s);
    232 	return(q);
    233 }
    234 
    235 void include(void)
    236 {
    237 	char name[100];
    238 	FILE *fin;
    239 	int c;
    240 
    241 	while ((c = input()) == ' ')
    242 		;
    243 	unput(c);
    244 	cstr(name, c == '"', sizeof(name));	/* gets it quoted or not */
    245 	if ((fin = fopen(name, "r")) == NULL)
    246 		ERROR "can't open file %s", name FATAL;
    247 	errno = 0;
    248 	curfile++;
    249 	curfile->fin = fin;
    250 	curfile->fname = strsave(name);
    251 	curfile->lineno = 0;
    252 	printf(".lf 1 %s\n", curfile->fname);
    253 	pushsrc(File, curfile->fname);
    254 }
    255 
    256 void delim(void)
    257 {
    258 	yyval = eqnreg = 0;
    259 	if (cstr(token, 0, SSIZE))
    260 		ERROR "Bizarre delimiters" FATAL;
    261 	lefteq = token[0];
    262 	righteq = token[1];
    263 	if (!isprint(lefteq) || !isprint(righteq))
    264 		ERROR "Bizarre delimiters" FATAL;
    265 	if (lefteq == 'o' && righteq == 'f')
    266 		lefteq = righteq = '\0';
    267 }