[BACK]Return to aicasm_scan.l CVS log [TXT][DIR] Up to [local] / sys / dev / microcode / aic7xxx

Annotation of sys/dev/microcode/aic7xxx/aicasm_scan.l, Revision 1.1

1.1     ! nbrk        1: %{
        !             2: /*     $OpenBSD: aicasm_scan.l,v 1.10 2007/05/28 22:17:21 pyr Exp $    */
        !             3: /*
        !             4:  * Lexical Analyzer for the Aic7xxx SCSI Host adapter sequencer assembler.
        !             5:  *
        !             6:  * Copyright (c) 1997, 1998, 2000 Justin T. Gibbs.
        !             7:  * Copyright (c) 2001, 2002 Adaptec Inc.
        !             8:  * All rights reserved.
        !             9:  *
        !            10:  * Redistribution and use in source and binary forms, with or without
        !            11:  * modification, are permitted provided that the following conditions
        !            12:  * are met:
        !            13:  * 1. Redistributions of source code must retain the above copyright
        !            14:  *    notice, this list of conditions, and the following disclaimer,
        !            15:  *    without modification.
        !            16:  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
        !            17:  *    substantially similar to the "NO WARRANTY" disclaimer below
        !            18:  *    ("Disclaimer") and any redistribution must be conditioned upon
        !            19:  *    including a substantially similar Disclaimer requirement for further
        !            20:  *    binary redistribution.
        !            21:  * 3. Neither the names of the above-listed copyright holders nor the names
        !            22:  *    of any contributors may be used to endorse or promote products derived
        !            23:  *    from this software without specific prior written permission.
        !            24:  *
        !            25:  * Alternatively, this software may be distributed under the terms of the
        !            26:  * GNU General Public License ("GPL") version 2 as published by the Free
        !            27:  * Software Foundation.
        !            28:  *
        !            29:  * NO WARRANTY
        !            30:  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
        !            31:  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
        !            32:  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
        !            33:  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
        !            34:  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            35:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            36:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            37:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        !            38:  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
        !            39:  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
        !            40:  * POSSIBILITY OF SUCH DAMAGES.
        !            41:  *
        !            42:  * $Id: aicasm_scan.l,v 1.10 2007/05/28 22:17:21 pyr Exp $
        !            43:  *
        !            44:  * $FreeBSD: src/sys/dev/aic7xxx/aicasm/aicasm_scan.l,v 1.22 2003/12/16 23:54:07 gibbs Exp $
        !            45:  */
        !            46:
        !            47: #include <sys/types.h>
        !            48:
        !            49: #include <inttypes.h>
        !            50: #include <limits.h>
        !            51: #include <regex.h>
        !            52: #include <stdio.h>
        !            53: #include <string.h>
        !            54: #include <sysexits.h>
        !            55: #ifdef __linux__
        !            56: #include "../queue.h"
        !            57: #else
        !            58: #include <sys/queue.h>
        !            59: #endif
        !            60:
        !            61: #include "aicasm.h"
        !            62: #include "aicasm_symbol.h"
        !            63: #include "aicasm_gram.h"
        !            64:
        !            65: /* This is used for macro body capture too, so err on the large size. */
        !            66: #define MAX_STR_CONST 4096
        !            67: static char string_buf[MAX_STR_CONST];
        !            68: static char *string_buf_ptr;
        !            69: static int  parren_count;
        !            70: static int  quote_count;
        !            71: static char buf[255];
        !            72: %}
        !            73:
        !            74: PATH           ([/]*[-A-Za-z0-9_.])+
        !            75: WORD           [A-Za-z_][-A-Za-z_0-9]*
        !            76: SPACE          [ \t]+
        !            77: MCARG          [^(), \t]+
        !            78: MBODY          ((\\[^\n])*[^\n\\]*)+
        !            79:
        !            80: %x COMMENT
        !            81: %x CEXPR
        !            82: %x INCLUDE
        !            83: %x STRING
        !            84: %x MACRODEF
        !            85: %x MACROARGLIST
        !            86: %x MACROCALLARGS
        !            87: %x MACROBODY
        !            88:
        !            89: %%
        !            90: \n                     { ++yylineno; }
        !            91: \r                     ;
        !            92: "/*"                   { BEGIN COMMENT;  /* Enter comment eating state */ }
        !            93: <COMMENT>"/*"          { fprintf(stderr, "Warning! Comment within comment."); }
        !            94: <COMMENT>\n            { ++yylineno; }
        !            95: <COMMENT>[^*/\n]*      ;
        !            96: <COMMENT>"*"+[^*/\n]*  ;
        !            97: <COMMENT>"/"+[^*/\n]*  ;
        !            98: <COMMENT>"*"+"/"       { BEGIN INITIAL; }
        !            99: if[ \t]*\(             {
        !           100:                                string_buf_ptr = string_buf;
        !           101:                                parren_count = 1;
        !           102:                                BEGIN CEXPR;
        !           103:                                return T_IF;
        !           104:                        }
        !           105: <CEXPR>\(              {       *string_buf_ptr++ = '('; parren_count++; }
        !           106: <CEXPR>\)              {
        !           107:                                parren_count--;
        !           108:                                if (parren_count == 0) {
        !           109:                                        /* All done */
        !           110:                                        BEGIN INITIAL;
        !           111:                                        *string_buf_ptr = '\0';
        !           112:                                        yylval.sym = symtable_get(string_buf);
        !           113:                                        return T_CEXPR;
        !           114:                                } else {
        !           115:                                        *string_buf_ptr++ = ')';
        !           116:                                }
        !           117:                        }
        !           118: <CEXPR>\n              { ++yylineno; }
        !           119: <CEXPR>\r              ;
        !           120: <CEXPR>[^()\n]+        {
        !           121:                                char *yptr;
        !           122:
        !           123:                                yptr = yytext;
        !           124:                                while (*yptr != '\0') {
        !           125:                                        /* Remove duplicate spaces */
        !           126:                                        if (*yptr == '\t')
        !           127:                                                *yptr = ' ';
        !           128:                                        if (*yptr == ' '
        !           129:                                         && string_buf_ptr != string_buf
        !           130:                                         && string_buf_ptr[-1] == ' ')
        !           131:                                                yptr++;
        !           132:                                        else
        !           133:                                                *string_buf_ptr++ = *yptr++;
        !           134:                                }
        !           135:                        }
        !           136:
        !           137: VERSION                        { return T_VERSION; }
        !           138: PREFIX                 { return T_PREFIX; }
        !           139: PATCH_ARG_LIST         { return T_PATCH_ARG_LIST; }
        !           140: \"                     {
        !           141:                                string_buf_ptr = string_buf;
        !           142:                                BEGIN STRING;
        !           143:                        }
        !           144: <STRING>[^"]+          {
        !           145:                                char *yptr;
        !           146:
        !           147:                                yptr = yytext;
        !           148:                                while (*yptr)
        !           149:                                        *string_buf_ptr++ = *yptr++;
        !           150:                        }
        !           151: <STRING>\"             {
        !           152:                                /* All done */
        !           153:                                BEGIN INITIAL;
        !           154:                                *string_buf_ptr = '\0';
        !           155:                                yylval.str = string_buf;
        !           156:                                return T_STRING;
        !           157:                        }
        !           158: {SPACE}                         ;
        !           159:
        !           160:        /* Register/SCB/SRAM definition keywords */
        !           161: export                 { return T_EXPORT; }
        !           162: register               { return T_REGISTER; }
        !           163: const                  { yylval.value = FALSE; return T_CONST; }
        !           164: download               { return T_DOWNLOAD; }
        !           165: address                        { return T_ADDRESS; }
        !           166: access_mode            { return T_ACCESS_MODE; }
        !           167: modes                  { return T_MODES; }
        !           168: RW|RO|WO               {
        !           169:                                 if (strcmp(yytext, "RW") == 0)
        !           170:                                        yylval.value = RW;
        !           171:                                 else if (strcmp(yytext, "RO") == 0)
        !           172:                                        yylval.value = RO;
        !           173:                                 else
        !           174:                                        yylval.value = WO;
        !           175:                                 return T_MODE;
        !           176:                        }
        !           177: BEGIN_CRITICAL         { return T_BEGIN_CS; }
        !           178: END_CRITICAL           { return T_END_CS; }
        !           179: SET_SRC_MODE           { return T_SET_SRC_MODE; }
        !           180: SET_DST_MODE           { return T_SET_DST_MODE; }
        !           181: field                  { return T_FIELD; }
        !           182: enum                   { return T_ENUM; }
        !           183: mask                   { return T_MASK; }
        !           184: alias                  { return T_ALIAS; }
        !           185: size                   { return T_SIZE; }
        !           186: scb                    { return T_SCB; }
        !           187: scratch_ram            { return T_SRAM; }
        !           188: accumulator            { return T_ACCUM; }
        !           189: mode_pointer           { return T_MODE_PTR; }
        !           190: allones                        { return T_ALLONES; }
        !           191: allzeros               { return T_ALLZEROS; }
        !           192: none                   { return T_NONE; }
        !           193: sindex                 { return T_SINDEX; }
        !           194: A                      { return T_A; }
        !           195:
        !           196:        /* Opcodes */
        !           197: shl                    { return T_SHL; }
        !           198: shr                    { return T_SHR; }
        !           199: ror                    { return T_ROR; }
        !           200: rol                    { return T_ROL; }
        !           201: mvi                    { return T_MVI; }
        !           202: mov                    { return T_MOV; }
        !           203: clr                    { return T_CLR; }
        !           204: jmp                    { return T_JMP; }
        !           205: jc                     { return T_JC;  }
        !           206: jnc                    { return T_JNC; }
        !           207: je                     { return T_JE;  }
        !           208: jne                    { return T_JNE; }
        !           209: jz                     { return T_JZ;  }
        !           210: jnz                    { return T_JNZ; }
        !           211: call                   { return T_CALL; }
        !           212: add                    { return T_ADD; }
        !           213: adc                    { return T_ADC; }
        !           214: bmov                   { return T_BMOV; }
        !           215: inc                    { return T_INC; }
        !           216: dec                    { return T_DEC; }
        !           217: stc                    { return T_STC; }
        !           218: clc                    { return T_CLC; }
        !           219: cmp                    { return T_CMP; }
        !           220: not                    { return T_NOT; }
        !           221: xor                    { return T_XOR; }
        !           222: test                   { return T_TEST;}
        !           223: and                    { return T_AND; }
        !           224: or                     { return T_OR;  }
        !           225: ret                    { return T_RET; }
        !           226: nop                    { return T_NOP; }
        !           227: else                   { return T_ELSE; }
        !           228:
        !           229:        /* Allowed Symbols */
        !           230: \<\<                   { return T_EXPR_LSHIFT; }
        !           231: \>\>                   { return T_EXPR_RSHIFT; }
        !           232: [-+,:()~|&."{};<>[\]/*!=] { return yytext[0]; }
        !           233:
        !           234:        /* Number processing */
        !           235: 0[0-7]*                        {
        !           236:                                yylval.value = strtol(yytext, NULL, 8);
        !           237:                                return T_NUMBER;
        !           238:                        }
        !           239:
        !           240: 0[xX][0-9a-fA-F]+      {
        !           241:                                yylval.value = strtoul(yytext + 2, NULL, 16);
        !           242:                                return T_NUMBER;
        !           243:                        }
        !           244:
        !           245: [1-9][0-9]*            {
        !           246:                                yylval.value = strtol(yytext, NULL, 10);
        !           247:                                return T_NUMBER;
        !           248:                        }
        !           249:        /* Include Files */
        !           250: #include{SPACE}                {
        !           251:                                BEGIN INCLUDE;
        !           252:                                quote_count = 0;
        !           253:                                return T_INCLUDE;
        !           254:                        }
        !           255: <INCLUDE>[<]           { return yytext[0]; }
        !           256: <INCLUDE>[>]           { BEGIN INITIAL; return yytext[0]; }
        !           257: <INCLUDE>[\"]          {
        !           258:                                if (quote_count != 0)
        !           259:                                        BEGIN INITIAL;
        !           260:                                quote_count++;
        !           261:                                return yytext[0];
        !           262:                        }
        !           263: <INCLUDE>{PATH}                {
        !           264:                                char *yptr;
        !           265:
        !           266:                                yptr = yytext;
        !           267:                                string_buf_ptr = string_buf;
        !           268:                                while (*yptr)
        !           269:                                        *string_buf_ptr++ = *yptr++;
        !           270:                                yylval.str = string_buf;
        !           271:                                *string_buf_ptr = '\0';
        !           272:                                return T_PATH;
        !           273:                        }
        !           274: <INCLUDE>.             { stop("Invalid include line", EX_DATAERR); }
        !           275: #define{SPACE}         {
        !           276:                                BEGIN MACRODEF;
        !           277:                                return T_DEFINE;
        !           278:                        }
        !           279: <MACRODEF>{WORD}{SPACE}        {
        !           280:                                char *yptr;
        !           281:
        !           282:                                /* Strip space and return as a normal symbol */
        !           283:                                yptr = yytext;
        !           284:                                while (*yptr != ' ' && *yptr != '\t')
        !           285:                                        yptr++;
        !           286:                                *yptr = '\0';
        !           287:                                yylval.sym = symtable_get(yytext);
        !           288:                                string_buf_ptr = string_buf;
        !           289:                                BEGIN MACROBODY;
        !           290:                                return T_SYMBOL;
        !           291:                        }
        !           292: <MACRODEF>{WORD}\(     {
        !           293:                                /*
        !           294:                                 * We store the symbol with its opening
        !           295:                                 * parren so we can differentiate macros
        !           296:                                 * that take args from macros with the
        !           297:                                 * same name that do not take args as
        !           298:                                 * is allowed in C.
        !           299:                                 */
        !           300:                                BEGIN MACROARGLIST;
        !           301:                                yylval.sym = symtable_get(yytext);
        !           302:                                unput('(');
        !           303:                                return T_SYMBOL;
        !           304:                        }
        !           305: <MACROARGLIST>{WORD}   {
        !           306:                                yylval.str = yytext;
        !           307:                                return T_ARG;
        !           308:                        }
        !           309: <MACROARGLIST>{SPACE}   ;
        !           310: <MACROARGLIST>[(,]     {
        !           311:                                return yytext[0];
        !           312:                        }
        !           313: <MACROARGLIST>[)]      {
        !           314:                                string_buf_ptr = string_buf;
        !           315:                                BEGIN MACROBODY;
        !           316:                                return ')';
        !           317:                        }
        !           318: <MACROARGLIST>.                {
        !           319:                                snprintf(buf, sizeof(buf), "Invalid character "
        !           320:                                         "'%c' in macro argument list",
        !           321:                                         yytext[0]);
        !           322:                                stop(buf, EX_DATAERR);
        !           323:                        }
        !           324: <MACROCALLARGS>{SPACE}  ;
        !           325: <MACROCALLARGS>\(      {
        !           326:                                parren_count++;
        !           327:                                if (parren_count == 1)
        !           328:                                        return ('(');
        !           329:                                *string_buf_ptr++ = '(';
        !           330:                        }
        !           331: <MACROCALLARGS>\)      {
        !           332:                                parren_count--;
        !           333:                                if (parren_count == 0) {
        !           334:                                        BEGIN INITIAL;
        !           335:                                        return (')');
        !           336:                                }
        !           337:                                *string_buf_ptr++ = ')';
        !           338:                        }
        !           339: <MACROCALLARGS>{MCARG} {
        !           340:                                char *yptr;
        !           341:
        !           342:                                yptr = yytext;
        !           343:                                while (*yptr)
        !           344:                                        *string_buf_ptr++ = *yptr++;
        !           345:                        }
        !           346: <MACROCALLARGS>\,      {
        !           347:                                if (string_buf_ptr != string_buf) {
        !           348:                                        /*
        !           349:                                         * Return an argument and
        !           350:                                         * rescan this comma so we
        !           351:                                         * can return it as well.
        !           352:                                         */
        !           353:                                        *string_buf_ptr = '\0';
        !           354:                                        yylval.str = string_buf;
        !           355:                                        string_buf_ptr = string_buf;
        !           356:                                        unput(',');
        !           357:                                        return T_ARG;
        !           358:                                }
        !           359:                                return ',';
        !           360:                        }
        !           361: <MACROBODY>\\\n                {
        !           362:                                /* Eat escaped newlines. */
        !           363:                                ++yylineno;
        !           364:                        }
        !           365: <MACROBODY>\r          ;
        !           366: <MACROBODY>\n          {
        !           367:                                /* Macros end on the first unescaped newline. */
        !           368:                                BEGIN INITIAL;
        !           369:                                *string_buf_ptr = '\0';
        !           370:                                yylval.str = string_buf;
        !           371:                                ++yylineno;
        !           372:                                return T_MACROBODY;
        !           373:                        }
        !           374: <MACROBODY>{MBODY}     {
        !           375:                                char *yptr;
        !           376:                                char c;
        !           377:
        !           378:                                yptr = yytext;
        !           379:                                while (c = *yptr++) {
        !           380:                                        /*
        !           381:                                         * Strip carriage returns.
        !           382:                                         */
        !           383:                                        if (c == '\r')
        !           384:                                                continue;
        !           385:                                        *string_buf_ptr++ = c;
        !           386:                                }
        !           387:                        }
        !           388: {WORD}\(               {
        !           389:                                char *yptr;
        !           390:                                char *ycopy;
        !           391:
        !           392:                                /* May be a symbol or a macro invocation. */
        !           393:                                yylval.sym = symtable_get(yytext);
        !           394:                                if (yylval.sym->type == MACRO) {
        !           395:                                        YY_BUFFER_STATE old_state;
        !           396:                                        YY_BUFFER_STATE temp_state;
        !           397:
        !           398:                                        ycopy = strdup(yytext);
        !           399:                                        yptr = ycopy + yyleng;
        !           400:                                        while (yptr > ycopy)
        !           401:                                                unput(*--yptr);
        !           402:                                        old_state = YY_CURRENT_BUFFER;
        !           403:                                        temp_state =
        !           404:                                            yy_create_buffer(stdin,
        !           405:                                                             YY_BUF_SIZE);
        !           406:                                        yy_switch_to_buffer(temp_state);
        !           407:                                        mm_switch_to_buffer(old_state);
        !           408:                                        mmparse();
        !           409:                                        mm_switch_to_buffer(temp_state);
        !           410:                                        yy_switch_to_buffer(old_state);
        !           411:                                        mm_delete_buffer(temp_state);
        !           412:                                        expand_macro(yylval.sym);
        !           413:                                } else {
        !           414:                                        if (yylval.sym->type == UNINITIALIZED) {
        !           415:                                                /* Try without the '(' */
        !           416:                                                symbol_delete(yylval.sym);
        !           417:                                                yytext[yyleng-1] = '\0';
        !           418:                                                yylval.sym =
        !           419:                                                    symtable_get(yytext);
        !           420:                                        }
        !           421:                                        unput('(');
        !           422:                                        return T_SYMBOL;
        !           423:                                }
        !           424:                        }
        !           425: {WORD}                 {
        !           426:                                yylval.sym = symtable_get(yytext);
        !           427:                                if (yylval.sym->type == MACRO) {
        !           428:                                        expand_macro(yylval.sym);
        !           429:                                } else {
        !           430:                                        return T_SYMBOL;
        !           431:                                }
        !           432:                        }
        !           433: .                      {
        !           434:                                snprintf(buf, sizeof(buf), "Invalid character "
        !           435:                                         "'%c'", yytext[0]);
        !           436:                                stop(buf, EX_DATAERR);
        !           437:                        }
        !           438: %%
        !           439:
        !           440: typedef struct include {
        !           441:         YY_BUFFER_STATE  buffer;
        !           442:         int              lineno;
        !           443:         char            *filename;
        !           444:        SLIST_ENTRY(include) links;
        !           445: }include_t;
        !           446:
        !           447: SLIST_HEAD(, include) include_stack;
        !           448:
        !           449: void
        !           450: include_file(char *file_name, include_type type)
        !           451: {
        !           452:        FILE *newfile;
        !           453:        include_t *include;
        !           454:
        !           455:        newfile = NULL;
        !           456:        /* Try the current directory first */
        !           457:        if (includes_search_curdir != 0 || type == SOURCE_FILE)
        !           458:                newfile = fopen(file_name, "r");
        !           459:
        !           460:        if (newfile == NULL && type != SOURCE_FILE) {
        !           461:                 path_entry_t include_dir;
        !           462:                SLIST_FOREACH(include_dir, &search_path, links) {
        !           463:                        char fullname[PATH_MAX];
        !           464:
        !           465:                        if ((include_dir->quoted_includes_only == TRUE)
        !           466:                         && (type != QUOTED_INCLUDE))
        !           467:                                continue;
        !           468:
        !           469:                        snprintf(fullname, sizeof(fullname),
        !           470:                                 "%s/%s", include_dir->directory, file_name);
        !           471:
        !           472:                        if ((newfile = fopen(fullname, "r")) != NULL)
        !           473:                                break;
        !           474:                 }
        !           475:         }
        !           476:
        !           477:        if (newfile == NULL) {
        !           478:                perror(file_name);
        !           479:                stop("Unable to open input file", EX_SOFTWARE);
        !           480:                /* NOTREACHED */
        !           481:        }
        !           482:
        !           483:        if (type != SOURCE_FILE) {
        !           484:                include = (include_t *)malloc(sizeof(include_t));
        !           485:                if (include == NULL) {
        !           486:                        stop("Unable to allocate include stack entry",
        !           487:                             EX_SOFTWARE);
        !           488:                        /* NOTREACHED */
        !           489:                }
        !           490:                include->buffer = YY_CURRENT_BUFFER;
        !           491:                include->lineno = yylineno;
        !           492:                include->filename = yyfilename;
        !           493:                SLIST_INSERT_HEAD(&include_stack, include, links);
        !           494:        }
        !           495:        yy_switch_to_buffer(yy_create_buffer(newfile, YY_BUF_SIZE));
        !           496:        yylineno = 1;
        !           497:        yyfilename = strdup(file_name);
        !           498: }
        !           499:
        !           500: static void next_substitution(struct symbol *mac_symbol, const char *body_pos,
        !           501:                              const char **next_match,
        !           502:                              struct macro_arg **match_marg, regmatch_t *match);
        !           503:
        !           504: void
        !           505: expand_macro(struct symbol *macro_symbol)
        !           506: {
        !           507:        struct macro_arg *marg;
        !           508:        struct macro_arg *match_marg;
        !           509:        const char *body_head;
        !           510:        const char *body_pos;
        !           511:        const char *next_match;
        !           512:
        !           513:        /*
        !           514:         * Due to the nature of unput, we must work
        !           515:         * backwards through the macro body performing
        !           516:         * any expansions.
        !           517:         */
        !           518:        body_head = macro_symbol->info.macroinfo->body;
        !           519:        body_pos = body_head + strlen(body_head);
        !           520:        while (body_pos > body_head) {
        !           521:                regmatch_t match;
        !           522:
        !           523:                next_match = body_head;
        !           524:                match_marg = NULL;
        !           525:                next_substitution(macro_symbol, body_pos, &next_match,
        !           526:                                  &match_marg, &match);
        !           527:
        !           528:                /* Put back everything up until the replacement. */
        !           529:                while (body_pos > next_match)
        !           530:                        unput(*--body_pos);
        !           531:
        !           532:                /* Perform the replacement. */
        !           533:                if (match_marg != NULL) {
        !           534:                        const char *strp;
        !           535:
        !           536:                        next_match = match_marg->replacement_text;
        !           537:                        strp = next_match + strlen(next_match);
        !           538:                        while (strp > next_match)
        !           539:                                unput(*--strp);
        !           540:
        !           541:                        /* Skip past the unexpanded macro arg. */
        !           542:                        body_pos -= match.rm_eo - match.rm_so;
        !           543:                }
        !           544:        }
        !           545:
        !           546:        /* Cleanup replacement text. */
        !           547:        TAILQ_FOREACH(marg, &macro_symbol->info.macroinfo->args, links) {
        !           548:                free(marg->replacement_text);
        !           549:        }
        !           550: }
        !           551:
        !           552: /*
        !           553:  * Find the next substitution in the macro working backwards from
        !           554:  * body_pos until the beginning of the macro buffer.  next_match
        !           555:  * should be initialized to the beginning of the macro buffer prior
        !           556:  * to calling this routine.
        !           557:  */
        !           558: static void
        !           559: next_substitution(struct symbol *mac_symbol, const char *body_pos,
        !           560:                  const char **next_match, struct macro_arg **match_marg,
        !           561:                  regmatch_t *match)
        !           562: {
        !           563:        regmatch_t        matches[2];
        !           564:        struct macro_arg *marg;
        !           565:        const char       *search_pos;
        !           566:        int               retval;
        !           567:
        !           568:        do {
        !           569:                search_pos = *next_match;
        !           570:
        !           571:                TAILQ_FOREACH(marg, &mac_symbol->info.macroinfo->args, links) {
        !           572:
        !           573:                        retval = regexec(&marg->arg_regex, search_pos, 2,
        !           574:                                         matches, 0);
        !           575:                        if (retval == 0
        !           576:                         && (matches[1].rm_eo + search_pos) <= body_pos
        !           577:                         && (matches[1].rm_eo + search_pos) > *next_match) {
        !           578:                                *match = matches[1];
        !           579:                                *next_match = match->rm_eo + search_pos;
        !           580:                                *match_marg = marg;
        !           581:                        }
        !           582:                }
        !           583:        } while (search_pos != *next_match);
        !           584: }
        !           585:
        !           586: int
        !           587: yywrap()
        !           588: {
        !           589:        include_t *include;
        !           590:
        !           591:        yy_delete_buffer(YY_CURRENT_BUFFER);
        !           592:        (void)fclose(yyin);
        !           593:        if (yyfilename != NULL)
        !           594:                free(yyfilename);
        !           595:        yyfilename = NULL;
        !           596:        include = SLIST_FIRST(&include_stack);
        !           597:        if (include != NULL) {
        !           598:                yy_switch_to_buffer(include->buffer);
        !           599:                yylineno = include->lineno;
        !           600:                yyfilename = include->filename;
        !           601:                SLIST_REMOVE_HEAD(&include_stack, links);
        !           602:                free(include);
        !           603:                return (0);
        !           604:        }
        !           605:        return (1);
        !           606: }

CVSweb