Subversion Repositories planix.SVN

Rev

Rev 2 | Blame | Compare with Previous | Last modification | View Log | RSS feed

#include "e.h"
#include "y.tab.h"
#include <ctype.h>

#define SSIZE   1000
char    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';
}