162306a36Sopenharmony_ci%{ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Sub-parser for macro invocation in the Aic7xxx SCSI 462306a36Sopenharmony_ci * Host adapter sequencer assembler. 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci * Copyright (c) 2001 Adaptec Inc. 762306a36Sopenharmony_ci * All rights reserved. 862306a36Sopenharmony_ci * 962306a36Sopenharmony_ci * Redistribution and use in source and binary forms, with or without 1062306a36Sopenharmony_ci * modification, are permitted provided that the following conditions 1162306a36Sopenharmony_ci * are met: 1262306a36Sopenharmony_ci * 1. Redistributions of source code must retain the above copyright 1362306a36Sopenharmony_ci * notice, this list of conditions, and the following disclaimer, 1462306a36Sopenharmony_ci * without modification. 1562306a36Sopenharmony_ci * 2. Redistributions in binary form must reproduce at minimum a disclaimer 1662306a36Sopenharmony_ci * substantially similar to the "NO WARRANTY" disclaimer below 1762306a36Sopenharmony_ci * ("Disclaimer") and any redistribution must be conditioned upon 1862306a36Sopenharmony_ci * including a substantially similar Disclaimer requirement for further 1962306a36Sopenharmony_ci * binary redistribution. 2062306a36Sopenharmony_ci * 3. Neither the names of the above-listed copyright holders nor the names 2162306a36Sopenharmony_ci * of any contributors may be used to endorse or promote products derived 2262306a36Sopenharmony_ci * from this software without specific prior written permission. 2362306a36Sopenharmony_ci * 2462306a36Sopenharmony_ci * Alternatively, this software may be distributed under the terms of the 2562306a36Sopenharmony_ci * GNU General Public License ("GPL") version 2 as published by the Free 2662306a36Sopenharmony_ci * Software Foundation. 2762306a36Sopenharmony_ci * 2862306a36Sopenharmony_ci * NO WARRANTY 2962306a36Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 3062306a36Sopenharmony_ci * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3162306a36Sopenharmony_ci * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 3262306a36Sopenharmony_ci * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3362306a36Sopenharmony_ci * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3462306a36Sopenharmony_ci * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3562306a36Sopenharmony_ci * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3662306a36Sopenharmony_ci * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 3762306a36Sopenharmony_ci * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 3862306a36Sopenharmony_ci * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 3962306a36Sopenharmony_ci * POSSIBILITY OF SUCH DAMAGES. 4062306a36Sopenharmony_ci * 4162306a36Sopenharmony_ci * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_macro_gram.y#5 $ 4262306a36Sopenharmony_ci * 4362306a36Sopenharmony_ci * $FreeBSD$ 4462306a36Sopenharmony_ci */ 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci#include <sys/types.h> 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci#include <inttypes.h> 4962306a36Sopenharmony_ci#include <regex.h> 5062306a36Sopenharmony_ci#include <stdio.h> 5162306a36Sopenharmony_ci#include <stdlib.h> 5262306a36Sopenharmony_ci#include <string.h> 5362306a36Sopenharmony_ci#include <sysexits.h> 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_ci#include "../queue.h" 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci#include "aicasm.h" 5862306a36Sopenharmony_ci#include "aicasm_symbol.h" 5962306a36Sopenharmony_ci#include "aicasm_insformat.h" 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_cistatic symbol_t *macro_symbol; 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_cistatic void add_macro_arg(const char *argtext, int position); 6462306a36Sopenharmony_civoid mmerror(const char *string); 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci%} 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_ci%union { 6962306a36Sopenharmony_ci int value; 7062306a36Sopenharmony_ci char *str; 7162306a36Sopenharmony_ci symbol_t *sym; 7262306a36Sopenharmony_ci} 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ci%token <str> T_ARG 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ci%token <sym> T_SYMBOL 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci%type <value> macro_arglist 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_ci%% 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_cimacrocall: 8462306a36Sopenharmony_ci T_SYMBOL '(' 8562306a36Sopenharmony_ci { 8662306a36Sopenharmony_ci macro_symbol = $1; 8762306a36Sopenharmony_ci } 8862306a36Sopenharmony_ci macro_arglist ')' 8962306a36Sopenharmony_ci { 9062306a36Sopenharmony_ci if (macro_symbol->info.macroinfo->narg != $4) { 9162306a36Sopenharmony_ci printf("Narg == %d", macro_symbol->info.macroinfo->narg); 9262306a36Sopenharmony_ci stop("Too few arguments for macro invocation", 9362306a36Sopenharmony_ci EX_DATAERR); 9462306a36Sopenharmony_ci /* NOTREACHED */ 9562306a36Sopenharmony_ci } 9662306a36Sopenharmony_ci macro_symbol = NULL; 9762306a36Sopenharmony_ci YYACCEPT; 9862306a36Sopenharmony_ci } 9962306a36Sopenharmony_ci; 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_cimacro_arglist: 10262306a36Sopenharmony_ci { 10362306a36Sopenharmony_ci /* Macros can take 0 arguments */ 10462306a36Sopenharmony_ci $$ = 0; 10562306a36Sopenharmony_ci } 10662306a36Sopenharmony_ci| T_ARG 10762306a36Sopenharmony_ci { 10862306a36Sopenharmony_ci $$ = 1; 10962306a36Sopenharmony_ci add_macro_arg($1, 1); 11062306a36Sopenharmony_ci } 11162306a36Sopenharmony_ci| macro_arglist ',' T_ARG 11262306a36Sopenharmony_ci { 11362306a36Sopenharmony_ci if ($1 == 0) { 11462306a36Sopenharmony_ci stop("Comma without preceding argument in arg list", 11562306a36Sopenharmony_ci EX_DATAERR); 11662306a36Sopenharmony_ci /* NOTREACHED */ 11762306a36Sopenharmony_ci } 11862306a36Sopenharmony_ci $$ = $1 + 1; 11962306a36Sopenharmony_ci add_macro_arg($3, $$); 12062306a36Sopenharmony_ci } 12162306a36Sopenharmony_ci; 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_ci%% 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_cistatic void 12662306a36Sopenharmony_ciadd_macro_arg(const char *argtext, int argnum) 12762306a36Sopenharmony_ci{ 12862306a36Sopenharmony_ci struct macro_arg *marg; 12962306a36Sopenharmony_ci int i; 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_ci if (macro_symbol == NULL || macro_symbol->type != MACRO) { 13262306a36Sopenharmony_ci stop("Invalid current symbol for adding macro arg", 13362306a36Sopenharmony_ci EX_SOFTWARE); 13462306a36Sopenharmony_ci /* NOTREACHED */ 13562306a36Sopenharmony_ci } 13662306a36Sopenharmony_ci /* 13762306a36Sopenharmony_ci * Macro Invocation. Find the appropriate argument and fill 13862306a36Sopenharmony_ci * in the replace ment text for this call. 13962306a36Sopenharmony_ci */ 14062306a36Sopenharmony_ci i = 0; 14162306a36Sopenharmony_ci STAILQ_FOREACH(marg, ¯o_symbol->info.macroinfo->args, links) { 14262306a36Sopenharmony_ci i++; 14362306a36Sopenharmony_ci if (i == argnum) 14462306a36Sopenharmony_ci break; 14562306a36Sopenharmony_ci } 14662306a36Sopenharmony_ci if (marg == NULL) { 14762306a36Sopenharmony_ci stop("Too many arguments for macro invocation", EX_DATAERR); 14862306a36Sopenharmony_ci /* NOTREACHED */ 14962306a36Sopenharmony_ci } 15062306a36Sopenharmony_ci marg->replacement_text = strdup(argtext); 15162306a36Sopenharmony_ci if (marg->replacement_text == NULL) { 15262306a36Sopenharmony_ci stop("Unable to replicate replacement text", EX_SOFTWARE); 15362306a36Sopenharmony_ci /* NOTREACHED */ 15462306a36Sopenharmony_ci } 15562306a36Sopenharmony_ci} 15662306a36Sopenharmony_ci 15762306a36Sopenharmony_civoid 15862306a36Sopenharmony_cimmerror(const char *string) 15962306a36Sopenharmony_ci{ 16062306a36Sopenharmony_ci stop(string, EX_DATAERR); 16162306a36Sopenharmony_ci} 162