Annotation of 43BSDReno/contrib/mh/sbr/fmtcompile.c, revision 1.1

1.1     ! root        1: /* fmtcompile.c - "compile" format strings for fmtscan */
        !             2: 
        !             3: #include "../h/mh.h"
        !             4: #include "../h/addrsbr.h"
        !             5: #include "../h/formatsbr.h"
        !             6: #include "../zotnet/tws.h"
        !             7: #include "../h/fmtcompile.h"
        !             8: #include <ctype.h>
        !             9: #include <stdio.h>
        !            10: #include <sys/types.h>
        !            11: #include <sys/stat.h>
        !            12: 
        !            13: static struct format *formatvec;       /* array to hold formats */
        !            14: static struct format *next_fp;         /* next free format slot */
        !            15: static struct format *fp;              /* current format slot */
        !            16: static struct comp *cm;                        /* most recent comp ref */
        !            17: static struct ftable *ftbl;            /* most recent func ref */
        !            18: static int ncomp;
        !            19: static int infunction;                 /* function nesting cnt */
        !            20: 
        !            21: extern char *getusr();
        !            22: extern struct mailname fmt_mnull;
        !            23: 
        !            24: struct ftable {
        !            25:     char       *name;          /* function name */
        !            26:     char       type;           /* argument type */
        !            27: #define                TF_COMP 0           /* component expected */
        !            28: #define                TF_NUM  1           /* number expected */
        !            29: #define                TF_STR  2           /* string expected */
        !            30: #define                TF_EXPR 3           /* component or func. expected */
        !            31: #define                TF_NONE 4           /* no argument */
        !            32: #define                TF_MYBOX 5          /* special - get current user's mbox */
        !            33: #define                TF_NOW  6           /* special - get current unix time */
        !            34: #define                TF_EXPR_SV 7        /* like expr but save current str reg */
        !            35: #define                TF_NOP  8           /* like expr but no result */
        !            36: #define                TF_TERMCAP  9       /* special - get some termcap ent */
        !            37:     char       f_type;         /* fmt type */
        !            38:     char       extra;          /* arg. type dependent extra info */
        !            39:     char       flags;
        !            40: #define                TFL_PUTS  1         /* implicit putstr if top level */
        !            41: #define                TFL_PUTN  2         /* implicit putnum if top level */
        !            42: };
        !            43: 
        !            44: static struct ftable functable[] = {
        !            45:     "nonzero", TF_EXPR,        FT_V_NE,        FT_IF_V_NE,     0,
        !            46:     "zero",    TF_EXPR,        FT_V_EQ,        FT_IF_V_EQ,     0,
        !            47:     "eq",      TF_NUM,         FT_V_EQ,        FT_IF_V_EQ,     0,
        !            48:     "ne",      TF_NUM,         FT_V_NE,        FT_IF_V_NE,     0,
        !            49:     "gt",      TF_NUM,         FT_V_GT,        FT_IF_V_GT,     0,
        !            50:     "null",    TF_EXPR,        FT_S_NULL,      FT_IF_S_NULL,   0,
        !            51:     "nonnull", TF_EXPR,        FT_S_NONNULL,   FT_IF_S,        0,
        !            52:     "match",   TF_STR,         FT_V_MATCH,     FT_IF_MATCH,    0,
        !            53:     "amatch",  TF_STR,         FT_V_AMATCH,    FT_IF_AMATCH,   0,
        !            54: 
        !            55:     "putstr",  TF_EXPR,        FT_STR,         0,              0,
        !            56:     "putstrf", TF_EXPR,        FT_STRF,        0,              0,
        !            57:     "putnum",  TF_EXPR,        FT_NUM,         0,              0,
        !            58:     "putnumf", TF_EXPR,        FT_NUMF,        0,              0,
        !            59:     "putaddr", TF_STR,         FT_PUTADDR,     0,              0,
        !            60:     "void",    TF_NOP,         0,              0,              0,
        !            61: 
        !            62:     "comp",    TF_COMP,        FT_LS_COMP,     0,              TFL_PUTS,
        !            63:     "lit",     TF_STR,         FT_LS_LIT,      0,              TFL_PUTS,
        !            64:     "force",   TF_STR,         FT_LIT_FORCE,   0,              0,
        !            65:     "trim",    TF_EXPR,        FT_LS_TRIM,     0,              0,
        !            66:     "compval", TF_COMP,        FT_LV_COMP,     0,              TFL_PUTN,
        !            67:     "compflag",        TF_COMP,        FT_LV_COMPFLAG, 0,              TFL_PUTN,
        !            68:     "num",     TF_NUM,         FT_LV_LIT,      0,              TFL_PUTN,
        !            69:     "msg",     TF_NONE,        FT_LV_DAT,      0,              TFL_PUTN,
        !            70:     "cur",     TF_NONE,        FT_LV_DAT,      1,              TFL_PUTN,
        !            71:     "size",    TF_NONE,        FT_LV_DAT,      2,              TFL_PUTN,
        !            72:     "width",   TF_NONE,        FT_LV_DAT,      3,              TFL_PUTN,
        !            73:     "dat",     TF_NUM,         FT_LV_DAT,      0,              TFL_PUTN,
        !            74:     "strlen",  TF_NONE,        FT_LV_STRLEN,   0,              TFL_PUTN,
        !            75:     "me",      TF_MYBOX,       FT_LS_LIT,      0,              TFL_PUTS,
        !            76:     "plus",    TF_NUM,         FT_LV_PLUS_L,   0,              TFL_PUTN,
        !            77:     "minus",   TF_NUM,         FT_LV_MINUS_L,  0,              TFL_PUTN,
        !            78:     "divide",  TF_NUM,         FT_LV_DIVIDE_L, 0,              TFL_PUTN,
        !            79:     "charleft",        TF_NONE,        FT_LV_CHAR_LEFT, 0,             TFL_PUTN,
        !            80:     "timenow", TF_NOW,         FT_LV_LIT,      0,              TFL_PUTN,
        !            81:     "termcap", TF_TERMCAP,     FT_LIT_FORCE,   0,              0,
        !            82: 
        !            83:     "month",   TF_COMP,        FT_LS_MONTH,    FT_PARSEDATE,   TFL_PUTS,
        !            84:     "lmonth",  TF_COMP,        FT_LS_LMONTH,   FT_PARSEDATE,   TFL_PUTS,
        !            85:     "tzone",   TF_COMP,        FT_LS_ZONE,     FT_PARSEDATE,   TFL_PUTS,
        !            86:     "day",     TF_COMP,        FT_LS_DAY,      FT_PARSEDATE,   TFL_PUTS,
        !            87:     "weekday", TF_COMP,        FT_LS_WEEKDAY,  FT_PARSEDATE,   TFL_PUTS,
        !            88:     "tws",     TF_COMP,        FT_LS_822DATE,  FT_PARSEDATE,   TFL_PUTS,
        !            89:     "sec",     TF_COMP,        FT_LV_SEC,      FT_PARSEDATE,   TFL_PUTN,
        !            90:     "min",     TF_COMP,        FT_LV_MIN,      FT_PARSEDATE,   TFL_PUTN,
        !            91:     "hour",    TF_COMP,        FT_LV_HOUR,     FT_PARSEDATE,   TFL_PUTN,
        !            92:     "mday",    TF_COMP,        FT_LV_MDAY,     FT_PARSEDATE,   TFL_PUTN,
        !            93:     "mon",     TF_COMP,        FT_LV_MON,      FT_PARSEDATE,   TFL_PUTN,
        !            94:     "year",    TF_COMP,        FT_LV_YEAR,     FT_PARSEDATE,   TFL_PUTN,
        !            95:     "yday",    TF_COMP,        FT_LV_YDAY,     FT_PARSEDATE,   TFL_PUTN,
        !            96:     "wday",    TF_COMP,        FT_LV_WDAY,     FT_PARSEDATE,   TFL_PUTN,
        !            97:     "zone",    TF_COMP,        FT_LV_ZONE,     FT_PARSEDATE,   TFL_PUTN,
        !            98:     "clock",   TF_COMP,        FT_LV_CLOCK,    FT_PARSEDATE,   TFL_PUTN,
        !            99:     "rclock",  TF_COMP,        FT_LV_RCLOCK,   FT_PARSEDATE,   TFL_PUTN,
        !           100:     "sday",    TF_COMP,        FT_LV_DAYF,     FT_PARSEDATE,   TFL_PUTN,
        !           101:     "szone",   TF_COMP,        FT_LV_ZONEF,    FT_PARSEDATE,   TFL_PUTN,
        !           102:     "dst",     TF_COMP,        FT_LV_DST,      FT_PARSEDATE,   TFL_PUTN,
        !           103:     "pretty",  TF_COMP,        FT_LS_PRETTY,   FT_PARSEDATE,   TFL_PUTS,
        !           104:     "nodate",  TF_COMP,        FT_LV_COMPFLAG, FT_PARSEDATE,   TFL_PUTN,
        !           105:     "date2local", TF_COMP,     FT_LOCALDATE,   FT_PARSEDATE,   0,
        !           106:     "date2gmt",        TF_COMP,        FT_GMTDATE,     FT_PARSEDATE,   0,
        !           107: 
        !           108:     "pers",    TF_COMP,        FT_LS_PERS,     FT_PARSEADDR,   TFL_PUTS,
        !           109:     "mbox",    TF_COMP,        FT_LS_MBOX,     FT_PARSEADDR,   TFL_PUTS,
        !           110:     "host",    TF_COMP,        FT_LS_HOST,     FT_PARSEADDR,   TFL_PUTS,
        !           111:     "path",    TF_COMP,        FT_LS_PATH,     FT_PARSEADDR,   TFL_PUTS,
        !           112:     "gname",   TF_COMP,        FT_LS_GNAME,    FT_PARSEADDR,   TFL_PUTS,
        !           113:     "note",    TF_COMP,        FT_LS_NOTE,     FT_PARSEADDR,   TFL_PUTS,
        !           114:     "proper",  TF_COMP,        FT_LS_822ADDR,  FT_PARSEADDR,   TFL_PUTS,
        !           115:     "type",    TF_COMP,        FT_LV_HOSTTYPE, FT_PARSEADDR,   TFL_PUTN,
        !           116:     "ingrp",   TF_COMP,        FT_LV_INGRPF,   FT_PARSEADDR,   TFL_PUTN,
        !           117:     "nohost",  TF_COMP,        FT_LV_NOHOSTF,  FT_PARSEADDR,   TFL_PUTN,
        !           118:     "formataddr", TF_EXPR_SV,  FT_FORMATADDR,  FT_FORMATADDR,  0,
        !           119:     "friendly",        TF_COMP,        FT_LS_FRIENDLY, FT_PARSEADDR,   TFL_PUTS,
        !           120: 
        !           121:     "mymbox",  TF_COMP,        FT_LV_COMPFLAG, FT_MYMBOX,      TFL_PUTN,
        !           122:     "addtoseq", TF_STR,                FT_ADDTOSEQ,    0,              0,
        !           123: 
        !           124:     (char *)0, 0,              0,              0,              0
        !           125: };
        !           126: 
        !           127: 
        !           128: long time();
        !           129: 
        !           130: static struct ftable *
        !           131: lookup(name)
        !           132:        register char *name;
        !           133: {
        !           134:     register struct ftable *t = functable;
        !           135:     register char *nm;
        !           136:     register char c = *name;
        !           137: 
        !           138:     while (nm = t->name) {
        !           139:        if (*nm == c && strcmp (nm, name) == 0)
        !           140:            return (ftbl = t);
        !           141: 
        !           142:        t++;
        !           143:     }
        !           144:     return (struct ftable *)0;
        !           145: }
        !           146: 
        !           147: 
        !           148: #define NEWCOMP(cm,name)\
        !           149:        cm = ((struct comp *)calloc(1, sizeof (struct comp)));\
        !           150:        cm->c_name = name; ncomp++;\
        !           151:        i = CHASH(name); cm->c_next = wantcomp[i]; wantcomp[i] = cm;
        !           152: 
        !           153: #define NEWFMT (next_fp++)
        !           154: #define NEW(type,fill,wid)\
        !           155:        fp=NEWFMT; fp->f_type=(type); fp->f_fill=(fill); fp->f_width=(wid);
        !           156: 
        !           157: #define ADDC(name)\
        !           158:        FINDCOMP( cm, name );\
        !           159:        if ( ! cm ) {\
        !           160:            NEWCOMP(cm,name);\
        !           161:        }\
        !           162:        fp->f_comp = cm;
        !           163: 
        !           164: #define LV( type, value )      NEW(type,0,0); fp->f_value = (value);
        !           165: #define LS( type, str )                NEW(type,0,0); fp->f_text = (str);
        !           166: #define PUTCOMP( comp )                NEW(FT_COMP,0,0); ADDC(comp);
        !           167: #define PUTLIT( str )          NEW(FT_LIT,0,0); fp->f_text = (str);
        !           168: #define PUTC( c )              NEW(FT_CHAR,0,0); fp->f_char = (c);
        !           169: 
        !           170: static char *compile();
        !           171: static char *do_spec();
        !           172: static char *do_name();
        !           173: static char *do_func();
        !           174: static char *do_expr();
        !           175: static char *do_if();
        !           176: 
        !           177: static char *format_string;
        !           178: static char *usr_fstring;      /* for CERROR */
        !           179: 
        !           180: #define CERROR(str) compile_error (str, cp)
        !           181: 
        !           182: static void
        !           183: compile_error(str, cp)
        !           184:        char *str;
        !           185:        char *cp;
        !           186: {
        !           187:     int errpos = cp - format_string;
        !           188:     int errctx = errpos > 20 ? 20 : errpos;
        !           189:     int i;
        !           190: 
        !           191:     usr_fstring[errpos] = '\0';
        !           192:     for (i = errpos-errctx; i < errpos; i++)
        !           193:        if (usr_fstring[i] < 32)
        !           194:            usr_fstring[i] = '_';
        !           195:     advise(NULLCP, "\"%s\": format compile error - %s",
        !           196:           &usr_fstring[errpos-errctx], str);
        !           197:     adios (NULLCP, "%*s", errctx+1, "^");
        !           198: }
        !           199: 
        !           200: /*
        !           201:  * Compile format string "fstring" into format list "fmt".
        !           202:  * Return the number of header components found in the format
        !           203:  * string.
        !           204:  */
        !           205: fmt_compile(fstring, fmt)
        !           206:        register char *fstring;
        !           207:        struct format **fmt;
        !           208: {
        !           209:     register char *cp;
        !           210:     int i;
        !           211: 
        !           212:     if (format_string)
        !           213:        (void) free (format_string);
        !           214:     format_string = getcpy (fstring);
        !           215:     usr_fstring = fstring;
        !           216: 
        !           217:     /* init the component hash table. */
        !           218:     for (i = 0; i < sizeof(wantcomp)/sizeof(wantcomp[0]); i++)
        !           219:        wantcomp[i] = 0;
        !           220: 
        !           221:     bzero ((char *) &fmt_mnull, sizeof fmt_mnull);
        !           222: 
        !           223:     /* it takes at least 4 char to generate one format so we
        !           224:      * allocate a worst-case format array using 1/4 the length
        !           225:      * of the format string.  We actually need twice this much
        !           226:      * to handle both pre-processing (e.g., address parsing) and
        !           227:      * normal processing.
        !           228:      */
        !           229:     i = strlen(fstring)/2 + 1;
        !           230:     next_fp = formatvec = (struct format *)calloc ((unsigned) i,
        !           231:                                                   sizeof(struct format));
        !           232:     if (next_fp == NULL)
        !           233:        adios (NULLCP, "unable to allocate format storage");
        !           234: 
        !           235:     ncomp = 0;
        !           236:     infunction = 0;
        !           237: 
        !           238:     cp = compile(format_string);
        !           239:     if (*cp) {
        !           240:        CERROR("extra '%>' or '%|'");
        !           241:     }
        !           242:     NEW(FT_DONE,0,0);
        !           243:     *fmt = formatvec;
        !           244: 
        !           245:     return (ncomp);
        !           246: }
        !           247: 
        !           248: static char *
        !           249: compile(sp)
        !           250:        register char *sp;
        !           251: {
        !           252:     register char *cp = sp;
        !           253:     register int  c;
        !           254: 
        !           255:     for (;;) {
        !           256:        sp = cp;
        !           257:        while ((c = *cp) && c != '%')
        !           258:            cp++;
        !           259:        *cp = 0;
        !           260:        switch (cp-sp) {
        !           261:        case 0:
        !           262:            break;
        !           263:        case 1:
        !           264:            PUTC(*sp);
        !           265:            break;
        !           266:        default:
        !           267:            PUTLIT(sp);
        !           268:            break;
        !           269:        }
        !           270:        if (c == 0)
        !           271:            return (cp);
        !           272: 
        !           273:        switch (c = *++cp) {
        !           274:        case '%':
        !           275:            PUTC (*cp);
        !           276:            cp++;
        !           277:            break;
        !           278: 
        !           279:        case '|':
        !           280:        case '>':
        !           281:            return (cp);
        !           282: 
        !           283:        case '<':
        !           284:            cp = do_if(++cp);
        !           285:            break;
        !           286: 
        !           287:        default:
        !           288:            cp = do_spec(cp);
        !           289:            break;
        !           290:        }
        !           291:     }
        !           292: }
        !           293: 
        !           294: static char *
        !           295: do_spec(sp)
        !           296:        register char *sp;
        !           297: {
        !           298:     register char *cp = sp;
        !           299:     register int c;
        !           300:     register int ljust = 0;
        !           301:     register int wid = 0;
        !           302:     register char fill = ' ';
        !           303: 
        !           304:     c = *cp++;
        !           305:     if (c == '-') {
        !           306:        ljust++;
        !           307:        c = *cp++;
        !           308:     }
        !           309:     if (c == '0') {
        !           310:        fill = c;
        !           311:        c = *cp++;
        !           312:     }
        !           313:     while (isdigit(c)) {
        !           314:        wid = wid*10 + (c - '0');
        !           315:        c = *cp++;
        !           316:     }
        !           317:     if (c == '{') {                    /* } paren match fodder */
        !           318:        cp = do_name(cp, 0);
        !           319:        if (! infunction)
        !           320:            fp->f_type = wid? FT_COMPF : FT_COMP;
        !           321:     }
        !           322:     else if (c == '(') {
        !           323:        cp = do_func(cp);
        !           324:        if (! infunction) {
        !           325:            if (ftbl->flags & TFL_PUTS) {
        !           326:                LV( wid? FT_STRF : FT_STR, ftbl->extra);
        !           327:            }
        !           328:            else if (ftbl->flags & TFL_PUTN) {
        !           329:                LV( wid? FT_NUMF : FT_NUM, ftbl->extra);
        !           330:            }
        !           331:        }
        !           332:     }
        !           333:     else {
        !           334:        CERROR("component or function name expected");
        !           335:     }
        !           336:     if (ljust)
        !           337:        wid = -wid;
        !           338:     fp->f_width = wid;
        !           339:     fp->f_fill = fill;
        !           340: 
        !           341:     return (cp);
        !           342: }
        !           343: 
        !           344: static char *
        !           345: do_name(sp, preprocess)
        !           346:        char *sp;
        !           347:        int preprocess;
        !           348: {
        !           349:     register char *cp = sp;
        !           350:     register int c;
        !           351:     register int i;
        !           352:     static int primed = 0;
        !           353: 
        !           354:     while (isalnum(c = *cp++) || c == '-')
        !           355:        ;
        !           356:     /* {{ paren match fodder */
        !           357:     if (c != '}') {
        !           358:        CERROR("'}' expected");
        !           359:     }
        !           360:     cp[-1] = '\0';
        !           361:     PUTCOMP(sp);
        !           362:     switch (preprocess) {
        !           363: 
        !           364:     case FT_PARSEDATE:
        !           365:        if (cm->c_type & CT_ADDR) {
        !           366:            CERROR("component used as both date and address");
        !           367:        }
        !           368:        if (! (cm->c_type & CT_DATE)) {
        !           369:            cm->c_tws = (struct tws *)
        !           370:                                calloc((unsigned) 1, sizeof *cm -> c_tws);
        !           371:            fp->f_type = preprocess;
        !           372:            PUTCOMP(sp);
        !           373:            cm->c_type |= CT_DATE;
        !           374:        }
        !           375:        break;
        !           376: 
        !           377:     case FT_MYMBOX:
        !           378:        if (!primed) {
        !           379:            (void) ismymbox ((struct mailname *) 0);
        !           380:            primed++;
        !           381:        }
        !           382:        cm->c_type |= CT_MYMBOX;
        !           383:        /* fall through */
        !           384:     case FT_PARSEADDR:
        !           385:        if (cm->c_type & CT_DATE) {
        !           386:            CERROR("component used as both date and address");
        !           387:        }
        !           388:        if (! (cm->c_type & CT_ADDRPARSE)) {
        !           389:            cm->c_mn = &fmt_mnull;
        !           390:            fp->f_type = preprocess;
        !           391:            PUTCOMP(sp);
        !           392:            cm->c_type |= (CT_ADDR | CT_ADDRPARSE);
        !           393:        }
        !           394:        break;
        !           395: 
        !           396:     case FT_FORMATADDR:
        !           397:        if (cm->c_type & CT_DATE) {
        !           398:            CERROR("component used as both date and address");
        !           399:        }
        !           400:        cm->c_type |= CT_ADDR;
        !           401:        break;
        !           402:     }
        !           403:     return (cp);
        !           404: }
        !           405: 
        !           406: static char *
        !           407: do_func(sp)
        !           408:        char *sp;
        !           409: {
        !           410:     register char *cp = sp;
        !           411:     register int c;
        !           412:     register struct ftable *t;
        !           413:     register int n;
        !           414:     extern char *get_termcap();
        !           415: 
        !           416:     infunction++;
        !           417: 
        !           418:     while (isalnum(c = *cp++))
        !           419:        ;
        !           420:     if (c != '(' && c != '{' && c != ' ' && c != ')') {
        !           421:        CERROR("'(', '{', ' ' or ')' expected"); /* }} paren match fodder */
        !           422:     }
        !           423:     cp[-1] = '\0';
        !           424:     if ((t = lookup (sp)) == 0) {
        !           425:        CERROR("unknown function");
        !           426:     }
        !           427:     if (isspace(c))
        !           428:        c = *cp++;
        !           429: 
        !           430:     switch (t->type) {
        !           431: 
        !           432:     case TF_COMP:
        !           433:        if (c != '{') {                         /* } paren match fodder */
        !           434:            CERROR("component name expected");
        !           435:        }
        !           436:        cp = do_name(cp, t->extra);
        !           437:        fp->f_type = t->f_type;
        !           438:        c = *cp++;
        !           439:        break;
        !           440: 
        !           441:     case TF_NUM:
        !           442:        n = 0;
        !           443:        while (isdigit(c)) {
        !           444:            n = n*10 + (c - '0');
        !           445:            c = *cp++;
        !           446:        }
        !           447:        LV(t->f_type,n);
        !           448:        break;
        !           449: 
        !           450:     case TF_STR:
        !           451:        sp = cp - 1;
        !           452:        while (c && c != ')')
        !           453:            c = *cp++;
        !           454:        cp[-1] = '\0';
        !           455:        LS(t->f_type,sp);
        !           456:        break;
        !           457: 
        !           458:     case TF_NONE:
        !           459:        LV(t->f_type,t->extra);
        !           460:        break;
        !           461: 
        !           462:     case TF_MYBOX:
        !           463:        LS(t->f_type, getusr());
        !           464:        break;
        !           465: 
        !           466:     case TF_NOW:
        !           467:        LV(t->f_type, time((long *) 0));
        !           468:        break;
        !           469: 
        !           470:     case TF_EXPR_SV:
        !           471:        LV(FT_SAVESTR, 0);
        !           472:        /* fall through */
        !           473:     case TF_EXPR:
        !           474:        *--cp = c;
        !           475:        cp = do_expr(cp, t->extra);
        !           476:        LV(t->f_type, t->extra);
        !           477:        c = *cp++;
        !           478:        ftbl = t;
        !           479:        break;
        !           480: 
        !           481:     case TF_NOP:
        !           482:        *--cp = c;
        !           483:        cp = do_expr(cp, t->extra);
        !           484:        c = *cp++;
        !           485:        ftbl = t;
        !           486:        break;
        !           487: 
        !           488:     case TF_TERMCAP:
        !           489:        sp = cp - 1;
        !           490:        while (c && c != ')')
        !           491:            c = *cp++;
        !           492:        cp[-1] = '\0';
        !           493:        if (*sp && *sp != ' ') {
        !           494:                sp = get_termcap(sp);
        !           495:                if (*sp != '\0')
        !           496:                        LS(t->f_type, sp);
        !           497:        }
        !           498:        break;
        !           499:     }
        !           500:     if (c != ')') {
        !           501:        CERROR("')' expected");
        !           502:     }
        !           503:     --infunction;
        !           504:     return (cp);
        !           505: }
        !           506: 
        !           507: static char *
        !           508: do_expr(sp, preprocess)
        !           509:        char *sp;
        !           510: {
        !           511:     register char *cp = sp;
        !           512:     register int  c;
        !           513: 
        !           514:     if ((c = *cp++) == '{') {                  /* } parent match fodder */
        !           515:        cp = do_name (cp, preprocess);
        !           516:        fp->f_type = FT_LS_COMP;
        !           517:     } else if (c == '(') {
        !           518:        cp = do_func (cp);
        !           519:     } else if (c == ')') {
        !           520:        return (--cp);
        !           521:     } else if (c == '%' && *cp == '<') {
        !           522:        cp = do_if (cp+1);
        !           523:     } else {
        !           524:        CERROR ("'(', '{', '%<' or ')' expected"); /* } parent match fodder */
        !           525:     }
        !           526:     return (cp);
        !           527: }
        !           528: 
        !           529: static char *
        !           530: do_if(sp)
        !           531:        register char *sp;
        !           532: {
        !           533:     register char *cp = sp;
        !           534:     register struct format *fexpr, *fif, *felse;
        !           535:     register int c;
        !           536: 
        !           537:     if ((c = *cp++) == '{') {          /* } paren match fodder */
        !           538:        cp = do_name(cp, 0);
        !           539:        fp->f_type = FT_LS_COMP;
        !           540:        LV (FT_IF_S, 0);
        !           541:     }
        !           542:     else if (c == '(') {
        !           543:        cp = do_func(cp);
        !           544:        /* see if we can merge the load and the "if" */
        !           545:        if (ftbl->f_type >= IF_FUNCS)
        !           546:            fp->f_type = ftbl->extra;
        !           547:        else {
        !           548:            LV (FT_IF_V_NE, 0);
        !           549:        }
        !           550:     }
        !           551:     else  {
        !           552:        CERROR("'(' or '{' expected");  /* } paren match fodder */
        !           553:     }
        !           554:     fexpr = fp;
        !           555:     cp = compile (cp);
        !           556:     if ((c = *cp++) == '|') {
        !           557:        LV(FT_GOTO, 0);
        !           558:        fif = fp;
        !           559:        felse = next_fp;
        !           560:        cp = compile(cp);
        !           561:        fif->f_skip = next_fp - fif;
        !           562:        c = *cp++;
        !           563:     }
        !           564:     else
        !           565:        felse = next_fp;
        !           566: 
        !           567:     if (c != '>') {
        !           568:        CERROR("'>' expected.");
        !           569:     }
        !           570:     fexpr->f_skip = felse - fexpr;
        !           571: 
        !           572:     return (cp);
        !           573: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.