/*
 * Copyright 1998 Bertho A. Stultiens (BS)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "config.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

#include "wrc.h"
#include "utils.h"
#include "preproc.h"


#define HASHKEY		2039
static pp_entry_t *pp_defines[HASHKEY];

#define MAXIFSTACK	64
static if_state_t if_stack[MAXIFSTACK];
static int if_stack_idx = 0;

#if 0
void pp_status(void) __attribute__((destructor));
void pp_status(void)
{
	int i;
	int sum;
	int total = 0;
	pp_entry_t *ppp;

	fprintf(stderr, "Defines statistics:\n");
	for(i = 0; i < HASHKEY; i++)
	{
		sum = 0;
		for(ppp = pp_defines[i]; ppp; ppp = ppp->next)
			sum++;
		total += sum;
		fprintf(stderr, "%4d, %3d\n", i, sum);
	}
	fprintf(stderr, "Total defines: %d\n", total);
}
#endif

/* Don't comment on the hash, its primitive but functional... */
int pphash(char *str)
{
	int sum = 0;
	while(*str)
		sum += *str++;
	return sum % HASHKEY;
}

pp_entry_t *pplookup(char *ident)
{
	int idx = pphash(ident);
	pp_entry_t *ppp;

	for(ppp = pp_defines[idx]; ppp; ppp = ppp->next)
	{
		if(!strcmp(ident, ppp->ident))
			return ppp;
	}
	return NULL;
}

void del_define(char *name)
{
	int idx;
	pp_entry_t *ppp;

	if((ppp = pplookup(name)) == NULL)
	{
		if(pedantic)
			yywarning("%s was not defined", name);
		return;
	}

	if(ppp->iep)
	{
		if(debuglevel & DEBUGLEVEL_PPMSG)
			fprintf(stderr, "del_define: %s:%d: includelogic removed, include_ppp='%s', file=%s\n", input_name, line_number, name, ppp->iep->filename);
		if(ppp->iep == includelogiclist)
		{
			includelogiclist = ppp->iep->next;
			if(includelogiclist)
				includelogiclist->prev = NULL;
		}
		else
		{
			ppp->iep->prev->next = ppp->iep->next;
			if(ppp->iep->next)
				ppp->iep->next->prev = ppp->iep->prev;
		}
		free(ppp->iep->filename);
		free(ppp->iep);
	}

	idx = pphash(name);
	if(pp_defines[idx] == ppp)
	{
		pp_defines[idx] = ppp->next;
		if(pp_defines[idx])
			pp_defines[idx]->prev = NULL;
	}
	else
	{
		ppp->prev->next = ppp->next;
		if(ppp->next)
			ppp->next->prev = ppp->prev;
	}

	free(ppp);

	if(debuglevel & DEBUGLEVEL_PPMSG)
		printf("Deleted (%s, %d) <%s>\n", input_name, line_number, name);
}

pp_entry_t *add_define(char *def, char *text)
{
	int len;
	char *cptr;
	int idx = pphash(def);
	pp_entry_t *ppp;

	if((ppp = pplookup(def)) != NULL)
	{
		if(pedantic)
			yywarning("Redefinition of %s\n\tPrevious definition: %s:%d", def, ppp->filename, ppp->linenumber);
		del_define(def);
	}
	ppp = (pp_entry_t *)xmalloc(sizeof(pp_entry_t));
	ppp->ident = def;
	ppp->type = def_define;
	ppp->subst.text = text;
	ppp->filename = input_name ? xstrdup(input_name) : "<internal or cmdline>";
	ppp->linenumber = input_name ? line_number : 0;
	ppp->next = pp_defines[idx];
	pp_defines[idx] = ppp;
	if(ppp->next)
		ppp->next->prev = ppp;
	if(text)
	{
		/* Strip trailing white space from subst text */
		len = strlen(text);
		while(len && strchr(" \t\r\n", text[len-1]))
		{
			text[--len] = '\0';
		}
		/* Strip leading white space from subst text */
		for(cptr = text; *cptr && strchr(" \t\r", *cptr); cptr++)
		;
		if(text != cptr)
			memmove(text, cptr, strlen(cptr)+1);
	}
	if(debuglevel & DEBUGLEVEL_PPMSG)
		printf("Added define (%s, %d) <%s> to <%s>\n", input_name, line_number, ppp->ident, text ? text : "(null)");

	return ppp;
}

pp_entry_t *add_cmdline_define(char *set)
{
	char *cpy = xstrdup(set);	/* Because gcc passes a R/O string */
	char *cptr = strchr(cpy, '=');
	if(cptr)
		*cptr = '\0';
	return add_define(cpy, xstrdup(cptr ? cptr+1 : ""));
}

pp_entry_t *add_special_define(char *id)
{
	pp_entry_t *ppp = add_define(xstrdup(id), xstrdup(""));
	ppp->type = def_special;
	return ppp;
}

