123925Sgibbs%{ 2139749Simp/*- 323925Sgibbs * Lexical Analyzer for the Aic7xxx SCSI Host adapter sequencer assembler. 423925Sgibbs * 595376Sgibbs * Copyright (c) 1997, 1998, 2000 Justin T. Gibbs. 6102668Sgibbs * Copyright (c) 2001, 2002 Adaptec Inc. 723925Sgibbs * All rights reserved. 823925Sgibbs * 923925Sgibbs * Redistribution and use in source and binary forms, with or without 1023925Sgibbs * modification, are permitted provided that the following conditions 1123925Sgibbs * are met: 1223925Sgibbs * 1. Redistributions of source code must retain the above copyright 1326997Sgibbs * notice, this list of conditions, and the following disclaimer, 1454211Sgibbs * without modification. 1595376Sgibbs * 2. Redistributions in binary form must reproduce at minimum a disclaimer 1695376Sgibbs * substantially similar to the "NO WARRANTY" disclaimer below 1795376Sgibbs * ("Disclaimer") and any redistribution must be conditioned upon 1895376Sgibbs * including a substantially similar Disclaimer requirement for further 1995376Sgibbs * binary redistribution. 2095376Sgibbs * 3. Neither the names of the above-listed copyright holders nor the names 2195376Sgibbs * of any contributors may be used to endorse or promote products derived 2295376Sgibbs * from this software without specific prior written permission. 2323925Sgibbs * 2463457Sgibbs * Alternatively, this software may be distributed under the terms of the 2595376Sgibbs * GNU General Public License ("GPL") version 2 as published by the Free 2695376Sgibbs * Software Foundation. 2763457Sgibbs * 2895376Sgibbs * NO WARRANTY 2995376Sgibbs * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 3095376Sgibbs * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3195376Sgibbs * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 3295376Sgibbs * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3395376Sgibbs * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3423925Sgibbs * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3523925Sgibbs * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3695376Sgibbs * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 3795376Sgibbs * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 3895376Sgibbs * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 3995376Sgibbs * POSSIBILITY OF SUCH DAMAGES. 4023925Sgibbs * 41123577Sgibbs * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_scan.l#19 $ 4265943Sgibbs * 4350477Speter * $FreeBSD$ 4423925Sgibbs */ 4523925Sgibbs 4623942Sbde#include <sys/types.h> 4723942Sbde 48104028Sgibbs#include <inttypes.h> 4923925Sgibbs#include <limits.h> 5095376Sgibbs#include <regex.h> 5123925Sgibbs#include <stdio.h> 5223925Sgibbs#include <string.h> 5323925Sgibbs#include <sysexits.h> 5423925Sgibbs#include <sys/queue.h> 5523925Sgibbs 5629050Sgibbs#include "aicasm.h" 5729050Sgibbs#include "aicasm_symbol.h" 5895376Sgibbs#include "aicasm_gram.h" 5939220Sgibbs 6095376Sgibbs/* This is used for macro body capture too, so err on the large size. */ 6195376Sgibbs#define MAX_STR_CONST 4096 6295376Sgibbsstatic char string_buf[MAX_STR_CONST]; 6395376Sgibbsstatic char *string_buf_ptr; 6495376Sgibbsstatic int parren_count; 6595376Sgibbsstatic int quote_count; 66193244Sdelphijstatic char msgbuf[255]; 67193244Sdelphij 68193244Sdelphijextern int yylex(void); 69193244Sdelphijextern int mmlex(void); 70193244Sdelphijextern int mmparse(void); 71193244Sdelphijextern void mm_switch_to_buffer(YY_BUFFER_STATE); 72193244Sdelphijextern void mm_delete_buffer(YY_BUFFER_STATE); 7323925Sgibbs%} 7423925Sgibbs 75229101Sdim%option noinput 76229101Sdim 7795376SgibbsPATH ([/]*[-A-Za-z0-9_.])+ 7823925SgibbsWORD [A-Za-z_][-A-Za-z_0-9]* 7923925SgibbsSPACE [ \t]+ 8095376SgibbsMCARG [^(), \t]+ 8195376SgibbsMBODY ((\\[^\n])*[^\n\\]*)+ 8223925Sgibbs 8323925Sgibbs%x COMMENT 8439220Sgibbs%x CEXPR 8539220Sgibbs%x INCLUDE 8679873Sgibbs%x STRING 8795376Sgibbs%x MACRODEF 8895376Sgibbs%x MACROARGLIST 8995376Sgibbs%x MACROCALLARGS 9095376Sgibbs%x MACROBODY 9123925Sgibbs 9223925Sgibbs%% 9323925Sgibbs\n { ++yylineno; } 94123577Sgibbs\r ; 9523925Sgibbs"/*" { BEGIN COMMENT; /* Enter comment eating state */ } 9623925Sgibbs<COMMENT>"/*" { fprintf(stderr, "Warning! Comment within comment."); } 9723925Sgibbs<COMMENT>\n { ++yylineno; } 9823925Sgibbs<COMMENT>[^*/\n]* ; 9923925Sgibbs<COMMENT>"*"+[^*/\n]* ; 10023925Sgibbs<COMMENT>"/"+[^*/\n]* ; 10123925Sgibbs<COMMENT>"*"+"/" { BEGIN INITIAL; } 10239220Sgibbsif[ \t]*\( { 10339220Sgibbs string_buf_ptr = string_buf; 10439220Sgibbs parren_count = 1; 10539220Sgibbs BEGIN CEXPR; 10639220Sgibbs return T_IF; 10739220Sgibbs } 10839220Sgibbs<CEXPR>\( { *string_buf_ptr++ = '('; parren_count++; } 10939220Sgibbs<CEXPR>\) { 11039220Sgibbs parren_count--; 11139220Sgibbs if (parren_count == 0) { 11239220Sgibbs /* All done */ 11339220Sgibbs BEGIN INITIAL; 11439220Sgibbs *string_buf_ptr = '\0'; 11539220Sgibbs yylval.sym = symtable_get(string_buf); 11639220Sgibbs return T_CEXPR; 11739220Sgibbs } else { 11839220Sgibbs *string_buf_ptr++ = ')'; 11939220Sgibbs } 12039220Sgibbs } 12139220Sgibbs<CEXPR>\n { ++yylineno; } 122123577Sgibbs<CEXPR>\r ; 12365943Sgibbs<CEXPR>[^()\n]+ { 12479873Sgibbs char *yptr; 12523925Sgibbs 12679873Sgibbs yptr = yytext; 12765943Sgibbs while (*yptr != '\0') { 12865943Sgibbs /* Remove duplicate spaces */ 12965943Sgibbs if (*yptr == '\t') 13065943Sgibbs *yptr = ' '; 13165943Sgibbs if (*yptr == ' ' 13265943Sgibbs && string_buf_ptr != string_buf 13365943Sgibbs && string_buf_ptr[-1] == ' ') 13465943Sgibbs yptr++; 13565943Sgibbs else 13665943Sgibbs *string_buf_ptr++ = *yptr++; 13765943Sgibbs } 13839220Sgibbs } 13939220Sgibbs 14079873SgibbsVERSION { return T_VERSION; } 141102668SgibbsPREFIX { return T_PREFIX; } 14295376SgibbsPATCH_ARG_LIST { return T_PATCH_ARG_LIST; } 14379873Sgibbs\" { 14479873Sgibbs string_buf_ptr = string_buf; 14579873Sgibbs BEGIN STRING; 14679873Sgibbs } 14779873Sgibbs<STRING>[^"]+ { 14879873Sgibbs char *yptr; 14979873Sgibbs 15079873Sgibbs yptr = yytext; 15179873Sgibbs while (*yptr) 15279873Sgibbs *string_buf_ptr++ = *yptr++; 15379873Sgibbs } 15479873Sgibbs<STRING>\" { 15579873Sgibbs /* All done */ 15679873Sgibbs BEGIN INITIAL; 15779873Sgibbs *string_buf_ptr = '\0'; 15879873Sgibbs yylval.str = string_buf; 15979873Sgibbs return T_STRING; 16079873Sgibbs } 16195376Sgibbs{SPACE} ; 16223925Sgibbs 16323925Sgibbs /* Register/SCB/SRAM definition keywords */ 16495376Sgibbsexport { return T_EXPORT; } 16523925Sgibbsregister { return T_REGISTER; } 16623925Sgibbsconst { yylval.value = FALSE; return T_CONST; } 16729897Sgibbsdownload { return T_DOWNLOAD; } 16823925Sgibbsaddress { return T_ADDRESS; } 16923925Sgibbsaccess_mode { return T_ACCESS_MODE; } 17095376Sgibbsmodes { return T_MODES; } 17123925SgibbsRW|RO|WO { 17223925Sgibbs if (strcmp(yytext, "RW") == 0) 17323925Sgibbs yylval.value = RW; 17423925Sgibbs else if (strcmp(yytext, "RO") == 0) 17523925Sgibbs yylval.value = RO; 17623925Sgibbs else 17723925Sgibbs yylval.value = WO; 17823925Sgibbs return T_MODE; 17923925Sgibbs } 18066270SgibbsBEGIN_CRITICAL { return T_BEGIN_CS; } 18166270SgibbsEND_CRITICAL { return T_END_CS; } 18295376SgibbsSET_SRC_MODE { return T_SET_SRC_MODE; } 18395376SgibbsSET_DST_MODE { return T_SET_DST_MODE; } 184102668Sgibbsfield { return T_FIELD; } 185102668Sgibbsenum { return T_ENUM; } 18623925Sgibbsmask { return T_MASK; } 18723925Sgibbsalias { return T_ALIAS; } 18823925Sgibbssize { return T_SIZE; } 18923925Sgibbsscb { return T_SCB; } 19023925Sgibbsscratch_ram { return T_SRAM; } 19123925Sgibbsaccumulator { return T_ACCUM; } 19295376Sgibbsmode_pointer { return T_MODE_PTR; } 19323925Sgibbsallones { return T_ALLONES; } 19423925Sgibbsallzeros { return T_ALLZEROS; } 19523925Sgibbsnone { return T_NONE; } 19623925Sgibbssindex { return T_SINDEX; } 19723925SgibbsA { return T_A; } 19823925Sgibbs 19923925Sgibbs /* Opcodes */ 20023925Sgibbsshl { return T_SHL; } 20123925Sgibbsshr { return T_SHR; } 20223925Sgibbsror { return T_ROR; } 20323925Sgibbsrol { return T_ROL; } 20423925Sgibbsmvi { return T_MVI; } 20523925Sgibbsmov { return T_MOV; } 20623925Sgibbsclr { return T_CLR; } 20723925Sgibbsjmp { return T_JMP; } 20823925Sgibbsjc { return T_JC; } 20923925Sgibbsjnc { return T_JNC; } 21023925Sgibbsje { return T_JE; } 21123925Sgibbsjne { return T_JNE; } 21223925Sgibbsjz { return T_JZ; } 21323925Sgibbsjnz { return T_JNZ; } 21423925Sgibbscall { return T_CALL; } 21523925Sgibbsadd { return T_ADD; } 21623925Sgibbsadc { return T_ADC; } 21739220Sgibbsbmov { return T_BMOV; } 21823925Sgibbsinc { return T_INC; } 21923925Sgibbsdec { return T_DEC; } 22023925Sgibbsstc { return T_STC; } 22123925Sgibbsclc { return T_CLC; } 22223925Sgibbscmp { return T_CMP; } 22363457Sgibbsnot { return T_NOT; } 22423925Sgibbsxor { return T_XOR; } 22523925Sgibbstest { return T_TEST;} 22623925Sgibbsand { return T_AND; } 22723925Sgibbsor { return T_OR; } 22823925Sgibbsret { return T_RET; } 22923925Sgibbsnop { return T_NOP; } 23039220Sgibbselse { return T_ELSE; } 23123925Sgibbs 23223925Sgibbs /* Allowed Symbols */ 23395376Sgibbs\<\< { return T_EXPR_LSHIFT; } 23495376Sgibbs\>\> { return T_EXPR_RSHIFT; } 23595376Sgibbs[-+,:()~|&."{};<>[\]/*!=] { return yytext[0]; } 23623925Sgibbs 23723925Sgibbs /* Number processing */ 23823925Sgibbs0[0-7]* { 23923925Sgibbs yylval.value = strtol(yytext, NULL, 8); 24023925Sgibbs return T_NUMBER; 24123925Sgibbs } 24223925Sgibbs 24323925Sgibbs0[xX][0-9a-fA-F]+ { 24423925Sgibbs yylval.value = strtoul(yytext + 2, NULL, 16); 24523925Sgibbs return T_NUMBER; 24623925Sgibbs } 24723925Sgibbs 24823925Sgibbs[1-9][0-9]* { 24923925Sgibbs yylval.value = strtol(yytext, NULL, 10); 25023925Sgibbs return T_NUMBER; 25123925Sgibbs } 25223925Sgibbs /* Include Files */ 25379873Sgibbs#include{SPACE} { 25479873Sgibbs BEGIN INCLUDE; 25579873Sgibbs quote_count = 0; 25679873Sgibbs return T_INCLUDE; 25779873Sgibbs } 25879873Sgibbs<INCLUDE>[<] { return yytext[0]; } 25979873Sgibbs<INCLUDE>[>] { BEGIN INITIAL; return yytext[0]; } 26079873Sgibbs<INCLUDE>[\"] { 26179873Sgibbs if (quote_count != 0) 26279873Sgibbs BEGIN INITIAL; 26379873Sgibbs quote_count++; 26479873Sgibbs return yytext[0]; 26579873Sgibbs } 26695376Sgibbs<INCLUDE>{PATH} { 26779873Sgibbs char *yptr; 26823925Sgibbs 26979873Sgibbs yptr = yytext; 27079873Sgibbs string_buf_ptr = string_buf; 27179873Sgibbs while (*yptr) 27279873Sgibbs *string_buf_ptr++ = *yptr++; 27379873Sgibbs yylval.str = string_buf; 27479873Sgibbs *string_buf_ptr = '\0'; 27579873Sgibbs return T_PATH; 27679873Sgibbs } 27795376Sgibbs<INCLUDE>. { stop("Invalid include line", EX_DATAERR); } 27895376Sgibbs#define{SPACE} { 27995376Sgibbs BEGIN MACRODEF; 28095376Sgibbs return T_DEFINE; 28195376Sgibbs } 28295376Sgibbs<MACRODEF>{WORD}{SPACE} { 28395376Sgibbs char *yptr; 28479873Sgibbs 28595376Sgibbs /* Strip space and return as a normal symbol */ 28695376Sgibbs yptr = yytext; 28795376Sgibbs while (*yptr != ' ' && *yptr != '\t') 28895376Sgibbs yptr++; 28995376Sgibbs *yptr = '\0'; 29095376Sgibbs yylval.sym = symtable_get(yytext); 29195376Sgibbs string_buf_ptr = string_buf; 29295376Sgibbs BEGIN MACROBODY; 29395376Sgibbs return T_SYMBOL; 29495376Sgibbs } 29595376Sgibbs<MACRODEF>{WORD}\( { 29695376Sgibbs /* 29795376Sgibbs * We store the symbol with its opening 29895376Sgibbs * parren so we can differentiate macros 29995376Sgibbs * that take args from macros with the 30095376Sgibbs * same name that do not take args as 30195376Sgibbs * is allowed in C. 30295376Sgibbs */ 30395376Sgibbs BEGIN MACROARGLIST; 30495376Sgibbs yylval.sym = symtable_get(yytext); 30595376Sgibbs unput('('); 30695376Sgibbs return T_SYMBOL; 30795376Sgibbs } 30895376Sgibbs<MACROARGLIST>{WORD} { 30995376Sgibbs yylval.str = yytext; 31095376Sgibbs return T_ARG; 31195376Sgibbs } 31295376Sgibbs<MACROARGLIST>{SPACE} ; 31395376Sgibbs<MACROARGLIST>[(,] { 31495376Sgibbs return yytext[0]; 31595376Sgibbs } 31695376Sgibbs<MACROARGLIST>[)] { 31795376Sgibbs string_buf_ptr = string_buf; 31895376Sgibbs BEGIN MACROBODY; 31995376Sgibbs return ')'; 32095376Sgibbs } 32195376Sgibbs<MACROARGLIST>. { 322193244Sdelphij snprintf(msgbuf, sizeof(msgbuf), "Invalid character " 32395376Sgibbs "'%c' in macro argument list", 32495376Sgibbs yytext[0]); 325193244Sdelphij stop(msgbuf, EX_DATAERR); 32695376Sgibbs } 32795376Sgibbs<MACROCALLARGS>{SPACE} ; 32895376Sgibbs<MACROCALLARGS>\( { 32995376Sgibbs parren_count++; 33095376Sgibbs if (parren_count == 1) 33195376Sgibbs return ('('); 33295376Sgibbs *string_buf_ptr++ = '('; 33395376Sgibbs } 33495376Sgibbs<MACROCALLARGS>\) { 33595376Sgibbs parren_count--; 33695376Sgibbs if (parren_count == 0) { 33795376Sgibbs BEGIN INITIAL; 33895376Sgibbs return (')'); 33995376Sgibbs } 34095376Sgibbs *string_buf_ptr++ = ')'; 34195376Sgibbs } 34295376Sgibbs<MACROCALLARGS>{MCARG} { 34395376Sgibbs char *yptr; 34423925Sgibbs 34595376Sgibbs yptr = yytext; 34695376Sgibbs while (*yptr) 34795376Sgibbs *string_buf_ptr++ = *yptr++; 34895376Sgibbs } 34995376Sgibbs<MACROCALLARGS>\, { 35095376Sgibbs if (string_buf_ptr != string_buf) { 35195376Sgibbs /* 35295376Sgibbs * Return an argument and 35395376Sgibbs * rescan this comma so we 35495376Sgibbs * can return it as well. 35595376Sgibbs */ 35695376Sgibbs *string_buf_ptr = '\0'; 35795376Sgibbs yylval.str = string_buf; 35895376Sgibbs string_buf_ptr = string_buf; 35995376Sgibbs unput(','); 36095376Sgibbs return T_ARG; 36195376Sgibbs } 36295376Sgibbs return ','; 36395376Sgibbs } 36495376Sgibbs<MACROBODY>\\\n { 36595376Sgibbs /* Eat escaped newlines. */ 36695376Sgibbs ++yylineno; 36795376Sgibbs } 368123577Sgibbs<MACROBODY>\r ; 36995376Sgibbs<MACROBODY>\n { 37095376Sgibbs /* Macros end on the first unescaped newline. */ 37195376Sgibbs BEGIN INITIAL; 37295376Sgibbs *string_buf_ptr = '\0'; 37395376Sgibbs yylval.str = string_buf; 37495376Sgibbs ++yylineno; 37595376Sgibbs return T_MACROBODY; 37695376Sgibbs } 37795376Sgibbs<MACROBODY>{MBODY} { 37895376Sgibbs char *yptr; 379123577Sgibbs char c; 38095376Sgibbs 38195376Sgibbs yptr = yytext; 382193244Sdelphij while ((c = *yptr++)) { 383123577Sgibbs /* 384123577Sgibbs * Strip carriage returns. 385123577Sgibbs */ 386123577Sgibbs if (c == '\r') 387123577Sgibbs continue; 388123577Sgibbs *string_buf_ptr++ = c; 389123577Sgibbs } 39095376Sgibbs } 39195376Sgibbs{WORD}\( { 39295376Sgibbs char *yptr; 39395376Sgibbs char *ycopy; 39495376Sgibbs 39595376Sgibbs /* May be a symbol or a macro invocation. */ 39695376Sgibbs yylval.sym = symtable_get(yytext); 39795376Sgibbs if (yylval.sym->type == MACRO) { 39895376Sgibbs YY_BUFFER_STATE old_state; 39995376Sgibbs YY_BUFFER_STATE temp_state; 40095376Sgibbs 40195376Sgibbs ycopy = strdup(yytext); 40295376Sgibbs yptr = ycopy + yyleng; 40395376Sgibbs while (yptr > ycopy) 40495376Sgibbs unput(*--yptr); 40595376Sgibbs old_state = YY_CURRENT_BUFFER; 40695376Sgibbs temp_state = 40795376Sgibbs yy_create_buffer(stdin, 40895376Sgibbs YY_BUF_SIZE); 40995376Sgibbs yy_switch_to_buffer(temp_state); 41095376Sgibbs mm_switch_to_buffer(old_state); 41195376Sgibbs mmparse(); 41295376Sgibbs mm_switch_to_buffer(temp_state); 41395376Sgibbs yy_switch_to_buffer(old_state); 41495376Sgibbs mm_delete_buffer(temp_state); 41595376Sgibbs expand_macro(yylval.sym); 41695376Sgibbs } else { 41795376Sgibbs if (yylval.sym->type == UNINITIALIZED) { 41895376Sgibbs /* Try without the '(' */ 41995376Sgibbs symbol_delete(yylval.sym); 42095376Sgibbs yytext[yyleng-1] = '\0'; 42195376Sgibbs yylval.sym = 42295376Sgibbs symtable_get(yytext); 42395376Sgibbs } 42495376Sgibbs unput('('); 42595376Sgibbs return T_SYMBOL; 42695376Sgibbs } 42795376Sgibbs } 42895376Sgibbs{WORD} { 42995376Sgibbs yylval.sym = symtable_get(yytext); 43095376Sgibbs if (yylval.sym->type == MACRO) { 43195376Sgibbs expand_macro(yylval.sym); 43295376Sgibbs } else { 43395376Sgibbs return T_SYMBOL; 43495376Sgibbs } 43595376Sgibbs } 43623925Sgibbs. { 437193244Sdelphij snprintf(msgbuf, sizeof(msgbuf), "Invalid character " 43823925Sgibbs "'%c'", yytext[0]); 439193244Sdelphij stop(msgbuf, EX_DATAERR); 44023925Sgibbs } 44123925Sgibbs%% 44223925Sgibbs 44323925Sgibbstypedef struct include { 44423925Sgibbs YY_BUFFER_STATE buffer; 44523925Sgibbs int lineno; 44623925Sgibbs char *filename; 44760938Sjake SLIST_ENTRY(include) links; 44823925Sgibbs}include_t; 44923925Sgibbs 45060938SjakeSLIST_HEAD(, include) include_stack; 45123925Sgibbs 45223925Sgibbsvoid 45365943Sgibbsinclude_file(char *file_name, include_type type) 45423925Sgibbs{ 45523925Sgibbs FILE *newfile; 45623925Sgibbs include_t *include; 45723925Sgibbs 45823925Sgibbs newfile = NULL; 45923925Sgibbs /* Try the current directory first */ 46023925Sgibbs if (includes_search_curdir != 0 || type == SOURCE_FILE) 46123925Sgibbs newfile = fopen(file_name, "r"); 46223925Sgibbs 46323925Sgibbs if (newfile == NULL && type != SOURCE_FILE) { 46423925Sgibbs path_entry_t include_dir; 46523925Sgibbs for (include_dir = search_path.slh_first; 46623925Sgibbs include_dir != NULL; 46723925Sgibbs include_dir = include_dir->links.sle_next) { 46823925Sgibbs char fullname[PATH_MAX]; 46923925Sgibbs 47023925Sgibbs if ((include_dir->quoted_includes_only == TRUE) 47123925Sgibbs && (type != QUOTED_INCLUDE)) 47223925Sgibbs continue; 47323925Sgibbs 47423925Sgibbs snprintf(fullname, sizeof(fullname), 47523925Sgibbs "%s/%s", include_dir->directory, file_name); 47623925Sgibbs 47723925Sgibbs if ((newfile = fopen(fullname, "r")) != NULL) 47823925Sgibbs break; 47923925Sgibbs } 48023925Sgibbs } 48123925Sgibbs 48223925Sgibbs if (newfile == NULL) { 48323925Sgibbs perror(file_name); 48423925Sgibbs stop("Unable to open input file", EX_SOFTWARE); 48523925Sgibbs /* NOTREACHED */ 48623925Sgibbs } 48726997Sgibbs 48826997Sgibbs if (type != SOURCE_FILE) { 48926997Sgibbs include = (include_t *)malloc(sizeof(include_t)); 49026997Sgibbs if (include == NULL) { 49126997Sgibbs stop("Unable to allocate include stack entry", 49226997Sgibbs EX_SOFTWARE); 49326997Sgibbs /* NOTREACHED */ 49426997Sgibbs } 49526997Sgibbs include->buffer = YY_CURRENT_BUFFER; 49626997Sgibbs include->lineno = yylineno; 49726997Sgibbs include->filename = yyfilename; 49826997Sgibbs SLIST_INSERT_HEAD(&include_stack, include, links); 49923925Sgibbs } 50023925Sgibbs yy_switch_to_buffer(yy_create_buffer(newfile, YY_BUF_SIZE)); 50123925Sgibbs yylineno = 1; 50223925Sgibbs yyfilename = strdup(file_name); 50323925Sgibbs} 50423925Sgibbs 50595376Sgibbsstatic void next_substitution(struct symbol *mac_symbol, const char *body_pos, 50695376Sgibbs const char **next_match, 50795376Sgibbs struct macro_arg **match_marg, regmatch_t *match); 50895376Sgibbs 50995376Sgibbsvoid 51095376Sgibbsexpand_macro(struct symbol *macro_symbol) 51195376Sgibbs{ 51295376Sgibbs struct macro_arg *marg; 51395376Sgibbs struct macro_arg *match_marg; 51495376Sgibbs const char *body_head; 51595376Sgibbs const char *body_pos; 51695376Sgibbs const char *next_match; 517193268Sdelphij regmatch_t match = { .rm_so = 0, .rm_eo = 0 }; 51895376Sgibbs 51995376Sgibbs /* 52095376Sgibbs * Due to the nature of unput, we must work 52195376Sgibbs * backwards through the macro body performing 52295376Sgibbs * any expansions. 52395376Sgibbs */ 52495376Sgibbs body_head = macro_symbol->info.macroinfo->body; 52595376Sgibbs body_pos = body_head + strlen(body_head); 52695376Sgibbs while (body_pos > body_head) { 52795376Sgibbs next_match = body_head; 52895376Sgibbs match_marg = NULL; 52995376Sgibbs next_substitution(macro_symbol, body_pos, &next_match, 53095376Sgibbs &match_marg, &match); 53195376Sgibbs 53295376Sgibbs /* Put back everything up until the replacement. */ 53395376Sgibbs while (body_pos > next_match) 53495376Sgibbs unput(*--body_pos); 53595376Sgibbs 53695376Sgibbs /* Perform the replacement. */ 53795376Sgibbs if (match_marg != NULL) { 53895376Sgibbs const char *strp; 53995376Sgibbs 54095376Sgibbs next_match = match_marg->replacement_text; 54195376Sgibbs strp = next_match + strlen(next_match); 54295376Sgibbs while (strp > next_match) 54395376Sgibbs unput(*--strp); 54495376Sgibbs 54595376Sgibbs /* Skip past the unexpanded macro arg. */ 54695376Sgibbs body_pos -= match.rm_eo - match.rm_so; 54795376Sgibbs } 54895376Sgibbs } 54995376Sgibbs 55095376Sgibbs /* Cleanup replacement text. */ 55195376Sgibbs STAILQ_FOREACH(marg, ¯o_symbol->info.macroinfo->args, links) { 55295376Sgibbs free(marg->replacement_text); 55395376Sgibbs } 55495376Sgibbs} 55595376Sgibbs 55695376Sgibbs/* 55795376Sgibbs * Find the next substitution in the macro working backwards from 55895376Sgibbs * body_pos until the beginning of the macro buffer. next_match 55995376Sgibbs * should be initialized to the beginning of the macro buffer prior 56095376Sgibbs * to calling this routine. 56195376Sgibbs */ 56295376Sgibbsstatic void 56395376Sgibbsnext_substitution(struct symbol *mac_symbol, const char *body_pos, 56495376Sgibbs const char **next_match, struct macro_arg **match_marg, 56595376Sgibbs regmatch_t *match) 56695376Sgibbs{ 56795376Sgibbs regmatch_t matches[2]; 56895376Sgibbs struct macro_arg *marg; 56995376Sgibbs const char *search_pos; 57095376Sgibbs int retval; 57195376Sgibbs 57295376Sgibbs do { 57395376Sgibbs search_pos = *next_match; 57495376Sgibbs 57595376Sgibbs STAILQ_FOREACH(marg, &mac_symbol->info.macroinfo->args, links) { 57695376Sgibbs 57795376Sgibbs retval = regexec(&marg->arg_regex, search_pos, 2, 57895376Sgibbs matches, 0); 57995376Sgibbs if (retval == 0 58095376Sgibbs && (matches[1].rm_eo + search_pos) <= body_pos 58195376Sgibbs && (matches[1].rm_eo + search_pos) > *next_match) { 58295376Sgibbs *match = matches[1]; 58395376Sgibbs *next_match = match->rm_eo + search_pos; 58495376Sgibbs *match_marg = marg; 58595376Sgibbs } 58695376Sgibbs } 58795376Sgibbs } while (search_pos != *next_match); 58895376Sgibbs} 58995376Sgibbs 59023925Sgibbsint 591201261Sedyywrap(void) 59223925Sgibbs{ 59323925Sgibbs include_t *include; 59423925Sgibbs 59523925Sgibbs yy_delete_buffer(YY_CURRENT_BUFFER); 59623925Sgibbs (void)fclose(yyin); 59723925Sgibbs if (yyfilename != NULL) 59823925Sgibbs free(yyfilename); 59926997Sgibbs yyfilename = NULL; 60023925Sgibbs include = include_stack.slh_first; 60123925Sgibbs if (include != NULL) { 60223925Sgibbs yy_switch_to_buffer(include->buffer); 60323925Sgibbs yylineno = include->lineno; 60423925Sgibbs yyfilename = include->filename; 60523925Sgibbs SLIST_REMOVE_HEAD(&include_stack, links); 60623925Sgibbs free(include); 60723925Sgibbs return (0); 60823925Sgibbs } 60923925Sgibbs return (1); 61023925Sgibbs} 611