Annotation of 43BSDReno/contrib/mh/sbr/fmtcompile.c, revision 1.1.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.