/* $XConsortium: parse.c,v 1.30 94/04/17 20:10:38 gildea Exp $ */
/*

Copyright (c) 1993, 1994  X Consortium

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Except as contained in this notice, the name of the X Consortium shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from the X Consortium.

*/

#include "def.h"
char *hash_lookup( char *symbol, struct symhash *symbols );
void hash_undefine( char *symbol, struct symhash *symbols );
int gobble( register struct filepointer *filep, struct inclist *file,
    struct inclist *file_red, struct symhash *symbols );
int deftype ( register char *line, register struct filepointer *filep,
    register struct inclist *file_red, register struct inclist *file,
    int parse_it, struct symhash *symbols);
int zero_value(register char *exp, register struct filepointer *filep,
    register struct inclist *file_red, register struct symhash *symbols);

extern char	*directives[];
extern struct symhash *maininclist;

int find_includes(filep, file, file_red, recursion, failOK, incCollection, symbols)
	struct filepointer	*filep;
	struct inclist		*file, *file_red;
	int			recursion;
	boolean			failOK;
    struct IncludesCollection* incCollection; 
	struct symhash		*symbols;
{
	register char	*line;
	register int	type;
	boolean recfailOK;

	while ((line = get_line(filep))) {
		switch(type = deftype(line, filep, file_red, file, TRUE, symbols)) {
		case IF:
		doif:
			type = find_includes(filep, file,
				file_red, recursion+1, failOK, incCollection, symbols);
			while ((type == ELIF) || (type == ELIFFALSE) ||
			       (type == ELIFGUESSFALSE))
				type = gobble(filep, file, file_red, symbols);
			if (type == ELSE)
				gobble(filep, file, file_red, symbols);
			break;
		case IFFALSE:
		case IFGUESSFALSE:
		    doiffalse:
			if (type == IFGUESSFALSE || type == ELIFGUESSFALSE)
			    recfailOK = TRUE;
			else
			    recfailOK = failOK;
			type = gobble(filep, file, file_red, symbols);
			if (type == ELSE)
			    find_includes(filep, file,
					  file_red, recursion+1, recfailOK, incCollection, symbols);
			else
			if (type == ELIF)
			    goto doif;
			else
			if ((type == ELIFFALSE) || (type == ELIFGUESSFALSE))
			    goto doiffalse;
			break;
		case IFDEF:
		case IFNDEF:
			if ((type == IFDEF && hash_lookup(line, symbols))
			 || (type == IFNDEF && !hash_lookup(line, symbols))) {
				debug(1,(type == IFNDEF ?
				    "line %d: %s !def'd in %s via %s%s\n" : "",
				    filep->f_line, line,
				    file->i_file, file_red->i_file, ": doit"));
				type = find_includes(filep, file,
					file_red, recursion+1, failOK, incCollection, symbols);
				while (type == ELIF || type == ELIFFALSE || type == ELIFGUESSFALSE)
					type = gobble(filep, file, file_red, symbols);
				if (type == ELSE)
					gobble(filep, file, file_red, symbols);
			}
			else {
				debug(1,(type == IFDEF ?
				    "line %d: %s !def'd in %s via %s%s\n" : "",
				    filep->f_line, line,
				    file->i_file, file_red->i_file, ": gobble"));
				type = gobble(filep, file, file_red, symbols);
				if (type == ELSE)
					find_includes(filep, file,
						file_red, recursion + 1, failOK, incCollection, symbols);
				else if (type == ELIF)
				    	goto doif;
				else if (type == ELIFFALSE || type == ELIFGUESSFALSE)
				    	goto doiffalse;
			}
			break;
		case ELSE:
		case ELIFFALSE:
		case ELIFGUESSFALSE:
		case ELIF:
			if (!recursion)
				gobble(filep, file, file_red, symbols);
		case ENDIF:
			if (recursion)
				return(type);
		case DEFINE:
			define(line, &symbols);
			break;
		case UNDEF:
			if (!*line) {
			    warning("%s, line %d: incomplete undef == \"%s\"\n",
				file_red->i_file, filep->f_line, line);
			    break;
			}
			hash_undefine(line, symbols);
			break;
		case INCLUDE:
			add_include(filep, file, file_red, line, FALSE, failOK, incCollection, symbols);
			break;
		case INCLUDEDOT:
			add_include(filep, file, file_red, line, TRUE, failOK, incCollection, symbols);
			break;
		case ERROR:
		    	warning("%s: %d: %s\n", file_red->i_file,
				 filep->f_line, line);
		    	break;
		    
		case PRAGMA:
		case IDENT:
		case SCCS:
		case EJECT:
			break;
		case -1:
			warning("%s", file_red->i_file);
			if (file_red != file)
			    warning1(" (reading %s)", file->i_file);
			warning1(", line %d: unknown directive == \"%s\"\n",
				 filep->f_line, line);
			break;
		case -2:
			warning("%s", file_red->i_file);
			if (file_red != file)
			    warning1(" (reading %s)", file->i_file);
			warning1(", line %d: incomplete include == \"%s\"\n",
				 filep->f_line, line);
			break;
		}
	}
	return(-1);
}

