[BACK]Return to scan.l CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / usr.bin / config

Annotation of src/usr.bin/config/scan.l, Revision 1.13

1.1       thorpej     1: %{
1.13    ! christos    2: /*     $NetBSD: scan.l,v 1.12 2009/04/11 12:41:10 lukem Exp $  */
1.1       thorpej     3:
                      4: /*
                      5:  * Copyright (c) 1992, 1993
                      6:  *     The Regents of the University of California.  All rights reserved.
                      7:  *
                      8:  * This software was developed by the Computer Systems Engineering group
                      9:  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
                     10:  * contributed to Berkeley.
                     11:  *
                     12:  * All advertising materials mentioning features or use of this software
                     13:  * must display the following acknowledgement:
                     14:  *     This product includes software developed by the University of
                     15:  *     California, Lawrence Berkeley Laboratories.
                     16:  *
                     17:  * Redistribution and use in source and binary forms, with or without
                     18:  * modification, are permitted provided that the following conditions
                     19:  * are met:
                     20:  * 1. Redistributions of source code must retain the above copyright
                     21:  *    notice, this list of conditions and the following disclaimer.
                     22:  * 2. Redistributions in binary form must reproduce the above copyright
                     23:  *    notice, this list of conditions and the following disclaimer in the
                     24:  *    documentation and/or other materials provided with the distribution.
                     25:  * 3. Neither the name of the University nor the names of its contributors
                     26:  *    may be used to endorse or promote products derived from this software
                     27:  *    without specific prior written permission.
                     28:  *
                     29:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     30:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     31:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     32:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     33:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     34:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     35:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     36:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     37:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     38:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     39:  * SUCH DAMAGE.
                     40:  *
                     41:  *     from: @(#)scan.l        8.1 (Berkeley) 6/6/93
                     42:  */
                     43:
                     44: #include <sys/param.h>
                     45: #include <errno.h>
                     46: #include <libgen.h>
                     47: #include <stdio.h>
                     48: #include <stdlib.h>
                     49: #include <string.h>
                     50: #include <unistd.h>
1.2       martin     51: #include <stddef.h>
                     52: #include <ctype.h>
1.5       christos   53: #include <util.h>
                     54: #undef ECHO
1.1       thorpej    55: #include "defs.h"
                     56: #include "gram.h"
                     57:
                     58: int    yyline;
                     59: const char *yyfile;
                     60: const char *lastfile;
1.2       martin     61: char curinclpath[PATH_MAX];
1.9       cube       62: int ifdefstate = -1;
                     63: int st;
                     64: #define IDS_PARENT_DISABLED \
                     65:     ((ifdefstate > 6) && ((((ifdefstate/6)-1) & 1) == 1))
                     66: #define IDS_MAX_DEPTH          362797056 /* 6^11 */
                     67: /* States for ifdefstate:
                     68:
                     69:   0  -> matched ifdef
                     70:   1  -> unmatched ifdef
                     71:   2  -> matched elifdef
                     72:   3  -> unmatched elifdef
                     73:   4  -> matched else
                     74:   5  -> unmatched else
                     75:
                     76:   Upon "ifdef", add one and multiply by 6.
                     77:   Upon "endif", divide by 6, remove 1.
                     78:
                     79:   ifdef -> MATCH => continue
                     80:            MISMATCH => set to 1
                     81:   elifdef -> if (!1) -> MISMATCH
                     82:              MATCH => set to 2
                     83:              MISMATCH => if (2 || 3) set to 3, else set to 1
                     84:   else -> if (1) -> MATCH
                     85:           MATCH => set to 4
                     86:           MISMATCH => set to 5
                     87:
                     88:   in each case, if parent & 1 == 1, MISMATCH
                     89: */
                     90:
1.1       thorpej    91: /*
                     92:  * Data for returning to previous files from include files.
                     93:  */
                     94: struct incl {
                     95:        struct  incl *in_prev;  /* previous includes in effect, if any */
                     96:        YY_BUFFER_STATE in_buf; /* previous lex state */
                     97:        const char *in_fname;   /* previous file name */
                     98:        int     in_lineno;      /* previous line number */
                     99:        int     in_ateof;       /* token to insert at EOF */
                    100:        int     in_interesting; /* previous value for "interesting" */
1.9       cube      101:        int     in_ifdefstate;  /* conditional level */
1.1       thorpej   102: };
                    103: static struct incl *incl;
                    104: static int endinclude(void);
1.2       martin    105: static int getincludepath(void);
1.9       cube      106: static int getcurifdef(void);
1.1       thorpej   107:
                    108:
                    109: %}
                    110:
