%{
/*
 * Lexical Analyzer for the Aic7xxx SCSI Host adapter sequencer assembler.
 *
 * Copyright (c) 1997, 1998, 2000 Justin T. Gibbs.
 * Copyright (c) 2001, 2002 Adaptec Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions, and the following disclaimer,
 *    without modification.
 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
 *    substantially similar to the "NO WARRANTY" disclaimer below
 *    ("Disclaimer") and any redistribution must be conditioned upon
 *    including a substantially similar Disclaimer requirement for further
 *    binary redistribution.
 * 3. Neither the names of the above-listed copyright holders nor the names
 *    of any contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * Alternatively, this software may be distributed under the terms of the
 * GNU General Public License ("GPL") version 2 as published by the Free
 * Software Foundation.
 *
 * NO WARRANTY
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGES.
 *
 * $Id: //depot/aic7xxx/aic7xxx/aicasm/aicasm_scan.l#20 $
 *
 * $FreeBSD$
 */

#include <sys/types.h>

#include <inttypes.h>
#include <limits.h>
#include <regex.h>
#include <stdio.h>
#include <string.h>
#include <sysexits.h>
#include "../queue.h"

#include "aicasm.h"
#include "aicasm_symbol.h"
#include "aicasm_gram.h"

/* This is used for macro body capture too, so err on the large size. */
#define MAX_STR_CONST 4096
static char string_buf[MAX_STR_CONST];
static char *string_buf_ptr;
static int  parren_count;
static int  quote_count;
static char buf[255];
%}

PATH		([/]*[-A-Za-z0-9_.])+
WORD		[A-Za-z_][-A-Za-z_0-9]*
SPACE		[ \t]+
MCARG		[^(), \t]+
MBODY		((\\[^\n])*[^\n\\]*)+

%x COMMENT
%x CEXPR
%x INCLUDE
%x STRING
%x MACRODEF
%x MACROARGLIST
%x MACROCALLARGS
%x MACROBODY

%%
\n			{ ++yylineno; }
\r			;
"/*"			{ BEGIN COMMENT;  /* Enter comment eating state */ }
<COMMENT>"/*"		{ fprintf(stderr, "Warning! Comment within comment."); }
<COMMENT>\n		{ ++yylineno; }
<COMMENT>[^*/\n]*	;
<COMMENT>"*"+[^*/\n]*	;
<COMMENT>"/"+[^*/\n]*	;
<COMMENT>"*"+"/"	{ BEGIN INITIAL; }
if[ \t]*\(		{
				string_buf_ptr = string_buf;
				parren_count = 1;
				BEGIN CEXPR;
				return T_IF;
			}
<CEXPR>\(		{	*string_buf_ptr++ = '('; parren_count++; }
<CEXPR>\)		{
				parren_count--;
				if (parren_count == 0) {
					/* All done */
					BEGIN INITIAL;
					*string_buf_ptr = '\0';
					yylval.sym = symtable_get(string_buf);
					return T_CEXPR;
				} else {
					*string_buf_ptr++ = ')';
				}
			}
<CEXPR>\n		{ ++yylineno; }
<CEXPR>\r		;
<CEXPR>[^()\n]+	{
				char *yptr;

				yptr = yytext;
				while (*yptr != '\0') {
					/* Remove duplicate spaces */
					if (*yptr == '\t')
						*yptr = ' ';
					if (*yptr == ' '
					 && string_buf_ptr != string_buf
					 && string_buf_ptr[-1] == ' ')
						yptr++;
					else 
						*string_buf_ptr++ = *yptr++;
				}
			}
else			{ return T_ELSE; }
VERSION			{ return T_VERSION; }
PREFIX			{ return T_PREFIX; }
PATCH_ARG_LIST		{ return T_PATCH_ARG_LIST; }
\"			{
				string_buf_ptr = string_buf;
				BEGIN STRING;
			}
<STRING>[^"]+		{
				char *yptr;

				yptr = yytext;
				while (*yptr)
					*string_buf_ptr++ = *yptr++;
			}
<STRING>\"		{
				/* All done */
				BEGIN INITIAL;
				*string_buf_ptr = '\0';
				yylval.str = string_buf;
				return T_STRING;
			}
{SPACE}			 ;

	/* Register/SCB/SRAM definition keywords */