pp_entry_t *add_macro(char *id, marg_t *args[], int nargs, mtext_t *exp)
{
	int idx = pphash(id);
	pp_entry_t *ppp;

	if((ppp = pplookup(id)) != NULL)
	{
		if(pedantic)
			yywarning("Redefinition of %s\n\tPrevious definition: %s:%d", id, ppp->filename, ppp->linenumber);
		del_define(id);
	}
	ppp = (pp_entry_t *)xmalloc(sizeof(pp_entry_t));
	ppp->ident	= id;
	ppp->type	= def_macro;
	ppp->margs	= args;
	ppp->nargs	= nargs;
	ppp->subst.mtext= exp;
	ppp->filename = input_name ? xstrdup(input_name) : "<internal or cmdline>";
	ppp->linenumber = input_name ? line_number : 0;
	ppp->next	= pp_defines[idx];
	pp_defines[idx] = ppp;
	if(ppp->next)
		ppp->next->prev = ppp;

	if(debuglevel & DEBUGLEVEL_PPMSG)
	{
		fprintf(stderr, "Added macro (%s, %d) <%s(%d)> to <", input_name, line_number, ppp->ident, nargs);
		for(; exp; exp = exp->next)
		{
			switch(exp->type)
			{
			case exp_text:
				fprintf(stderr, " \"%s\" ", exp->subst.text);
				break;
			case exp_stringize:
				fprintf(stderr, " #(%d) ", exp->subst.argidx);
				break;
			case exp_concat:
				fprintf(stderr, "##");
				break;
			case exp_subst:
				fprintf(stderr, " <%d> ", exp->subst.argidx);
				break;
			}
		}
		fprintf(stderr, ">\n");
	}
	return ppp;
}


/*
 *-------------------------------------------------------------------------
 * Include management
 *-------------------------------------------------------------------------
 */
#if defined(_Windows) || defined(__MSDOS__)
#define INCLUDESEPARATOR	";"
#else
#define INCLUDESEPARATOR	":"
#endif

static char **includepath;
static int nincludepath = 0;

void add_include_path(char *path)
{
	char *tok;
	char *cpy = xstrdup(path);

	tok = strtok(cpy, INCLUDESEPARATOR);
	while(tok)
	{
		char *dir;
		char *cptr;
		if(strlen(tok) == 0)
			continue;
		dir = xstrdup(tok);
		for(cptr = dir; *cptr; cptr++)
		{
			/* Convert to forward slash */
			if(*cptr == '\\')
				*cptr = '/';
		}
		/* Kill eventual trailing '/' */
		if(*(cptr = dir + strlen(dir)-1) == '/')
			*cptr = '\0';

		/* Add to list */
		nincludepath++;
		includepath = (char **)xrealloc(includepath, nincludepath * sizeof(*includepath));
		includepath[nincludepath-1] = dir;
		tok = strtok(NULL, INCLUDESEPARATOR);
	}
	free(cpy);
}

FILE *open_include(const char *name, int search, char **newpath)
{
	char *cpy = xstrdup(name);
	char *cptr;
	FILE *fp;
	int i;

	for(cptr = cpy; *cptr; cptr++)
	{
		/* kill double backslash */
		if(*cptr == '\\' && *(cptr+1) == '\\')
			memmove(cptr, cptr+1, strlen(cptr));
		/* Convert to forward slash */
		if(*cptr == '\\')
			*cptr = '/';
	}

	if(search)
	{
		/* Search current dir and then -I path */
		fp = fopen(cpy, "rt");
		if(fp)
		{
			if(debuglevel & DEBUGLEVEL_PPMSG)
				printf("Going to include <%s>\n", name);
			if(newpath)
				*newpath = cpy;
			else
				free(cpy);
			return fp;
		}
	}
	/* Search -I path */
	for(i = 0; i < nincludepath; i++)
	{
		char *path;
		path = (char *)xmalloc(strlen(includepath[i]) + strlen(cpy) + 2);
		strcpy(path, includepath[i]);
		strcat(path, "/");
		strcat(path, cpy);
		fp = fopen(path, "rt");
		if(fp && (debuglevel & DEBUGLEVEL_PPMSG))
			printf("Going to include <%s>\n", path);
		if(fp)
		{
			if(newpath)
				*newpath = path;
			else
				free(path);
			free(cpy);
			return fp;
		}
		free(path);
	}
	free(cpy);
	if(newpath)
		*newpath = NULL;
	return NULL;
}