int gobble(filep, file, file_red, symbols)
	register struct filepointer *filep;
	struct inclist		*file, *file_red;
	struct symhash		*symbols;
{
	register char	*line;
	register int	type;

	while ((line = get_line(filep))) {
		switch(type = deftype(line, filep, file_red, file, FALSE, symbols)) {
		case IF:
		case IFFALSE:
		case IFGUESSFALSE:
		case IFDEF:
		case IFNDEF:
			type = gobble(filep, file, file_red, symbols);
			while ((type == ELIF) || (type == ELIFFALSE) ||
			       (type == ELIFGUESSFALSE))
			    type = gobble(filep, file, file_red, symbols);
			if (type == ELSE)
			        (void)gobble(filep, file, file_red, symbols);
			break;
		case ELSE:
		case ENDIF:
			debug(0,("%s, line %d: #%s\n",
				file->i_file, filep->f_line,
				directives[type]));
			return(type);
		case DEFINE:
		case UNDEF:
		case INCLUDE:
		case INCLUDEDOT:
		case PRAGMA:
		case ERROR:
		case IDENT:
		case SCCS:
		case EJECT:
			break;
		case ELIF:
		case ELIFFALSE:
		case ELIFGUESSFALSE:
			return(type);
		case -1:
			warning("%s, line %d: unknown directive == \"%s\"\n",
				file_red->i_file, filep->f_line, line);
			break;
		}
	}
	return(-1);
}

/*
 * Decide what type of # directive this line is.
 */
int deftype (line, filep, file_red, file, parse_it, symbols)
	register char	*line;
	register struct filepointer *filep;
	register struct inclist *file_red, *file;
	int	parse_it;
	struct symhash	*symbols;
{
	register char	*p;
	char	*directive, savechar;
	register int	ret;

	/*
	 * Parse the directive...
	 */
	directive=line+1;
	while (*directive == ' ' || *directive == '\t')
		directive++;

	p = directive;
	while (*p >= 'a' && *p <= 'z')
		p++;
	savechar = *p;
	*p = '\0';
	ret = match(directive, directives);
	*p = savechar;

	/* If we don't recognize this compiler directive or we happen to just
	 * be gobbling up text while waiting for an #endif or #elif or #else
	 * in the case of an #elif we must check the zero_value and return an
	 * ELIF or an ELIFFALSE.
	 */

	if (ret == ELIF && !parse_it)
	{
	    while (*p == ' ' || *p == '\t')
		p++;
	    /*
	     * parse an expression.
	     */
	    debug(0,("%s, line %d: #elif %s ",
		   file->i_file, filep->f_line, p));
	    ret = zero_value(p, filep, file_red, symbols);
	    if (ret != IF)
	    {
		debug(0,("false...\n"));
		if (ret == IFFALSE)
		    return(ELIFFALSE);
		else
		    return(ELIFGUESSFALSE);
	    }
	    else
	    {
		debug(0,("true...\n"));
		return(ELIF);
	    }
	}

	if (ret < 0 || ! parse_it)
		return(ret);