export			{ return T_EXPORT; }
register		{ return T_REGISTER; }
const			{ yylval.value = FALSE; return T_CONST; }
download		{ return T_DOWNLOAD; }
address			{ return T_ADDRESS; }
count			{ return T_COUNT; }
access_mode		{ return T_ACCESS_MODE; }
dont_generate_debug_code { return T_DONT_GENERATE_DEBUG_CODE; }
modes			{ return T_MODES; }
RW|RO|WO		{
				 if (strcmp(yytext, "RW") == 0)
					yylval.value = RW;
				 else if (strcmp(yytext, "RO") == 0)
					yylval.value = RO;
				 else
					yylval.value = WO;
				 return T_MODE;
			}
field			{ return T_FIELD; }
enum			{ return T_ENUM; }
mask			{ return T_MASK; }
alias			{ return T_ALIAS; }
size			{ return T_SIZE; }
scb			{ return T_SCB; }
scratch_ram		{ return T_SRAM; }
accumulator		{ return T_ACCUM; }
mode_pointer		{ return T_MODE_PTR; }
allones			{ return T_ALLONES; }
allzeros		{ return T_ALLZEROS; }
none			{ return T_NONE; }
sindex			{ return T_SINDEX; }
A			{ return T_A; }

	/* Instruction Formatting */
PAD_PAGE		{ return T_PAD_PAGE; }
BEGIN_CRITICAL		{ return T_BEGIN_CS; }
END_CRITICAL		{ return T_END_CS; }
SET_SRC_MODE		{ return T_SET_SRC_MODE; }
SET_DST_MODE		{ return T_SET_DST_MODE; }

	/* Opcodes */
shl			{ return T_SHL; }
shr			{ return T_SHR; }
ror			{ return T_ROR; }
rol			{ return T_ROL; }
mvi			{ return T_MVI; }
mov			{ return T_MOV; }
clr			{ return T_CLR; }
jmp			{ return T_JMP; }
jc			{ return T_JC;	}
jnc			{ return T_JNC;	}
je			{ return T_JE;	}
jne			{ return T_JNE;	}
jz			{ return T_JZ;	}
jnz			{ return T_JNZ;	}
call			{ return T_CALL; }
add			{ return T_ADD; }
adc			{ return T_ADC; }
bmov			{ return T_BMOV; }
inc			{ return T_INC; }
dec			{ return T_DEC; }
stc			{ return T_STC;	}
clc			{ return T_CLC; }
cmp			{ return T_CMP;	}
not			{ return T_NOT;	}
xor			{ return T_XOR;	}
test			{ return T_TEST;}
and			{ return T_AND;	}
or			{ return T_OR;	}
ret			{ return T_RET; }
nop			{ return T_NOP; }

	/* ARP2 16bit extensions */
	/* or16			{ return T_OR16; } */
	/* and16			{ return T_AND16; }*/
	/* xor16			{ return T_XOR16; }*/
	/* add16			{ return T_ADD16; }*/
	/* adc16			{ return T_ADC16; }*/
	/* mvi16			{ return T_MVI16; }*/
	/* test16			{ return T_TEST16; }*/
	/* cmp16			{ return T_CMP16; }*/
	/* cmpxchg			{ return T_CMPXCHG; }*/

	/* Allowed Symbols */
\<\<			{ return T_EXPR_LSHIFT; }
\>\>			{ return T_EXPR_RSHIFT; }
[-+,:()~|&."{};<>[\]/*!=] { return yytext[0]; }

	/* Number processing */
0[0-7]*			{
				yylval.value = strtol(yytext, NULL, 8);
				return T_NUMBER;
			}

0[xX][0-9a-fA-F]+	{
				yylval.value = strtoul(yytext + 2, NULL, 16);
				return T_NUMBER;
			}

[1-9][0-9]*		{
				yylval.value = strtol(yytext, NULL, 10);
				return T_NUMBER;
			}
	/* Include Files */
#include{SPACE}		{
				BEGIN INCLUDE;
				quote_count = 0;
				return T_INCLUDE;
			}
<INCLUDE>[<]		{ return yytext[0]; }
<INCLUDE>[>]		{ BEGIN INITIAL; return yytext[0]; }
<INCLUDE>[\"]		{
				if (quote_count != 0)
					BEGIN INITIAL;
				quote_count++;
				return yytext[0];
			}
<INCLUDE>{PATH}		{
				char *yptr;

				yptr = yytext;
				string_buf_ptr = string_buf;
				while (*yptr)
					*string_buf_ptr++ = *yptr++;
				yylval.str = string_buf;
				*string_buf_ptr = '\0';
				return T_PATH;
			}
<INCLUDE>.		{ stop("Invalid include line", EX_DATAERR); }
#define{SPACE}		{
				BEGIN MACRODEF;
				return T_DEFINE;
			}
