18c2ecf20Sopenharmony_ci%{ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Sub-parser for macro invocation in the Aic7xxx SCSI 48c2ecf20Sopenharmony_ci * Host adapter sequencer assembler. 58c2ecf20Sopenharmony_ci * 68c2ecf20Sopenharmony_ci * Copyright (c) 2001 Adaptec Inc. 78c2ecf20Sopenharmony_ci * All rights reserved. 88c2ecf20Sopenharmony_ci * 98c2ecf20Sopenharmony_ci * Redistribution and use in source and binary forms, with or without 108c2ecf20Sopenharmony_ci * modification, are permitted provided that the following conditions 118c2ecf20Sopenharmony_ci * are met: 128c2ecf20Sopenharmony_ci * 1. Redistributions of source code must retain the above copyright 138c2ecf20Sopenharmony_ci * notice, this list of conditions, and the following disclaimer, 148c2ecf20Sopenharmony_ci * without modification. 158c2ecf20Sopenharmony_ci * 2. Redistributions in binary form must reproduce at minimum a disclaimer 168c2ecf20Sopenharmony_ci * substantially similar to the "NO WARRANTY" disclaimer below 178c2ecf20Sopenharmony_ci * ("Disclaimer") and any redistribution must be conditioned upon 188c2ecf20Sopenharmony_ci * including a substantially similar Disclaimer requirement for further 198c2ecf20Sopenharmony_ci * binary redistribution. 208c2ecf20Sopenharmony_ci * 3. Neither the names of the above-listed copyright holders nor the names 218c2ecf20Sopenharmony_ci * of any contributors may be used to endorse or promote products derived 228c2ecf20Sopenharmony_ci * from this software without specific prior written permission. 238c2ecf20Sopenharmony_ci * 248c2ecf20Sopenharmony_ci * Alternatively, this software may be distributed under the terms of the 258c2ecf20Sopenharmony_ci * GNU General Public License ("GPL") version 2 as published by the Free 268c2ecf20Sopenharmony_ci * Software Foundation. 278c2ecf20Sopenharmony_ci * 288c2ecf20Sopenharmony_ci * NO WARRANTY 298c2ecf20Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 308c2ecf20Sopenharmony_ci * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 318c2ecf20Sopenharmony_ci * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 328c2ecf20Sopenharmony_ci * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 338c2ecf20Sopenharmony_ci * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 348c2ecf20Sopenharmony_ci * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 358c2ecf20Sopenharmony_ci * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 368c2ecf20Sopenharmony_ci * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 378c2ecf20Sopenharmony_ci * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 388c2ecf20Sopenharmony_ci * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 398c2ecf20Sopenharmony_ci * POSSIBILITY OF SUCH DAMAGES. 408c2ecf20Sopenharmony_ci * 418c2ecf20Sopenharmony_ci * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_macro_gram.y#5 $ 428c2ecf20Sopenharmony_ci * 438c2ecf20Sopenharmony_ci * $FreeBSD$ 448c2ecf20Sopenharmony_ci */ 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci#include <sys/types.h> 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci#include <inttypes.h> 498c2ecf20Sopenharmony_ci#include <regex.h> 508c2ecf20Sopenharmony_ci#include <stdio.h> 518c2ecf20Sopenharmony_ci#include <stdlib.h> 528c2ecf20Sopenharmony_ci#include <string.h> 538c2ecf20Sopenharmony_ci#include <sysexits.h> 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci#include "../queue.h" 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ci#include "aicasm.h" 588c2ecf20Sopenharmony_ci#include "aicasm_symbol.h" 598c2ecf20Sopenharmony_ci#include "aicasm_insformat.h" 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_cistatic symbol_t *macro_symbol; 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_cistatic void add_macro_arg(const char *argtext, int position); 648c2ecf20Sopenharmony_civoid mmerror(const char *string); 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_ci%} 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci%union { 698c2ecf20Sopenharmony_ci int value; 708c2ecf20Sopenharmony_ci char *str; 718c2ecf20Sopenharmony_ci symbol_t *sym; 728c2ecf20Sopenharmony_ci} 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_ci%token <str> T_ARG 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_ci%token <sym> T_SYMBOL 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_ci%type <value> macro_arglist 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_ci%% 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_cimacrocall: 848c2ecf20Sopenharmony_ci T_SYMBOL '(' 858c2ecf20Sopenharmony_ci { 868c2ecf20Sopenharmony_ci macro_symbol = $1; 878c2ecf20Sopenharmony_ci } 888c2ecf20Sopenharmony_ci macro_arglist ')' 898c2ecf20Sopenharmony_ci { 908c2ecf20Sopenharmony_ci if (macro_symbol->info.macroinfo->narg != $4) { 918c2ecf20Sopenharmony_ci printf("Narg == %d", macro_symbol->info.macroinfo->narg); 928c2ecf20Sopenharmony_ci stop("Too few arguments for macro invocation", 938c2ecf20Sopenharmony_ci EX_DATAERR); 948c2ecf20Sopenharmony_ci /* NOTREACHED */ 958c2ecf20Sopenharmony_ci } 968c2ecf20Sopenharmony_ci macro_symbol = NULL; 978c2ecf20Sopenharmony_ci YYACCEPT; 988c2ecf20Sopenharmony_ci } 998c2ecf20Sopenharmony_ci; 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_cimacro_arglist: 1028c2ecf20Sopenharmony_ci { 1038c2ecf20Sopenharmony_ci /* Macros can take 0 arguments */ 1048c2ecf20Sopenharmony_ci $$ = 0; 1058c2ecf20Sopenharmony_ci } 1068c2ecf20Sopenharmony_ci| T_ARG 1078c2ecf20Sopenharmony_ci { 1088c2ecf20Sopenharmony_ci $$ = 1; 1098c2ecf20Sopenharmony_ci add_macro_arg($1, 1); 1108c2ecf20Sopenharmony_ci } 1118c2ecf20Sopenharmony_ci| macro_arglist ',' T_ARG 1128c2ecf20Sopenharmony_ci { 1138c2ecf20Sopenharmony_ci if ($1 == 0) { 1148c2ecf20Sopenharmony_ci stop("Comma without preceding argument in arg list", 1158c2ecf20Sopenharmony_ci EX_DATAERR); 1168c2ecf20Sopenharmony_ci /* NOTREACHED */ 1178c2ecf20Sopenharmony_ci } 1188c2ecf20Sopenharmony_ci $$ = $1 + 1; 1198c2ecf20Sopenharmony_ci add_macro_arg($3, $$); 1208c2ecf20Sopenharmony_ci } 1218c2ecf20Sopenharmony_ci; 1228c2ecf20Sopenharmony_ci 1238c2ecf20Sopenharmony_ci%% 1248c2ecf20Sopenharmony_ci 1258c2ecf20Sopenharmony_cistatic void 1268c2ecf20Sopenharmony_ciadd_macro_arg(const char *argtext, int argnum) 1278c2ecf20Sopenharmony_ci{ 1288c2ecf20Sopenharmony_ci struct macro_arg *marg; 1298c2ecf20Sopenharmony_ci int i; 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_ci if (macro_symbol == NULL || macro_symbol->type != MACRO) { 1328c2ecf20Sopenharmony_ci stop("Invalid current symbol for adding macro arg", 1338c2ecf20Sopenharmony_ci EX_SOFTWARE); 1348c2ecf20Sopenharmony_ci /* NOTREACHED */ 1358c2ecf20Sopenharmony_ci } 1368c2ecf20Sopenharmony_ci /* 1378c2ecf20Sopenharmony_ci * Macro Invocation. Find the appropriate argument and fill 1388c2ecf20Sopenharmony_ci * in the replace ment text for this call. 1398c2ecf20Sopenharmony_ci */ 1408c2ecf20Sopenharmony_ci i = 0; 1418c2ecf20Sopenharmony_ci STAILQ_FOREACH(marg, ¯o_symbol->info.macroinfo->args, links) { 1428c2ecf20Sopenharmony_ci i++; 1438c2ecf20Sopenharmony_ci if (i == argnum) 1448c2ecf20Sopenharmony_ci break; 1458c2ecf20Sopenharmony_ci } 1468c2ecf20Sopenharmony_ci if (marg == NULL) { 1478c2ecf20Sopenharmony_ci stop("Too many arguments for macro invocation", EX_DATAERR); 1488c2ecf20Sopenharmony_ci /* NOTREACHED */ 1498c2ecf20Sopenharmony_ci } 1508c2ecf20Sopenharmony_ci marg->replacement_text = strdup(argtext); 1518c2ecf20Sopenharmony_ci if (marg->replacement_text == NULL) { 1528c2ecf20Sopenharmony_ci stop("Unable to replicate replacement text", EX_SOFTWARE); 1538c2ecf20Sopenharmony_ci /* NOTREACHED */ 1548c2ecf20Sopenharmony_ci } 1558c2ecf20Sopenharmony_ci} 1568c2ecf20Sopenharmony_ci 1578c2ecf20Sopenharmony_civoid 1588c2ecf20Sopenharmony_cimmerror(const char *string) 1598c2ecf20Sopenharmony_ci{ 1608c2ecf20Sopenharmony_ci stop(string, EX_DATAERR); 1618c2ecf20Sopenharmony_ci} 162