	/*
	 * now decide how to parse the directive, and do it.
	 */
	while (*p == ' ' || *p == '\t')
		p++;
	switch (ret) {
	case IF:
		/*
		 * parse an expression.
		 */
		ret = zero_value(p, filep, file_red, symbols);
		debug(0,("%s, line %d: %s #if %s\n",
			 file->i_file, filep->f_line, ret?"false":"true", p));
		break;
	case IFDEF:
	case IFNDEF:
		debug(0,("%s, line %d: #%s %s\n",
			file->i_file, filep->f_line, directives[ret], p));
	case UNDEF:
		/*
		 * separate the name of a single symbol.
		 */
		while (isalnum(*p) || *p == '_')
			*line++ = *p++;
		*line = '\0';
		break;
	case INCLUDE:
		debug(2,("%s, line %d: #include %s\n",
			file->i_file, filep->f_line, p));

		/* Support ANSI macro substitution */
		{
			char *sym = hash_lookup(p, symbols);
			while (sym)
			{
				p = sym;
				debug(3,("%s : #includes SYMBOL %s\n",
							file->i_incstring,
							sym));
				/* mark file as having included a 'soft include' */
				file->i_included_sym = TRUE; 
				sym = hash_lookup(p, symbols);
			}
		}

		/*
		 * Separate the name of the include file.
		 */
		while (*p && *p != '"' && *p != '<')
			p++;
		if (! *p)
			return(-2);
		if (*p++ == '"') {
			ret = INCLUDEDOT;
			while (*p && *p != '"')
				*line++ = *p++;
		} else
			while (*p && *p != '>')
				*line++ = *p++;
		*line = '\0';
		break;
	case DEFINE:
		/*
		 * copy the definition back to the beginning of the line.
		 */
		strcpy (line, p);
		break;
	case ELSE:
	case ENDIF:
	case ELIF:
	case PRAGMA:
	case ERROR:
	case IDENT:
	case SCCS:
	case EJECT:
		debug(0,("%s, line %d: #%s\n",
			file->i_file, filep->f_line, directives[ret]));
		/*
		 * nothing to do.
		 */
		break;
	}
	return(ret);
}

/*
 * HACK! - so that we do not have to introduce 'symbols' in each cppsetup.c
 * function...  It's safe, functions from cppsetup.c don't return here.
 */
struct symhash *global_symbols = NULL;

char * isdefined( symbol )
	register char *symbol;
{
	return hash_lookup( symbol, global_symbols );
}

/*
 * Return type based on if the #if expression evaluates to 0
 */
int zero_value(exp, filep, file_red, symbols)
	register char	*exp;
	register struct filepointer *filep;
	register struct inclist *file_red;
	register struct symhash *symbols;
{
	global_symbols = symbols; /* HACK! see above */
	if (cppsetup(exp, filep, file_red))
	    return(IFFALSE);
	else
	    return(IF);
}

void define( def, symbols )
    char	        *def;
    struct symhash **symbols;
{
    char *val;

    /* Separate symbol name and its value */
    val = def;
    while (isalnum(*val) || *val == '_')
	val++;
    if (*val)
	*val++ = '\0';
    while (*val == ' ' || *val == '\t')
	val++;

    if (!*val)
	val = "1";
    hash_define( def, val, symbols );
}

static int hash( str )
    register char *str;
{
    /* Hash (Kernighan and Ritchie) */
    register unsigned int hashval = 0;
    //char *s = str;

    for ( ; *str; str++ )
    {
        hashval = ( hashval * SYMHASHSEED ) + ( *str );
    }

    //fprintf( stderr, "hash: %s, %d\n", s, hashval & ( SYMHASHMEMBERS - 1 ) );
    return hashval & ( SYMHASHMEMBERS - 1 );
}

struct symhash *hash_copy( symbols )
    struct symhash *symbols;
{
    int i;
    struct symhash *newsym;
    if ( !symbols )
        return NULL;

    newsym = (struct symhash *) malloc( sizeof( struct symhash ) );
    
