diff options
Diffstat (limited to 'eqn/lex.c')
| -rw-r--r-- | eqn/lex.c | 308 |
1 files changed, 308 insertions, 0 deletions
diff --git a/eqn/lex.c b/eqn/lex.c new file mode 100644 index 0000000000000..2e7884efc170c --- /dev/null +++ b/eqn/lex.c @@ -0,0 +1,308 @@ +/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ +/* All Rights Reserved */ + + +/* + * Copyright (c) 1980 Regents of the University of California. + * All rights reserved. The Berkeley software License Agreement + * specifies the terms and conditions for redistribution. + */ + +/* + * Copyright (c) 1983, 1984 1985, 1986, 1987, 1988, Sun Microsystems, Inc. + * All Rights Reserved. + */ + +/* from OpenSolaris "lex.c 1.6 05/06/02 SMI" SVr4.0 1.1 */ + +/* + * Portions Copyright (c) 2005 Gunnar Ritter, Freiburg i. Br., Germany + * + * Sccsid @(#)lex.c 1.7 (gritter) 11/21/07 + */ + +/* + * Changes Copyright (c) 2014 Carsten Kunze (carsten.kunze at arcor.de) + */ + +#include "e.h" +#include <stdlib.h> +#include <string.h> +#include <inttypes.h> +#include "y.tab.h" + +extern YYSTYPE yyval; + +#define SSIZE 400 +char token[SSIZE]; +int sp; +#define putbak(c) *ip++ = c; +#define PUSHBACK 300 /* maximum pushback characters */ +char ibuf[PUSHBACK+SSIZE]; /* pushback buffer for definitions, etc. */ +char *ip = ibuf; + +int +gtc(void) { + loop: + if (ip > ibuf) + return(*--ip); /* already present */ + lastchar = getc(curfile); + if (lastchar=='\n') + linect++; + if (lastchar != EOF) + return(lastchar); + if (++ifile > svargc) { + return(EOF); + } + fclose(curfile); + linect = 1; + if (openinfile() == 0) + goto loop; + return(EOF); +} +/* + * open file indexed by ifile in svargv, return non zero if fail + */ +int +openinfile(void) +{ + if (strcmp(svargv[ifile], "-") == 0){ + curfile = stdin; + return(0); + } else if ((curfile=fopen(svargv[ifile], "r")) != NULL){ + return(0); + } + error(FATAL, "can't open file %s", svargv[ifile]); + return(1); +} + +void +pbstr(register char *str) +{ + register char *p; + + p = str; + while (*p++); + --p; + if (ip >= &ibuf[PUSHBACK]) + error( FATAL, "pushback overflow"); + while (p > str) + putbak(*--p); +} + +int +yylex(void) { + register int c; + tbl *tp; + extern tbl *keytbl[], *deftbl[]; + + beg: + while ((c=gtc())==' ' || c=='\n') + ; + yylval.token = c; + switch(c) { + + case EOF: + return(EOF); + case '~': + return(SPACE); + case '^': + return(THIN); + case '\t': + return(TAB); + case '{': + return('{'); + case '}': + return('}'); + case '"': + for (sp=0; (c=gtc())!='"' && c != '\n'; ) { + if (c == '\\') + if ((c = gtc()) != '"') + token[sp++] = '\\'; + token[sp++] = c; + if (sp>=SSIZE) + error(FATAL, "quoted string %.20s... too long", token); + } + token[sp]='\0'; + yylval.str = &token[0]; + if (c == '\n') + error(!FATAL, "missing \" in %.20s", token); + return(QTEXT); + } + if (c==righteq) + return(EOF); + + putbak(c); + if (getstr(token, SSIZE)) return EOF; + if (dbg)printf(".\tlex token = |%s|\n", token); + if ((tp = lookup(deftbl, token, NULL)) != NULL) { + putbak(' '); + pbstr(tp->defn); + putbak(' '); + if (dbg) + printf(".\tfound %s|=%s|\n", token, tp->defn); + } + else if ((tp = lookup(keytbl, token, NULL)) == NULL) { + if(dbg)printf(".\t%s is not a keyword\n", token); + return(CONTIG); + } + else if ((intptr_t)tp->defn == DEFINE || (intptr_t)tp->defn == NDEFINE || (intptr_t)tp->defn == TDEFINE) + define((intptr_t)tp->defn); + else if (tp->defn == (char *) DELIM) + delim(); + else if (tp->defn == (char *) GSIZE) + globsize(); + else if (tp->defn == (char *) GFONT) + globfont(); + else if (tp->defn == (char *) INCLUDE) + include(); + else if (tp->defn == (char *) SPACE) + space(); + else { + return((intptr_t) tp->defn); + } + goto beg; +} + +/* returns: 1 if ".{WS}+EN" found, 0 else */ +int +getstr(char *s, register int n) { + register int c; + register char *p; + enum { INI = 0, OTH, SP, C1, C2, PB } st = INI; + + p = s; + while ((c = gtc()) == ' ' || c == '\n') + ; + if (c == EOF) { + *s = 0; + return 0; + } + while (((c != ' ' && c != '\t') || st == SP) && c != '\n' && c != '{' + && c != '}' && c != '"' && c != '~' && c != '^' && c != righteq) { + if (c == '\\') + if ((c = gtc()) != '"') + *p++ = '\\'; + switch (st) { + case INI: + st = c == '.' ? SP : OTH; + break; + case SP: + if (c == 'E') st = C1; + else if (c != ' ' && c != '\t') st = PB; + break; + case C1: + st = c == 'N' ? C2 : PB; + break; + case C2: + st = PB; + break; + default: ; + } + *p++ = c; + if (st == PB) + goto TF; + else { + if (--n <= 0) + error(FATAL, "token %.20s... too long", s); + c = gtc(); + } + } + if (c=='{' || c=='}' || c=='"' || c=='~' || c=='^' || c=='\t' || c==righteq) + putbak(c); +TF: + if (st == SP || st == C1 || st == PB) { + while (--p != s) putbak(*p); + p++; + } + *p = '\0'; + yylval.str = s; + return st == C2; +} + +int +cstr(char *s, int quote, int maxs) { + int del, c, i; + + s[0] = 0; + while((del=gtc()) == ' ' || del == '\t'); + if (quote) + for (i=0; (c=gtc()) != 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=gtc())!=' ' && c!= '\t' && c!='\n' && c!=EOF;) { + s[i++]=c; + if (i >= maxs) + return(1); /* disaster */ + } + } + s[i] = '\0'; + if (c == EOF) + error(FATAL, "Unexpected end of input at %.20s", s); + return(0); +} + +void +define(int type) { + char *p1, *p2; + extern tbl *deftbl[]; + + 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(FATAL, "Unterminated definition at %.20s", token); + p2 = strsave(token); + lookup(deftbl, p1, p2); + if (dbg)printf(".\tname %s defined as %s\n", p1, p2); +} + +char *spaceval = NULL; + +void +space(void) /* collect line of form "space amt" to replace \x in output */ +{ + getstr(token, SSIZE); + spaceval = strsave(token); + if (dbg) printf(".\tsetting space to %s\n", token); +} + + +char * +strsave(char *s) +{ + register char *q; + size_t l; + + l = strlen(s)+1; + q = malloc(l); + if (q == NULL) + error(FATAL, "out of space in strsave on %s", s); + n_strcpy(q, s, l); + return(q); +} + +void +include(void) { + error(!FATAL, "Include not yet implemented"); +} + +void +delim(void) { + yyval.token = eqnreg = 0; + if (cstr(token, 0, SSIZE) || token[0] & 0200 || token[1] & 0200) + error(FATAL, "Bizarre delimiters at %.20s", token); + lefteq = token[0]; + righteq = token[1]; + if (lefteq == 'o' && righteq == 'f') + lefteq = righteq = '\0'; +} |