<MACRODEF>{WORD}{SPACE}	{ 
				char *yptr;

				/* Strip space and return as a normal symbol */
				yptr = yytext;
				while (*yptr != ' ' && *yptr != '\t')
					yptr++;
				*yptr = '\0';
				yylval.sym = symtable_get(yytext);
				string_buf_ptr = string_buf;
				BEGIN MACROBODY;
				return T_SYMBOL;
			}
<MACRODEF>{WORD}\(	{
				/*
				 * We store the symbol with its opening
				 * parren so we can differentiate macros
				 * that take args from macros with the
				 * same name that do not take args as
				 * is allowed in C.
				 */
				BEGIN MACROARGLIST;
				yylval.sym = symtable_get(yytext);
				unput('(');
				return T_SYMBOL;
			}
<MACROARGLIST>{WORD}	{
				yylval.str = yytext;
				return T_ARG;
			}
<MACROARGLIST>{SPACE}   ;
<MACROARGLIST>[(,]	{
				return yytext[0];
			}
<MACROARGLIST>[)]	{
				string_buf_ptr = string_buf;
				BEGIN MACROBODY;
				return ')';
			}
<MACROARGLIST>.		{
				snprintf(buf, sizeof(buf), "Invalid character "
					 "'%c' in macro argument list",
					 yytext[0]);
				stop(buf, EX_DATAERR);
			}
<MACROCALLARGS>{SPACE}  ;
<MACROCALLARGS>\(	{
				parren_count++;
				if (parren_count == 1)
					return ('(');
				*string_buf_ptr++ = '(';
			}
<MACROCALLARGS>\)	{
				parren_count--;
				if (parren_count == 0) {
					BEGIN INITIAL;
					return (')');
				}
				*string_buf_ptr++ = ')';
			}
<MACROCALLARGS>{MCARG}	{
				char *yptr;

				yptr = yytext;
				while (*yptr)
					*string_buf_ptr++ = *yptr++;
			}
<MACROCALLARGS>\,	{
				if (string_buf_ptr != string_buf) {
					/*
					 * Return an argument and
					 * rescan this comma so we
					 * can return it as well.
					 */
					*string_buf_ptr = '\0';
					yylval.str = string_buf;
					string_buf_ptr = string_buf;
					unput(',');
					return T_ARG;
				}
				return ',';
			}
<MACROBODY>\\\n		{
				/* Eat escaped newlines. */
				++yylineno;
			}
<MACROBODY>\r		;
<MACROBODY>\n		{
				/* Macros end on the first unescaped newline. */
				BEGIN INITIAL;
				*string_buf_ptr = '\0';
				yylval.str = string_buf;
				++yylineno;
				return T_MACROBODY;
			}
<MACROBODY>{MBODY}	{
				char *yptr;
				char c;

				yptr = yytext;
				while (c = *yptr++) {
					/*
					 * Strip carriage returns.
					 */
					if (c == '\r')
						continue;
					*string_buf_ptr++ = c;
				}
			}
{WORD}\(		{
				char *yptr;
				char *ycopy;

				/* May be a symbol or a macro invocation. */
				yylval.sym = symtable_get(yytext);
				if (yylval.sym->type == MACRO) {
					YY_BUFFER_STATE old_state;
					YY_BUFFER_STATE temp_state;

					ycopy = strdup(yytext);
					yptr = ycopy + yyleng;
					while (yptr > ycopy)
						unput(*--yptr);
					old_state = YY_CURRENT_BUFFER;
					temp_state =
					    yy_create_buffer(stdin,
							     YY_BUF_SIZE);
					yy_switch_to_buffer(temp_state);
					mm_switch_to_buffer(old_state);
					mmparse();
					mm_switch_to_buffer(temp_state);
					yy_switch_to_buffer(old_state);
					mm_delete_buffer(temp_state);
					expand_macro(yylval.sym);
				} else {
					if (yylval.sym->type == UNINITIALIZED) {
						/* Try without the '(' */
						symbol_delete(yylval.sym);
						yytext[yyleng-1] = '\0';
						yylval.sym =
						    symtable_get(yytext);
					}
					unput('(');
					return T_SYMBOL;
				}
			}
{WORD}			{
				yylval.sym = symtable_get(yytext);
				if (yylval.sym->type == MACRO) {
					expand_macro(yylval.sym);
				} else {
					return T_SYMBOL;
				}
			}
.			{ 
				snprintf(buf, sizeof(buf), "Invalid character "
					 "'%c'", yytext[0]);
				stop(buf, EX_DATAERR);
			}
%%

typedef struct include {
        YY_BUFFER_STATE  buffer;
        int              lineno;
        char            *filename;
	SLIST_ENTRY(include) links;
}include_t;

SLIST_HEAD(, include) include_stack;

void
include_file(char *file_name, include_type type)
{
	FILE *newfile;
	include_t *include;

	newfile = NULL;
	/* Try the current directory first */
	if (includes_search_curdir != 0 || type == SOURCE_FILE)
		newfile = fopen(file_name, "r");

	if (newfile == NULL && type != SOURCE_FILE) {
                path_entry_t include_dir;
                for (include_dir = search_path.slh_first;
                     include_dir != NULL;                
                     include_dir = include_dir->links.sle_next) {
			char fullname[PATH_MAX];

			if ((include_dir->quoted_includes_only == TRUE)
			 && (type != QUOTED_INCLUDE))
				continue;

			snprintf(fullname, sizeof(fullname),
				 "%s/%s", include_dir->directory, file_name);

			if ((newfile = fopen(fullname, "r")) != NULL)
				break;
                }
        }

	if (newfile == NULL) {
		perror(file_name);
		stop("Unable to open input file", EX_SOFTWARE);
		/* NOTREACHED */
	}

	if (type != SOURCE_FILE) {
		include = (include_t *)malloc(sizeof(include_t));
		if (include == NULL) {
			stop("Unable to allocate include stack entry",
			     EX_SOFTWARE);
			/* NOTREACHED */
		}
		include->buffer = YY_CURRENT_BUFFER;
		include->lineno = yylineno;
		include->filename = yyfilename;
		SLIST_INSERT_HEAD(&include_stack, include, links);
	}
	yy_switch_to_buffer(yy_create_buffer(newfile, YY_BUF_SIZE));
	yylineno = 1;
	yyfilename = strdup(file_name);
}

static void next_substitution(struct symbol *mac_symbol, const char *body_pos,
			      const char **next_match,
			      struct macro_arg **match_marg, regmatch_t *match);

void
expand_macro(struct symbol *macro_symbol)
{
	struct macro_arg *marg;
	struct macro_arg *match_marg;
	const char *body_head;
	const char *body_pos;
	const char *next_match;

	/*
	 * Due to the nature of unput, we must work
	 * backwards through the macro body performing
	 * any expansions.
	 */
	body_head = macro_symbol->info.macroinfo->body;
	body_pos = body_head + strlen(body_head);
	while (body_pos > body_head) {
		regmatch_t match;

		next_match = body_head;
		match_marg = NULL;
		next_substitution(macro_symbol, body_pos, &next_match,
				  &match_marg, &match);

		/* Put back everything up until the replacement. */
		while (body_pos > next_match)
			unput(*--body_pos);

		/* Perform the replacement. */
		if (match_marg != NULL) {
			const char *strp;

			next_match = match_marg->replacement_text;
			strp = next_match + strlen(next_match);
			while (strp > next_match)
				unput(*--strp);

			/* Skip past the unexpanded macro arg. */
			body_pos -= match.rm_eo - match.rm_so;
		}
	}

	/* Cleanup replacement text. */
	STAILQ_FOREACH(marg, &macro_symbol->info.macroinfo->args, links) {
		free(marg->replacement_text);
	}
}

/*
 * Find the next substitution in the macro working backwards from
 * body_pos until the beginning of the macro buffer.  next_match
 * should be initialized to the beginning of the macro buffer prior
 * to calling this routine.
 */
static void
next_substitution(struct symbol *mac_symbol, const char *body_pos,
		  const char **next_match, struct macro_arg **match_marg,
		  regmatch_t *match)
{
	regmatch_t	  matches[2];
	struct macro_arg *marg;
	const char	 *search_pos;
	int		  retval;

	do {
		search_pos = *next_match;

		STAILQ_FOREACH(marg, &mac_symbol->info.macroinfo->args, links) {

			retval = regexec(&marg->arg_regex, search_pos, 2,
					 matches, 0);
			if (retval == 0
			 && (matches[1].rm_eo + search_pos) <= body_pos
			 && (matches[1].rm_eo + search_pos) > *next_match) {
				*match = matches[1];
				*next_match = match->rm_eo + search_pos;
				*match_marg = marg;
			}
		}
	} while (search_pos != *next_match);
}

int
yywrap()
{
	include_t *include;

	yy_delete_buffer(YY_CURRENT_BUFFER);
	(void)fclose(yyin);
	if (yyfilename != NULL)
		free(yyfilename);
	yyfilename = NULL;
	include = include_stack.slh_first;
	if (include != NULL) {
		yy_switch_to_buffer(include->buffer);
		yylineno = include->lineno;
		yyfilename = include->filename;
		SLIST_REMOVE_HEAD(&include_stack, links);
		free(include);
		return (0);
	}
	return (1);
}