    for ( i = 0; i < SYMHASHMEMBERS; ++i )
    {
        if ( !symbols->s_pairs[ i ] )
            newsym->s_pairs[ i ] = NULL;
        else
        {
            struct pair *it = symbols->s_pairs[ i ];
            struct pair *nw = newsym->s_pairs[ i ] = (struct pair*) malloc( sizeof( struct pair ) );
            nw->p_name = it->p_name;
            nw->p_value = it->p_value;
            nw->p_next = NULL;
            
            while ( it->p_next )
            {
                nw->p_next = (struct pair*) malloc( sizeof( struct pair ) );
                it = it->p_next;
                nw = nw->p_next;
                nw->p_name = it->p_name;
                nw->p_value = it->p_value;
                nw->p_next = NULL;
            }
        }
    }
    return newsym;
}

void hash_free( symbols )
    struct symhash *symbols;
{
    int i;

    if ( !symbols )
        return;

    for ( i = 0; i < SYMHASHMEMBERS; ++i )
    {
        struct pair *it = symbols->s_pairs[ i ];
        struct pair *next;
        while ( it )
        {
            next = it->p_next;
            free( it );
            it = next;
        }
    }
    free( symbols->s_pairs );
}

void hash_define( name, val, symbols )
    char            *name, *val;
    struct symhash **symbols;
{
    int hashval;
    struct pair *it;

    if ( !symbols )
        return;

    /* Make space if it's needed */
    if ( *symbols == NULL )
    {
        int i;

        *symbols = (struct symhash *) malloc( sizeof( struct symhash ) );
        if ( *symbols == NULL )
            fatalerr( "malloc()/realloc() failure in insert_defn()\n" );

        for ( i = 0; i < SYMHASHMEMBERS; ++i )
            (*symbols)->s_pairs[i] = NULL;
    }

    hashval = hash( name );
    it = (*symbols)->s_pairs[ hashval ];
    
    /* Replace/insert the symbol */
    if ( it == NULL )
    {
        it = (*symbols)->s_pairs[ hashval ] = (struct pair*) malloc( sizeof( struct pair ) );
        it->p_name = copy( name );
        it->p_value = copy( val );
        it->p_next = NULL;
    }
    else if ( strcmp( it->p_name, name ) == 0 )
    {
        it->p_value = copy( val );
    }
    else
    {
        while ( it->p_next && ( strcmp( it->p_next->p_name, name ) != 0 ) )
        {
            it = it->p_next;
        }
        if ( it->p_next )
            it->p_next->p_name = copy( name );
        else
        {
            it->p_next = (struct pair*) malloc( sizeof( struct pair ) );
            it->p_next->p_name = copy( name );
            it->p_next->p_value = copy( val );
            it->p_next->p_next = NULL;
        }
    }
}

char *hash_lookup( symbol, symbols )
    char           *symbol;
    struct symhash *symbols;
{
    struct pair *it;

    if ( !symbols )
        return NULL;
    
    it = symbols->s_pairs[ hash( symbol ) ];

    while ( it && ( strcmp( it->p_name, symbol ) != 0 ) )
    {
        it = it->p_next;
    }
    if ( it )
        return it->p_value;

    return NULL;
}

void hash_undefine( symbol, symbols )
    char           *symbol;
    struct symhash *symbols;
{
    int hashval;
    struct pair *it;

    if ( !symbols )
        return;
    
    hashval = hash( symbol );
    it = symbols->s_pairs[ hashval ];
    
    /* Replace/insert the symbol */
    if ( it == NULL )
        return;
    else if ( strcmp( it->p_name, symbol ) == 0 )
    {
        if ( it->p_next )
        {
            struct pair *tmp;
            it->p_name = it->p_next->p_name;
            it->p_value = it->p_next->p_value;
            tmp = it->p_next->p_next;
            free( it->p_next );
            it->p_next = tmp;
        }
        else
        {
            free( it );
            symbols->s_pairs[ hashval ] = NULL;
        }
    }
    else
    {
        while ( it->p_next && ( strcmp( it->p_next->p_name, symbol ) != 0 ) )
        {
            it = it->p_next;
        }
        if ( it->p_next )
        {
            struct pair *tmp = it->p_next;
            it->p_next = it->p_next->p_next;
            free( tmp );
        }
    }
}
