1 %{ 2 /*- 3 * Sub-parser for macro invocation in the Aic7xxx SCSI 4 * Host adapter sequencer assembler. 5 * 6 * Copyright (c) 2001 Adaptec Inc. 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions, and the following disclaimer, 14 * without modification. 15 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 16 * substantially similar to the "NO WARRANTY" disclaimer below 17 * ("Disclaimer") and any redistribution must be conditioned upon 18 * including a substantially similar Disclaimer requirement for further 19 * binary redistribution. 20 * 3. Neither the names of the above-listed copyright holders nor the names 21 * of any contributors may be used to endorse or promote products derived 22 * from this software without specific prior written permission. 23 * 24 * Alternatively, this software may be distributed under the terms of the 25 * GNU General Public License ("GPL") version 2 as published by the Free 26 * Software Foundation. 27 * 28 * NO WARRANTY 29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 30 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 31 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 32 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 33 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR 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, 37 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 38 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 39 * POSSIBILITY OF SUCH DAMAGES. 40 * 41 * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_macro_gram.y#5 $ 42 * 43 * $FreeBSD$ 44 */ 45 46 #include <sys/types.h> 47 48 #include <inttypes.h> 49 #include <regex.h> 50 #include <stdio.h> 51 #include <stdlib.h> 52 #include <string.h> 53 #include <sysexits.h> 54 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_insformat.h" 64 65 static symbol_t *macro_symbol; 66 67 static void add_macro_arg(const char *argtext, int position); 68 69 extern int mmlex(void); 70 extern int mmparse(void); 71 72 %} 73 74 %union { 75 int value; 76 char *str; 77 symbol_t *sym; 78 } 79 80 81 %token <str> T_ARG 82 83 %token <sym> T_SYMBOL 84 85 %type <value> macro_arglist 86 87 %% 88 89 macrocall: 90 T_SYMBOL '(' 91 { 92 macro_symbol = $1; 93 } 94 macro_arglist ')' 95 { 96 if (macro_symbol->info.macroinfo->narg != $4) { 97 printf("Narg == %d", macro_symbol->info.macroinfo->narg); 98 stop("Too few arguments for macro invocation", 99 EX_DATAERR); 100 /* NOTREACHED */ 101 } 102 macro_symbol = NULL; 103 YYACCEPT; 104 } 105 ; 106 107 macro_arglist: 108 { 109 /* Macros can take 0 arguments */ 110 $$ = 0; 111 } 112 | T_ARG 113 { 114 $$ = 1; 115 add_macro_arg($1, 1); 116 } 117 | macro_arglist ',' T_ARG 118 { 119 if ($1 == 0) { 120 stop("Comma without preceding argument in arg list", 121 EX_DATAERR); 122 /* NOTREACHED */ 123 } 124 $$ = $1 + 1; 125 add_macro_arg($3, $$); 126 } 127 ; 128 129 %% 130 131 static void 132 add_macro_arg(const char *argtext, int argnum) 133 { 134 struct macro_arg *marg; 135 int i; 136 137 if (macro_symbol == NULL || macro_symbol->type != MACRO) { 138 stop("Invalid current symbol for adding macro arg", 139 EX_SOFTWARE); 140 /* NOTREACHED */ 141 } 142 /* 143 * Macro Invocation. Find the appropriate argument and fill 144 * in the replace ment text for this call. 145 */ 146 i = 0; 147 STAILQ_FOREACH(marg, ¯o_symbol->info.macroinfo->args, links) { 148 i++; 149 if (i == argnum) 150 break; 151 } 152 if (marg == NULL) { 153 stop("Too many arguments for macro invocation", EX_DATAERR); 154 /* NOTREACHED */ 155 } 156 marg->replacement_text = strdup(argtext); 157 if (marg->replacement_text == NULL) { 158 stop("Unable to replicate replacement text", EX_SOFTWARE); 159 /* NOTREACHED */ 160 } 161 } 162 163 static void 164 mmerror(const char *string) 165 { 166 stop(string, EX_DATAERR); 167 } 168