1*48252Sbostic /*-
2*48252Sbostic * Copyright (c) 1991 The Regents of the University of California.
3*48252Sbostic * All rights reserved.
4*48252Sbostic *
5*48252Sbostic * %sccs.include.proprietary.c%
6*48252Sbostic */
7*48252Sbostic
814486Ssam #ifndef lint
9*48252Sbostic static char sccsid[] = "@(#)lex.c 4.4 (Berkeley) 04/17/91";
10*48252Sbostic #endif /* not lint */
1111008Sshannon
1211008Sshannon #include "e.h"
1311008Sshannon #include "e.def"
1411008Sshannon
1511008Sshannon #define SSIZE 400
1611008Sshannon char token[SSIZE];
1711008Sshannon int sp;
1811008Sshannon #define putbak(c) *ip++ = c;
1911008Sshannon #define PUSHBACK 300 /* maximum pushback characters */
2011008Sshannon char ibuf[PUSHBACK+SSIZE]; /* pushback buffer for definitions, etc. */
2111008Sshannon char *ip = ibuf;
2211008Sshannon
gtc()2311008Sshannon gtc() {
2411008Sshannon loop:
2511008Sshannon if (ip > ibuf)
2611008Sshannon return(*--ip); /* already present */
2711008Sshannon lastchar = getc(curfile);
2811008Sshannon if (lastchar=='\n')
2911008Sshannon linect++;
3011008Sshannon if (lastchar != EOF)
3111008Sshannon return(lastchar);
3211008Sshannon if (++ifile > svargc) {
3311008Sshannon return(EOF);
3411008Sshannon }
3511008Sshannon fclose(curfile);
3611008Sshannon linect = 1;
3714899Srrh if (openinfile() == 0)
3811008Sshannon goto loop;
3911008Sshannon return(EOF);
4011008Sshannon }
4114899Srrh /*
4214899Srrh * open file indexed by ifile in svargv, return non zero if fail
4314899Srrh */
openinfile()4414899Srrh openinfile()
4514899Srrh {
4614899Srrh if (strcmp(svargv[ifile], "-") == 0){
4714899Srrh curfile = stdin;
4814899Srrh return(0);
4914899Srrh } else if ((curfile=fopen(svargv[ifile], "r")) != NULL){
5014899Srrh return(0);
5114899Srrh }
5214899Srrh error(FATAL, "can't open file %s", svargv[ifile]);
5314899Srrh return(1);
5414899Srrh }
5511008Sshannon
pbstr(str)5611008Sshannon pbstr(str)
5711008Sshannon register char *str;
5811008Sshannon {
5911008Sshannon register char *p;
6011008Sshannon
6111008Sshannon p = str;
6211008Sshannon while (*p++);
6311008Sshannon --p;
6411008Sshannon if (ip >= &ibuf[PUSHBACK])
6511008Sshannon error( FATAL, "pushback overflow");
6611008Sshannon while (p > str)
6711008Sshannon putbak(*--p);
6811008Sshannon }
6911008Sshannon
yylex()7011008Sshannon yylex() {
7111008Sshannon register int c;
7211008Sshannon tbl *tp, *lookup();
7311008Sshannon extern tbl **keytbl, **deftbl;
7411008Sshannon
7511008Sshannon beg:
7611008Sshannon while ((c=gtc())==' ' || c=='\n')
7711008Sshannon ;
7811008Sshannon yylval=c;
7911008Sshannon switch(c) {
8011008Sshannon
8111008Sshannon case EOF:
8211008Sshannon return(EOF);
8311008Sshannon case '~':
8411008Sshannon return(SPACE);
8511008Sshannon case '^':
8611008Sshannon return(THIN);
8711008Sshannon case '\t':
8811008Sshannon return(TAB);
8911008Sshannon case '{':
9011008Sshannon return('{');
9111008Sshannon case '}':
9211008Sshannon return('}');
9311008Sshannon case '"':
9411008Sshannon for (sp=0; (c=gtc())!='"' && c != '\n'; ) {
9511008Sshannon if (c == '\\')
9611008Sshannon if ((c = gtc()) != '"')
9711008Sshannon token[sp++] = '\\';
9811008Sshannon token[sp++] = c;
9911008Sshannon if (sp>=SSIZE)
10011008Sshannon error(FATAL, "quoted string %.20s... too long", token);
10111008Sshannon }
10211008Sshannon token[sp]='\0';
10311008Sshannon yylval = (int) &token[0];
10411008Sshannon if (c == '\n')
10511008Sshannon error(!FATAL, "missing \" in %.20s", token);
10611008Sshannon return(QTEXT);
10711008Sshannon }
10811008Sshannon if (c==righteq)
10911008Sshannon return(EOF);
11011008Sshannon
11111008Sshannon putbak(c);
11211008Sshannon getstr(token, SSIZE);
11311008Sshannon if (dbg)printf(".\tlex token = |%s|\n", token);
11411008Sshannon if ((tp = lookup(&deftbl, token, NULL)) != NULL) {
11511008Sshannon putbak(' ');
11611008Sshannon pbstr(tp->defn);
11711008Sshannon putbak(' ');
11811008Sshannon if (dbg)
11911008Sshannon printf(".\tfound %s|=%s|\n", token, tp->defn);
12011008Sshannon }
12111008Sshannon else if ((tp = lookup(&keytbl, token, NULL)) == NULL) {
12211008Sshannon if(dbg)printf(".\t%s is not a keyword\n", token);
12311008Sshannon return(CONTIG);
12411008Sshannon }
12511008Sshannon else if (tp->defn == (char *) DEFINE || tp->defn == (char *) NDEFINE || tp->defn == (char *) TDEFINE)
12611008Sshannon define(tp->defn);
12711008Sshannon else if (tp->defn == (char *) DELIM)
12811008Sshannon delim();
12911008Sshannon else if (tp->defn == (char *) GSIZE)
13011008Sshannon globsize();
13111008Sshannon else if (tp->defn == (char *) GFONT)
13211008Sshannon globfont();
13311008Sshannon else if (tp->defn == (char *) INCLUDE)
13411008Sshannon include();
13511008Sshannon else {
13611008Sshannon return((int) tp->defn);
13711008Sshannon }
13811008Sshannon goto beg;
13911008Sshannon }
14011008Sshannon
getstr(s,n)14111008Sshannon getstr(s, n) char *s; register int n; {
14211008Sshannon register int c;
14311008Sshannon register char *p;
14411008Sshannon
14511008Sshannon p = s;
14611008Sshannon while ((c = gtc()) == ' ' || c == '\n')
14711008Sshannon ;
14811008Sshannon if (c == EOF) {
14911008Sshannon *s = 0;
15011008Sshannon return;
15111008Sshannon }
15211008Sshannon while (c != ' ' && c != '\t' && c != '\n' && c != '{' && c != '}'
15311008Sshannon && c != '"' && c != '~' && c != '^' && c != righteq) {
15411008Sshannon if (c == '\\')
15511008Sshannon if ((c = gtc()) != '"')
15611008Sshannon *p++ = '\\';
15711008Sshannon *p++ = c;
15811008Sshannon if (--n <= 0)
15911008Sshannon error(FATAL, "token %.20s... too long", s);
16011008Sshannon c = gtc();
16111008Sshannon }
16211008Sshannon if (c=='{' || c=='}' || c=='"' || c=='~' || c=='^' || c=='\t' || c==righteq)
16311008Sshannon putbak(c);
16411008Sshannon *p = '\0';
16511008Sshannon yylval = (int) s;
16611008Sshannon }
16711008Sshannon
cstr(s,quote,maxs)16811008Sshannon cstr(s, quote, maxs) char *s; int quote; {
16911008Sshannon int del, c, i;
17011008Sshannon
17111008Sshannon while((del=gtc()) == ' ' || del == '\t' || del == '\n');
17211008Sshannon if (quote)
17311008Sshannon for (i=0; (c=gtc()) != del && c != EOF;) {
17411008Sshannon s[i++] = c;
17511008Sshannon if (i >= maxs)
17611008Sshannon return(1); /* disaster */
17711008Sshannon }
17811008Sshannon else {
17911008Sshannon s[0] = del;
18011008Sshannon for (i=1; (c=gtc())!=' ' && c!= '\t' && c!='\n' && c!=EOF;) {
18111008Sshannon s[i++]=c;
18211008Sshannon if (i >= maxs)
18311008Sshannon return(1); /* disaster */
18411008Sshannon }
18511008Sshannon }
18611008Sshannon s[i] = '\0';
18711008Sshannon if (c == EOF)
18811008Sshannon error(FATAL, "Unexpected end of input at %.20s", s);
18911008Sshannon return(0);
19011008Sshannon }
19111008Sshannon
define(type)19211008Sshannon define(type) int type; {
19311008Sshannon char *strsave(), *p1, *p2;
19411008Sshannon tbl *lookup();
19511008Sshannon extern tbl **deftbl;
19611008Sshannon
19711008Sshannon getstr(token, SSIZE); /* get name */
19811008Sshannon if (type != DEFINE) {
19911008Sshannon cstr(token, 1, SSIZE); /* skip the definition too */
20011008Sshannon return;
20111008Sshannon }
20211008Sshannon p1 = strsave(token);
20311008Sshannon if (cstr(token, 1, SSIZE))
20411008Sshannon error(FATAL, "Unterminated definition at %.20s", token);
20511008Sshannon p2 = strsave(token);
20611008Sshannon lookup(&deftbl, p1, p2);
20711008Sshannon if (dbg)printf(".\tname %s defined as %s\n", p1, p2);
20811008Sshannon }
20911008Sshannon
strsave(s)21011008Sshannon char *strsave(s)
21111008Sshannon char *s;
21211008Sshannon {
21311008Sshannon char *malloc();
21411008Sshannon register char *q;
21511008Sshannon
21611008Sshannon q = malloc(strlen(s)+1);
21711008Sshannon if (q == NULL)
21811008Sshannon error(FATAL, "out of space in strsave on %s", s);
21911008Sshannon strcpy(q, s);
22011008Sshannon return(q);
22111008Sshannon }
22211008Sshannon
include()22311008Sshannon include() {
22411008Sshannon error(!FATAL, "Include not yet implemented");
22511008Sshannon }
22611008Sshannon
delim()22711008Sshannon delim() {
22811008Sshannon yyval = eqnreg = 0;
22911008Sshannon if (cstr(token, 0, SSIZE))
23011008Sshannon error(FATAL, "Bizarre delimiters at %.20s", token);
23111008Sshannon lefteq = token[0];
23211008Sshannon righteq = token[1];
23311008Sshannon if (lefteq == 'o' && righteq == 'f')
23411008Sshannon lefteq = righteq = '\0';
23511008Sshannon }
236