1.13    ! christos  111: %option  noyywrap
        !           112:
1.1       thorpej   113: PATH   [A-Za-z_0-9]*[./][-A-Za-z_0-9./]*
1.2       martin    114: QCHARS ([^"\n]|\\\")+
1.1       thorpej   115: WORD   [A-Za-z_][-A-Za-z_0-9]*
1.2       martin    116: FILENAME       ({PATH}|\"{QCHARS}\")
1.8       cube      117: RESTOFLINE     [ \t]*(#[^\n]*)?\n
1.1       thorpej   118:
1.9       cube      119: %x     IGNORED
                    120:
1.1       thorpej   121: %%
                    122:                /* Local variables for yylex() */
                    123:                int tok;
                    124:
                    125: and            return AND;
                    126: at             return AT;
                    127: attach         return ATTACH;
                    128: block          return BLOCK;
                    129: build          return BUILD;
                    130: char           return CHAR;
                    131: compile-with   return COMPILE_WITH;
                    132: config         return CONFIG;
                    133: deffs          return DEFFS;
                    134: define         return DEFINE;
                    135: defflag                return DEFFLAG;
                    136: defopt         return DEFOPT;
                    137: defparam       return DEFPARAM;
                    138: defpseudo      return DEFPSEUDO;
1.10      drochner  139: defpseudodev   return DEFPSEUDODEV;
1.1       thorpej   140: devclass       return DEVCLASS;
                    141: device         return DEVICE;
                    142: device-major   return DEVICE_MAJOR;
                    143: dumps          return DUMPS;
                    144: file           return XFILE;
                    145: file-system    return FILE_SYSTEM;
                    146: flags          return FLAGS;
                    147: ident          return IDENT;
                    148: machine                return XMACHINE;
                    149: major          return MAJOR;
                    150: makeoptions    return MAKEOPTIONS;
                    151: maxpartitions  return MAXPARTITIONS;
                    152: maxusers       return MAXUSERS;
                    153: minor          return MINOR;
                    154: needs-count    return NEEDS_COUNT;
                    155: needs-flag     return NEEDS_FLAG;
                    156: no             return NO;
                    157: object         return XOBJECT;
1.4       cube      158: obsolete       return OBSOLETE;
1.1       thorpej   159: on             return ON;
                    160: options                return OPTIONS;
                    161: prefix         return PREFIX;
                    162: pseudo-device  return PSEUDO_DEVICE;
                    163: root           return ROOT;
                    164: source         return SOURCE;
                    165: type           return TYPE;
1.3       cube      166: version        return VERSION;
1.1       thorpej   167: with           return WITH;
                    168:
                    169: \+=            return PLUSEQ;
1.6       cube      170: :=             return COLONEQ;
1.1       thorpej   171:
1.9       cube      172: <*>ifdef[ \t]+{WORD}{RESTOFLINE} {
                    173:                ifdefstate = (ifdefstate + 1) * 6;
                    174:                if (ifdefstate >= IDS_MAX_DEPTH) {
                    175:                        yyerror("too many levels of conditional");
                    176:                }
                    177:                if (!IDS_PARENT_DISABLED && getcurifdef()) {
                    178:                        BEGIN(INITIAL);
                    179:                } else {
                    180:                        ifdefstate++;
                    181:                        BEGIN(IGNORED);
                    182:                }
                    183:                yyline++;
                    184:        }
                    185:
                    186: <*>ifndef[ \t]+{WORD}{RESTOFLINE} {
                    187:                ifdefstate = (ifdefstate + 1) * 6;
                    188:                if (ifdefstate >= IDS_MAX_DEPTH) {
                    189:                        yyerror("too many levels of conditional");
                    190:                }
                    191:                if (!IDS_PARENT_DISABLED && !getcurifdef()) {
                    192:                        BEGIN(INITIAL);
                    193:                } else {
                    194:                        ifdefstate++;
                    195:                        BEGIN(IGNORED);
                    196:                }
                    197:                yyline++;
                    198:        }
                    199:
                    200:
                    201: <*>elifdef[ \t]+{WORD}{RESTOFLINE} {
                    202:                st = ifdefstate % 6;
                    203:                if (ifdefstate < 0 || st > 3) {
                    204:                        yyerror("mismatched elifdef");
                    205:                }
                    206:                if (IDS_PARENT_DISABLED ||
                    207:                    st != 1 || !getcurifdef()) {
                    208:                        if (st == 2 || st == 3) {
                    209:                                ifdefstate += 3 - st;
                    210:                        } else {
                    211:                                ifdefstate += 1 - st;
                    212:                        }
                    213:                        BEGIN(IGNORED);
                    214:                } else {
                    215:                        ifdefstate++;
                    216:                        BEGIN(INITIAL);
                    217:                }
                    218:                yyline++;
                    219:        }
                    220:
                    221: <*>elifndef[ \t]+{WORD}{RESTOFLINE} {
                    222:                st = ifdefstate % 6;
                    223:                if (ifdefstate < 0 || st > 3) {
                    224:                        yyerror("mismatched elifndef");
                    225:                }
                    226:                if (IDS_PARENT_DISABLED ||
                    227:                    st != 1 || getcurifdef()) {
                    228:                        if (st == 2 || st == 3) {
                    229:                                ifdefstate += 3 - st;
                    230:                        } else {
                    231:                                ifdefstate += 1 - st;
                    232:                        }
                    233:                        BEGIN(IGNORED);
                    234:                } else {
                    235:                        ifdefstate++;
                    236:                        BEGIN(INITIAL);
                    237:                }
                    238:                yyline++;
                    239:        }
                    240:
                    241: <*>else{RESTOFLINE} {
                    242:                st = ifdefstate % 6;
                    243:                if (ifdefstate < 0 || st > 3) {
                    244:                        yyerror("mismatched else");
                    245:                }
                    246:                if (!IDS_PARENT_DISABLED && (st == 1)) {
                    247:                        ifdefstate += 3;
                    248:                        BEGIN(INITIAL);
                    249:                } else {
                    250:                        ifdefstate += 5 - st;
                    251:                        BEGIN(IGNORED);
                    252:                }
                    253:                yyline++;
                    254:        }
                    255:
                    256: <*>endif{RESTOFLINE} {
                    257:                if (ifdefstate < 0) {
                    258:                        yyerror("mismatched endif");
                    259:                }
                    260:                if (!IDS_PARENT_DISABLED) {
                    261:                        BEGIN(INITIAL);
                    262:                }
                    263:                ifdefstate = (ifdefstate/6) - 1;
                    264:                yyline++;
                    265:        }
                    266:
                    267: <IGNORED>\n            {
                    268:                yyline++;
                    269:        }
                    270:
                    271: <IGNORED>.     /* ignore */
                    272:
1.8       cube      273: include[ \t]+{FILENAME}{RESTOFLINE}    {
                    274:                yyline++;
1.2       martin    275:                if (getincludepath()) {
                    276:                        include(curinclpath, 0, 0, 1);
                    277:                } else {
                    278:                        yyerror("bad include path-name");
                    279:                }
                    280:        }
                    281:
1.8       cube      282: cinclude[ \t]+{FILENAME}{RESTOFLINE}   {
                    283:                yyline++;
1.2       martin    284:                if (getincludepath()) {
                    285:                        include(curinclpath, 0, 1, 1);
                    286:                } else {
                    287:                        yyerror("bad cinclude path-name");
                    288:                }
                    289:        }
                    290:
1.8       cube      291: package[ \t]+{FILENAME}{RESTOFLINE}    {
                    292:                yyline++;
1.2       martin    293:                if (!oktopackage) {
                    294:                        yyerror("package not allowed here");
                    295:                } else if (getincludepath()) {
                    296:                        package(curinclpath);
                    297:                } else {
                    298:                        yyerror("bad package path-name");
                    299:                }
                    300:        }
                    301:
1.1       thorpej   302: {PATH} {
                    303:                yylval.str = intern(yytext);
                    304:                return PATHNAME;
                    305:        }
                    306:
                    307: {WORD} {
                    308:                yylval.str = intern(yytext);
                    309:                return WORD;
                    310:        }
                    311:
                    312: \"\" {
                    313:                yylval.str = intern("");
1.5       christos  314:                return EMPTYSTRING;
1.1       thorpej   315:        }
1.2       martin    316:
                    317: \"{QCHARS}     {
1.1       thorpej   318:                tok = input();  /* eat closing quote */
                    319:                if (tok != '"') {
1.7       christos  320:                        cfgerror("closing quote missing\n");
1.1       thorpej   321:                        unput(tok);
                    322:                }
                    323:                yylval.str = intern(yytext + 1);
                    324:                return QSTRING;
                    325:        }
                    326: 0[0-7]*        {
                    327:                yylval.num.fmt = 8;
                    328:                yylval.num.val = strtoll(yytext, NULL, 8);
                    329:                return NUMBER;
                    330:        }
                    331: 0[xX][0-9a-fA-F]+ {
                    332:                yylval.num.fmt = 16;
                    333:                yylval.num.val = strtoull(yytext + 2, NULL, 16);
                    334:                return NUMBER;
                    335:        }
                    336: [1-9][0-9]* {
                    337:                yylval.num.fmt = 10;
                    338:                yylval.num.val = strtoll(yytext, NULL, 10);
                    339:                return NUMBER;
                    340:        }
                    341: \n[ \t] {
                    342:                /*
                    343:                 * Note: newline followed by whitespace is always a
                    344:                 * continuation of the previous line, so do NOT
                    345:                 * return a token in this case.
                    346:                 */
                    347:                yyline++;
                    348:        }
                    349: \n     {
                    350:                yyline++;
                    351:                return '\n';
                    352:        }
                    353: \00    {
                    354:                /* Detect NUL characters in the config file and
                    355:                 * error out.
                    356:                 */
1.7       christos  357:                cfgerror("NUL character detected at line %i\n", yyline);
1.1       thorpej   358:        }
                    359: #.*    { /* ignored (comment) */; }
                    360: [ \t]+ { /* ignored (white space) */; }
                    361: .      { return yytext[0]; }
1.9       cube      362: <*><<EOF>> {
                    363:                if (ifdefstate > (incl == NULL ? -1 : incl->in_ifdefstate)) {
                    364:                        yyerror("reached EOF while looking for endif");
                    365:                }
1.1       thorpej   366:                if (incl == NULL)
                    367:                        return YY_NULL;
                    368:                tok = endinclude();
                    369:                if (tok)
                    370:                        return tok;
                    371:                /* otherwise continue scanning */
                    372:        }
                    373:
                    374: %%
                    375:
                    376: int interesting = 1;
                    377:
                    378: static int
                    379: curdir_push(const char *fname)
                    380: {
                    381:        struct prefix *pf;
                    382:        char *p, *d, *f;
                    383:
                    384:        /* Set up the initial "current directory" for include directives. */
                    385:        d = dirname(f = estrdup(fname));
                    386:        if (*d == '/')
                    387:                p = estrdup(d);
                    388:        else {
                    389:                char *cwd, buf[PATH_MAX];
                    390:
1.11      dholland  391:                if ((cwd = getcwd(buf, sizeof(buf))) == NULL) {
                    392:                        free(f);
1.1       thorpej   393:                        return (-1);
1.11      dholland  394:                }
1.1       thorpej   395:                p = emalloc(strlen(cwd) + strlen(d) + 2);
                    396:                sprintf(p, "%s/%s", cwd, d);
                    397:        }
                    398:        free(f);
                    399:        pf = ecalloc(1, sizeof(*pf));
                    400:        pf->pf_prefix = p;
                    401:        SLIST_INSERT_HEAD(&curdirs, pf, pf_next);
                    402:
                    403:        return (0);
                    404: }
                    405:
                    406: static void
                    407: curdir_pop(void)
                    408: {
                    409:        struct prefix *pf;
                    410:
                    411:        pf = SLIST_FIRST(&curdirs);
                    412:        SLIST_REMOVE_HEAD(&curdirs, pf_next);
                    413:        if (SLIST_EMPTY(&curdirs))
                    414:                panic("curdirs is empty");
                    415:        /* LINTED cast away const (pf_prefix is malloc'd for curdirs) */
1.12      lukem     416:        free((void *)__UNCONST(pf->pf_prefix));
1.1       thorpej   417:        free(pf);
                    418: }
                    419:
                    420: /*
                    421:  * Open the "main" file (conffile).
                    422:  */
                    423: int
                    424: firstfile(const char *fname)
                    425: {
                    426:
                    427: #if defined(__NetBSD__)
                    428:        if ((yyin = fopen(fname, "rf")) == NULL)
                    429: #else
                    430:        if ((yyin = fopen(fname, "r")) == NULL)
                    431: #endif
                    432:                return (-1);
                    433:
                    434:        if (curdir_push(fname) == -1)
                    435:                return (-1);
                    436:
                    437:        yyfile = conffile = fname;
                    438:        yyline = 1;
                    439:        return (0);
                    440: }
                    441:
                    442: /*
                    443:  * Add a "package" to the configuration.  This is essentially
                    444:  * syntactic sugar around the sequence:
                    445:  *
                    446:  *     prefix ../some/directory
                    447:  *     include "files.package"
                    448:  *     prefix
                    449:  */
                    450: void
                    451: package(const char *fname)
                    452: {
                    453:        char *fname1 = estrdup(fname);
                    454:        char *fname2 = estrdup(fname);
                    455:        char *dir = dirname(fname1);
                    456:        char *file = basename(fname2);
                    457:
                    458:        /*
                    459:         * Push the prefix on to the prefix stack and process the include
                    460:         * file.  When we reach the end of the include file, inserting
                    461:         * the PREFIX token into the input stream will pop the prefix off
                    462:         * of the prefix stack.
                    463:         */
                    464:        prefix_push(dir);
                    465:        (void) include(file, PREFIX, 0, 1);
                    466:
                    467:        free(fname1);
                    468:        free(fname2);
                    469: }
                    470:
                    471: /*
                    472:  * Open the named file for inclusion at the current point.  Returns 0 on
                    473:  * success (file opened and previous state pushed), nonzero on failure
                    474:  * (fopen failed, complaint made).  The `ateof' parameter controls the
                    475:  * token to be inserted at the end of the include file (i.e. ENDFILE).
                    476:  * If ateof == 0 then nothing is inserted.
                    477:  */
                    478: int
                    479: include(const char *fname, int ateof, int conditional, int direct)
                    480: {
                    481:        FILE *fp;
                    482:        struct incl *in;
                    483:        char *s;
                    484:        static int havedirs;
                    485:        extern int vflag;
                    486:
                    487:        if (havedirs == 0) {
                    488:                havedirs = 1;
                    489:                setupdirs();
                    490:        }
                    491:
                    492:        if (fname[0] == '/')
                    493:                s = estrdup(fname);
                    494:        else if (fname[0] == '.' && fname[1] == '/') {
                    495:                struct prefix *pf = SLIST_FIRST(&curdirs);
                    496:                s = emalloc(strlen(pf->pf_prefix) + strlen(fname));
                    497:                sprintf(s, "%s/%s", pf->pf_prefix, fname + 2);
                    498:        } else
                    499:                s = sourcepath(fname);
                    500:        if ((fp = fopen(s, "r")) == NULL) {
                    501:                if (conditional == 0)
1.7       christos  502:                        cfgerror("cannot open %s for reading: %s\n", s,
1.1       thorpej   503:                            strerror(errno));
                    504:                else if (vflag)
1.7       christos  505:                        cfgwarn("cannot open conditional include file %s: %s",
1.1       thorpej   506:                             s, strerror(errno));
                    507:                free(s);
                    508:                return (-1);
                    509:        }
                    510:        if (curdir_push(s) == -1) {
1.7       christos  511:                cfgerror("cannot record current working directory for %s\n", s);
1.1       thorpej   512:                fclose(fp);
                    513:                free(s);
                    514:                return (-1);
                    515:        }
                    516:        in = ecalloc(1, sizeof *in);
                    517:        in->in_prev = incl;
                    518:        in->in_buf = YY_CURRENT_BUFFER;
                    519:        in->in_fname = yyfile;
                    520:        in->in_lineno = yyline;
                    521:        in->in_ateof = ateof;
                    522:        in->in_interesting = interesting;
1.9       cube      523:        in->in_ifdefstate = ifdefstate;
1.1       thorpej   524:        interesting = direct & interesting;
                    525:        if (interesting)
                    526:                logconfig_include(fp, fname);
                    527:        incl = in;
                    528:        yy_switch_to_buffer(yy_create_buffer(fp, YY_BUF_SIZE));
                    529:        yyfile = intern(s);
                    530:        yyline = 1;
                    531:        free(s);
                    532:        return (0);
                    533: }
                    534:
                    535: /*
1.2       martin    536:  * Extract the pathname from a include/cinclude/package into curinclpath
                    537:  */
                    538: static int
                    539: getincludepath()
                    540: {
                    541:        const char *p = yytext;
1.8       cube      542:        ptrdiff_t len;
                    543:        const char *e;
1.2       martin    544:
1.8       cube      545:        while (*p && isascii((unsigned int)*p) && !isspace((unsigned int)*p))
1.2       martin    546:                p++;
1.8       cube      547:        while (*p && isascii((unsigned int)*p) && isspace((unsigned int)*p))
1.2       martin    548:                p++;
                    549:        if (!*p)
                    550:                return 0;
                    551:        if (*p == '"') {
1.8       cube      552:                p++;
                    553:                e = strchr(p, '"');
1.2       martin    554:                if (!e) return 0;
                    555:        } else {
1.8       cube      556:                e = p;
                    557:                while (*e && isascii((unsigned int)*e)
                    558:                    && !isspace((unsigned int)*e))
                    559:                        e++;
1.2       martin    560:        }
                    561:
1.8       cube      562:        len = e-p;
1.12      lukem     563:        if (len > (ptrdiff_t)sizeof(curinclpath)-1)
1.8       cube      564:                len = sizeof(curinclpath)-1;
                    565:        strncpy(curinclpath, p, sizeof(curinclpath));
                    566:        curinclpath[len] = '\0';
                    567:
1.2       martin    568:        return 1;
                    569: }
                    570:
                    571: /*
1.1       thorpej   572:  * Terminate the most recent inclusion.
                    573:  */
                    574: static int
                    575: endinclude(void)
                    576: {
                    577:        struct incl *in;
                    578:        int ateof;
                    579:
                    580:        curdir_pop();
                    581:        if ((in = incl) == NULL)
                    582:                panic("endinclude");
                    583:        incl = in->in_prev;
                    584:        lastfile = yyfile;
                    585:        yy_delete_buffer(YY_CURRENT_BUFFER);
                    586:        (void)fclose(yyin);
                    587:        yy_switch_to_buffer(in->in_buf);
                    588:        yyfile = in->in_fname;
                    589:        yyline = in->in_lineno;
                    590:        ateof  = in->in_ateof;
                    591:        interesting = in->in_interesting;
                    592:        free(in);
                    593:
                    594:        return (ateof);
                    595: }
                    596:
                    597: /*
                    598:  * Return the current line number.  If yacc has looked ahead and caused
                    599:  * us to consume a newline, we have to subtract one.  yychar is yacc's
                    600:  * token lookahead, so we can tell.
                    601:  */
                    602: int
                    603: currentline(void)
                    604: {
                    605:        extern int yychar;
                    606:
                    607:        return (yyline - (yychar == '\n'));
                    608: }
1.9       cube      609:
                    610: static int
                    611: getcurifdef(void)
                    612: {
                    613:        char *p = yytext, *q;
                    614:
                    615:        while (*p && isascii((unsigned int)*p) && !isspace((unsigned int)*p))
                    616:                p++;
                    617:        while (*p && isascii((unsigned int)*p) && isspace((unsigned int)*p))
                    618:                p++;
                    619:        q = p;
                    620:        while (*q && isascii((unsigned int)*q) && !isspace((unsigned int)*q))
                    621:                q++;
                    622:        *q = '\0';
                    623:
                    624:        return ht_lookup(attrtab, intern(p)) != NULL;
                    625: }

CVSweb <webmaster@jp.NetBSD.org>