/*
 *-------------------------------------------------------------------------
 * #if, #ifdef, #ifndef, #else, #elif and #endif state management
 *
 * #if state transitions are made on basis of the current TOS and the next
 * required state. The state transitions are required to housekeep because
 * #if:s can be nested. The ignore case is activated to prevent output from
 * within a false clause.
 * Some special cases come from the fact that the #elif cases are not
 * binary, but three-state. The problem is that all other elif-cases must
 * be false when one true one has been found. A second problem is that the
 * #else clause is a final clause. No extra #else:s may follow.
 *
 * The states mean:
 * if_true	Process input to output
 * if_false	Process input but no output
 * if_ignore	Process input but no output
 * if_elif	Process input but no output
 * if_elsefalse	Process input but no output
 * if_elsettrue	Process input to output
 *
 * The possible state-sequences are [state(stack depth)] (rest can be deduced):
 *	TOS		#if 1		#else			#endif
 *	if_true(n)	if_true(n+1)	if_elsefalse(n+1)
 *	if_false(n)	if_ignore(n+1)	if_ignore(n+1)
 *	if_elsetrue(n)	if_true(n+1)	if_elsefalse(n+1)
 *	if_elsefalse(n)	if_ignore(n+1)	if_ignore(n+1)
 *	if_elif(n)	if_ignore(n+1)	if_ignore(n+1)
 *	if_ignore(n)	if_ignore(n+1)	if_ignore(n+1)
 *
 *	TOS		#if 1		#elif 0		#else		#endif
 *	if_true(n)	if_true(n+1)	if_elif(n+1)	if_elif(n+1)
 *	if_false(n)	if_ignore(n+1)	if_ignore(n+1)	if_ignore(n+1)
 *	if_elsetrue(n)	if_true(n+1)	if_elif(n+1)	if_elif(n+1)
 *	if_elsefalse(n)	if_ignore(n+1)	if_ignore(n+1)	if_ignore(n+1)
 *	if_elif(n)	if_ignore(n+1)	if_ignore(n+1)	if_ignore(n+1)
 *	if_ignore(n)	if_ignore(n+1)	if_ignore(n+1)	if_ignore(n+1)
 *
 *	TOS		#if 0		#elif 1		#else		#endif
 *	if_true(n)	if_false(n+1)	if_true(n+1)	if_elsefalse(n+1)
 *	if_false(n)	if_ignore(n+1)	if_ignore(n+1)	if_ignore(n+1)
 *	if_elsetrue(n)	if_false(n+1)	if_true(n+1)	if_elsefalse(n+1)
 *	if_elsefalse(n)	if_ignore(n+1)	if_ignore(n+1)	if_ignore(n+1)
 *	if_elif(n)	if_ignore(n+1)	if_ignore(n+1)	if_ignore(n+1)
 *	if_ignore(n)	if_ignore(n+1)	if_ignore(n+1)	if_ignore(n+1)
 *
 *-------------------------------------------------------------------------
 */
static char *if_state_str[] = {
	"if_false",
	"if_true",
	"if_elif",
	"if_elsefalse",
	"if_elsetrue",
	"if_ignore"
};

void push_if(if_state_t s)
{
	if(if_stack_idx >= MAXIFSTACK)
		internal_error(__FILE__, __LINE__, "#if-stack overflow; #{if,ifdef,ifndef} nested too deeply (> %d)", MAXIFSTACK);

	if(debuglevel & DEBUGLEVEL_PPLEX)
		fprintf(stderr, "Push if %s:%d: %s(%d) -> %s(%d)\n", input_name, line_number, if_state_str[if_state()], if_stack_idx, if_state_str[s], if_stack_idx+1);

	if_stack[if_stack_idx++] = s;

	switch(s)
	{
	case if_true:
	case if_elsetrue:
		break;
	case if_false:
	case if_elsefalse:
	case if_elif:
	case if_ignore:
		push_ignore_state();
		break;
	}
}

if_state_t pop_if(void)
{
	if(if_stack_idx <= 0)
		yyerror("#{endif,else,elif} without #{if,ifdef,ifndef} (#if-stack underflow)");

	switch(if_state())
	{
	case if_true:
	case if_elsetrue:
		break;
	case if_false:
	case if_elsefalse:
	case if_elif:
	case if_ignore:
		pop_ignore_state();
		break;
	}

	if(debuglevel & DEBUGLEVEL_PPLEX)
		fprintf(stderr, "Pop if %s:%d: %s(%d) -> %s(%d)\n",
				input_name,
				line_number,
				if_state_str[if_state()],
				if_stack_idx,
				if_state_str[if_stack[if_stack_idx <= 1 ? if_true : if_stack_idx-2]],
				if_stack_idx-1);

	return if_stack[--if_stack_idx];
}

if_state_t if_state(void)
{
	if(!if_stack_idx)
		return if_true;
	else
		return if_stack[if_stack_idx-1];
}


void next_if_state(int i)
{
	switch(if_state())
	{
	case if_true:
	case if_elsetrue:
		push_if(i ? if_true : if_false);
		break;
	case if_false:
	case if_elsefalse:
	case if_elif:
	case if_ignore:
		push_if(if_ignore);
		break;
	default:
		internal_error(__FILE__, __LINE__, "Invalid if_state (%d) in #{if,ifdef,ifndef} directive", (int)if_state());
	}
}

int get_if_depth(void)
{
	return if_stack_idx;
}

