URI:
       tlex.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tlex.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 }