Blame config/makedepend/parse.c

Packit b099d7
/* $XConsortium: parse.c /main/33 1996/12/04 10:11:28 swick $ */
Packit b099d7
/*
Packit b099d7
Packit b099d7
Copyright (c) 1993, 1994  X Consortium
Packit b099d7
Packit b099d7
Permission is hereby granted, free of charge, to any person obtaining a copy
Packit b099d7
of this software and associated documentation files (the "Software"), to deal
Packit b099d7
in the Software without restriction, including without limitation the rights
Packit b099d7
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
Packit b099d7
copies of the Software, and to permit persons to whom the Software is
Packit b099d7
furnished to do so, subject to the following conditions:
Packit b099d7
Packit b099d7
The above copyright notice and this permission notice shall be included in
Packit b099d7
all copies or substantial portions of the Software.
Packit b099d7
Packit b099d7
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
Packit b099d7
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
Packit b099d7
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
Packit b099d7
X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
Packit b099d7
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
Packit b099d7
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Packit b099d7
Packit b099d7
Except as contained in this notice, the name of the X Consortium shall not be
Packit b099d7
used in advertising or otherwise to promote the sale, use or other dealings
Packit b099d7
in this Software without prior written authorization from the X Consortium.
Packit b099d7
Packit b099d7
*/
Packit b099d7
/* $XFree86: xc/config/makedepend/parse.c,v 1.3 1997/01/12 10:39:45 dawes Exp $ */
Packit b099d7
Packit b099d7
#include "def.h"
Packit b099d7
Packit b099d7
extern char	*directives[];
Packit b099d7
extern struct inclist	maininclist;
Packit b099d7
Packit b099d7
int
Packit b099d7
gobble(filep, file, file_red)
Packit b099d7
	register struct filepointer *filep;
Packit b099d7
	struct inclist		*file, *file_red;
Packit b099d7
{
Packit b099d7
	register char	*line;
Packit b099d7
	register int	type;
Packit b099d7
Packit b099d7
	while (line = getline(filep)) {
Packit b099d7
		switch(type = deftype(line, filep, file_red, file, FALSE)) {
Packit b099d7
		case IF:
Packit b099d7
		case IFFALSE:
Packit b099d7
		case IFGUESSFALSE:
Packit b099d7
		case IFDEF:
Packit b099d7
		case IFNDEF:
Packit b099d7
			type = gobble(filep, file, file_red);
Packit b099d7
			while ((type == ELIF) || (type == ELIFFALSE) ||
Packit b099d7
			       (type == ELIFGUESSFALSE))
Packit b099d7
			    type = gobble(filep, file, file_red);
Packit b099d7
			if (type == ELSE)
Packit b099d7
			        (void)gobble(filep, file, file_red);
Packit b099d7
			break;
Packit b099d7
		case ELSE:
Packit b099d7
		case ENDIF:
Packit b099d7
			debug(0,("%s, line %d: #%s\n",
Packit b099d7
				file->i_file, filep->f_line,
Packit b099d7
				directives[type]));
Packit b099d7
			return(type);
Packit b099d7
		case DEFINE:
Packit b099d7
		case UNDEF:
Packit b099d7
		case INCLUDE:
Packit b099d7
		case INCLUDEDOT:
Packit b099d7
		case PRAGMA:
Packit b099d7
		case ERROR:
Packit b099d7
		case IDENT:
Packit b099d7
		case SCCS:
Packit b099d7
		case EJECT:
Packit b099d7
		case WARNING:
Packit b099d7
			break;
Packit b099d7
		case ELIF:
Packit b099d7
		case ELIFFALSE:
Packit b099d7
		case ELIFGUESSFALSE:
Packit b099d7
			return(type);
Packit b099d7
		case -1:
Packit b099d7
			warning("%s, line %d: unknown directive == \"%s\"\n",
Packit b099d7
				file_red->i_file, filep->f_line, line);
Packit b099d7
			break;
Packit b099d7
		}
Packit b099d7
	}
Packit b099d7
	return(-1);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*
Packit b099d7
 * Decide what type of # directive this line is.
Packit b099d7
 */
Packit b099d7
int deftype (line, filep, file_red, file, parse_it)
Packit b099d7
	register char	*line;
Packit b099d7
	register struct filepointer *filep;
Packit b099d7
	register struct inclist *file_red, *file;
Packit b099d7
	int	parse_it;
Packit b099d7
{
Packit b099d7
	register char	*p;
Packit b099d7
	char	*directive, savechar;
Packit b099d7
	register int	ret;
Packit b099d7
Packit b099d7
	/*
Packit b099d7
	 * Parse the directive...
Packit b099d7
	 */
Packit b099d7
	directive=line+1;
Packit b099d7
	while (*directive == ' ' || *directive == '\t')
Packit b099d7
		directive++;
Packit b099d7
Packit b099d7
	p = directive;
Packit b099d7
	while (*p >= 'a' && *p <= 'z')
Packit b099d7
		p++;
Packit b099d7
	savechar = *p;
Packit b099d7
	*p = '\0';
Packit b099d7
	ret = match(directive, directives);
Packit b099d7
	*p = savechar;
Packit b099d7
Packit b099d7
	/* If we don't recognize this compiler directive or we happen to just
Packit b099d7
	 * be gobbling up text while waiting for an #endif or #elif or #else
Packit b099d7
	 * in the case of an #elif we must check the zero_value and return an
Packit b099d7
	 * ELIF or an ELIFFALSE.
Packit b099d7
	 */
Packit b099d7
Packit b099d7
	if (ret == ELIF && !parse_it)
Packit b099d7
	{
Packit b099d7
	    while (*p == ' ' || *p == '\t')
Packit b099d7
		p++;
Packit b099d7
	    /*
Packit b099d7
	     * parse an expression.
Packit b099d7
	     */
Packit b099d7
	    debug(0,("%s, line %d: #elif %s ",
Packit b099d7
		   file->i_file, filep->f_line, p));
Packit b099d7
	    ret = zero_value(p, filep, file_red);
Packit b099d7
	    if (ret != IF)
Packit b099d7
	    {
Packit b099d7
		debug(0,("false...\n"));
Packit b099d7
		if (ret == IFFALSE)
Packit b099d7
		    return(ELIFFALSE);
Packit b099d7
		else
Packit b099d7
		    return(ELIFGUESSFALSE);
Packit b099d7
	    }
Packit b099d7
	    else
Packit b099d7
	    {
Packit b099d7
		debug(0,("true...\n"));
Packit b099d7
		return(ELIF);
Packit b099d7
	    }
Packit b099d7
	}
Packit b099d7
Packit b099d7
	if (ret < 0 || ! parse_it)
Packit b099d7
		return(ret);
Packit b099d7
Packit b099d7
	/*
Packit b099d7
	 * now decide how to parse the directive, and do it.
Packit b099d7
	 */
Packit b099d7
	while (*p == ' ' || *p == '\t')
Packit b099d7
		p++;
Packit b099d7
	switch (ret) {
Packit b099d7
	case IF:
Packit b099d7
		/*
Packit b099d7
		 * parse an expression.
Packit b099d7
		 */
Packit b099d7
		ret = zero_value(p, filep, file_red);
Packit b099d7
		debug(0,("%s, line %d: %s #if %s\n",
Packit b099d7
			 file->i_file, filep->f_line, ret?"false":"true", p));
Packit b099d7
		break;
Packit b099d7
	case IFDEF:
Packit b099d7
	case IFNDEF:
Packit b099d7
		debug(0,("%s, line %d: #%s %s\n",
Packit b099d7
			file->i_file, filep->f_line, directives[ret], p));
Packit b099d7
	case UNDEF:
Packit b099d7
		/*
Packit b099d7
		 * separate the name of a single symbol.
Packit b099d7
		 */
Packit b099d7
		while (isalnum(*p) || *p == '_')
Packit b099d7
			*line++ = *p++;
Packit b099d7
		*line = '\0';
Packit b099d7
		break;
Packit b099d7
	case INCLUDE:
Packit b099d7
		debug(2,("%s, line %d: #include %s\n",
Packit b099d7
			file->i_file, filep->f_line, p));
Packit b099d7
Packit b099d7
		/* Support ANSI macro substitution */
Packit b099d7
		{
Packit b099d7
		    struct symtab **sym = isdefined(p, file_red, NULL);
Packit b099d7
		    while (sym) {
Packit b099d7
			p = (*sym)->s_value;
Packit b099d7
			debug(3,("%s : #includes SYMBOL %s = %s\n",
Packit b099d7
			       file->i_incstring,
Packit b099d7
			       (*sym) -> s_name,
Packit b099d7
			       (*sym) -> s_value));
Packit b099d7
			/* mark file as having included a 'soft include' */
Packit b099d7
			file->i_flags |= INCLUDED_SYM; 
Packit b099d7
			sym = isdefined(p, file_red, NULL);
Packit b099d7
		    }
Packit b099d7
		}
Packit b099d7
Packit b099d7
		/*
Packit b099d7
		 * Separate the name of the include file.
Packit b099d7
		 */
Packit b099d7
		while (*p && *p != '"' && *p != '<')
Packit b099d7
			p++;
Packit b099d7
		if (! *p)
Packit b099d7
			return(-2);
Packit b099d7
		if (*p++ == '"') {
Packit b099d7
			ret = INCLUDEDOT;
Packit b099d7
			while (*p && *p != '"')
Packit b099d7
				*line++ = *p++;
Packit b099d7
		} else
Packit b099d7
			while (*p && *p != '>')
Packit b099d7
				*line++ = *p++;
Packit b099d7
		*line = '\0';
Packit b099d7
		break;
Packit b099d7
	case DEFINE:
Packit b099d7
		/*
Packit b099d7
		 * copy the definition back to the beginning of the line.
Packit b099d7
		 */
Packit b099d7
		strcpy (line, p);
Packit b099d7
		break;
Packit b099d7
	case ELSE:
Packit b099d7
	case ENDIF:
Packit b099d7
	case ELIF:
Packit b099d7
	case PRAGMA:
Packit b099d7
	case ERROR:
Packit b099d7
	case IDENT:
Packit b099d7
	case SCCS:
Packit b099d7
	case EJECT:
Packit b099d7
	case WARNING:
Packit b099d7
		debug(0,("%s, line %d: #%s\n",
Packit b099d7
			file->i_file, filep->f_line, directives[ret]));
Packit b099d7
		/*
Packit b099d7
		 * nothing to do.
Packit b099d7
		 */
Packit b099d7
		break;
Packit b099d7
	}
Packit b099d7
	return(ret);
Packit b099d7
}
Packit b099d7
Packit b099d7
struct symtab **fdefined(symbol, file, srcfile)
Packit b099d7
	register char	*symbol;
Packit b099d7
	struct inclist	*file;
Packit b099d7
	struct inclist	**srcfile;
Packit b099d7
{
Packit b099d7
	register struct inclist	**ip;
Packit b099d7
	register struct symtab	**val;
Packit b099d7
	register int	i;
Packit b099d7
	static int	recurse_lvl = 0;
Packit b099d7
Packit b099d7
	if (file->i_flags & DEFCHECKED)
Packit b099d7
		return(NULL);
Packit b099d7
	file->i_flags |= DEFCHECKED;
Packit b099d7
	if (val = slookup(symbol, file))
Packit b099d7
		debug(1,("%s defined in %s as %s\n",
Packit b099d7
			 symbol, file->i_file, (*val)->s_value));
Packit b099d7
	if (val == NULL && file->i_list)
Packit b099d7
		{
Packit b099d7
		for (ip = file->i_list, i=0; i < file->i_listlen; i++, ip++)
Packit b099d7
			if (file->i_merged[i]==FALSE) {
Packit b099d7
				val = fdefined(symbol, *ip, srcfile);
Packit b099d7
				if ((*ip)->i_flags & FINISHED) {
Packit b099d7
					merge2defines(file,*ip);
Packit b099d7
					file->i_merged[i]=TRUE;
Packit b099d7
				    }
Packit b099d7
				if (val!=NULL) break;
Packit b099d7
			}
Packit b099d7
		}
Packit b099d7
	else if (val != NULL && srcfile != NULL) *srcfile = file;
Packit b099d7
	recurse_lvl--;
Packit b099d7
	file->i_flags &= ~DEFCHECKED;
Packit b099d7
Packit b099d7
	return(val);
Packit b099d7
}
Packit b099d7
Packit b099d7
struct symtab **isdefined(symbol, file, srcfile)
Packit b099d7
	register char	*symbol;
Packit b099d7
	struct inclist	*file;
Packit b099d7
	struct inclist	**srcfile;
Packit b099d7
{
Packit b099d7
	register struct symtab	**val;
Packit b099d7
Packit b099d7
	if (val = slookup(symbol, &maininclist)) {
Packit b099d7
		debug(1,("%s defined on command line\n", symbol));
Packit b099d7
		if (srcfile != NULL) *srcfile = &maininclist;
Packit b099d7
		return(val);
Packit b099d7
	}
Packit b099d7
	if (val = fdefined(symbol, file, srcfile))
Packit b099d7
		return(val);
Packit b099d7
	debug(1,("%s not defined in %s\n", symbol, file->i_file));
Packit b099d7
	return(NULL);
Packit b099d7
}
Packit b099d7
Packit b099d7
/*
Packit b099d7
 * Return type based on if the #if expression evaluates to 0
Packit b099d7
 */
Packit b099d7
int
Packit b099d7
zero_value(exp, filep, file_red)
Packit b099d7
	register char	*exp;
Packit b099d7
	register struct filepointer *filep;
Packit b099d7
	register struct inclist *file_red;
Packit b099d7
{
Packit b099d7
	if (cppsetup(exp, filep, file_red))
Packit b099d7
	    return(IFFALSE);
Packit b099d7
	else
Packit b099d7
	    return(IF);
Packit b099d7
}
Packit b099d7
Packit b099d7
void
Packit b099d7
define2(name, val, file)
Packit b099d7
	char	*name, *val;
Packit b099d7
	struct inclist	*file;
Packit b099d7
{
Packit b099d7
    int first, last, below;
Packit b099d7
    register struct symtab **sp = NULL, **dest;
Packit b099d7
    struct symtab *stab;
Packit b099d7
Packit b099d7
    /* Make space if it's needed */
Packit b099d7
    if (file->i_defs == NULL)
Packit b099d7
    {
Packit b099d7
	file->i_defs = (struct symtab **)
Packit b099d7
			malloc(sizeof (struct symtab*) * SYMTABINC);
Packit b099d7
	file->i_ndefs = 0;
Packit b099d7
    }
Packit b099d7
    else if (!(file->i_ndefs % SYMTABINC))
Packit b099d7
	file->i_defs = (struct symtab **)
Packit b099d7
			realloc(file->i_defs,
Packit b099d7
			   sizeof(struct symtab*)*(file->i_ndefs+SYMTABINC));
Packit b099d7
Packit b099d7
    if (file->i_defs == NULL)
Packit b099d7
	fatalerr("malloc()/realloc() failure in insert_defn()\n");
Packit b099d7
Packit b099d7
    below = first = 0;
Packit b099d7
    last = file->i_ndefs - 1;
Packit b099d7
    while (last >= first)
Packit b099d7
    {
Packit b099d7
	/* Fast inline binary search */
Packit b099d7
	register char *s1;
Packit b099d7
	register char *s2;
Packit b099d7
	register int middle = (first + last) / 2;
Packit b099d7
Packit b099d7
	/* Fast inline strchr() */
Packit b099d7
	s1 = name;
Packit b099d7
	s2 = file->i_defs[middle]->s_name;
Packit b099d7
	while (*s1++ == *s2++)
Packit b099d7
	    if (s2[-1] == '\0') break;
Packit b099d7
Packit b099d7
	/* If exact match, set sp and break */
Packit b099d7
	if (*--s1 == *--s2) 
Packit b099d7
	{
Packit b099d7
	    sp = file->i_defs + middle;
Packit b099d7
	    break;
Packit b099d7
	}
Packit b099d7
Packit b099d7
	/* If name > i_defs[middle] ... */
Packit b099d7
	if (*s1 > *s2) 
Packit b099d7
	{
Packit b099d7
	    below = first;
Packit b099d7
	    first = middle + 1;
Packit b099d7
	}
Packit b099d7
	/* else ... */
Packit b099d7
	else
Packit b099d7
	{
Packit b099d7
	    below = last = middle - 1;
Packit b099d7
	}
Packit b099d7
    }
Packit b099d7
Packit b099d7
    /* Search is done.  If we found an exact match to the symbol name,
Packit b099d7
       just replace its s_value */
Packit b099d7
    if (sp != NULL)
Packit b099d7
    {
Packit b099d7
	free((*sp)->s_value);
Packit b099d7
	(*sp)->s_value = copy(val);
Packit b099d7
	return;
Packit b099d7
    }
Packit b099d7
Packit b099d7
    sp = file->i_defs + file->i_ndefs++;
Packit b099d7
    dest = file->i_defs + below + 1;
Packit b099d7
    while (sp > dest)
Packit b099d7
    {
Packit b099d7
	*sp = sp[-1];
Packit b099d7
	sp--;
Packit b099d7
    }
Packit b099d7
    stab = (struct symtab *) malloc(sizeof (struct symtab));
Packit b099d7
    if (stab == NULL)
Packit b099d7
	fatalerr("malloc()/realloc() failure in insert_defn()\n");
Packit b099d7
Packit b099d7
    stab->s_name = copy(name);
Packit b099d7
    stab->s_value = copy(val);
Packit b099d7
    *sp = stab;
Packit b099d7
}
Packit b099d7
Packit b099d7
void
Packit b099d7
define(def, file)
Packit b099d7
	char	*def;
Packit b099d7
	struct inclist	*file;
Packit b099d7
{
Packit b099d7
    char *val;
Packit b099d7
Packit b099d7
    /* Separate symbol name and its value */
Packit b099d7
    val = def;
Packit b099d7
    while (isalnum(*val) || *val == '_')
Packit b099d7
	val++;
Packit b099d7
    if (*val)
Packit b099d7
	*val++ = '\0';
Packit b099d7
    while (*val == ' ' || *val == '\t')
Packit b099d7
	val++;
Packit b099d7
Packit b099d7
    if (!*val)
Packit b099d7
	val = "1";
Packit b099d7
    define2(def, val, file);
Packit b099d7
}
Packit b099d7
Packit b099d7
struct symtab **slookup(symbol, file)
Packit b099d7
	register char	*symbol;
Packit b099d7
	register struct inclist	*file;
Packit b099d7
{
Packit b099d7
	register int first = 0;
Packit b099d7
	register int last = file->i_ndefs - 1;
Packit b099d7
Packit b099d7
	if (file) while (last >= first)
Packit b099d7
	{
Packit b099d7
	    /* Fast inline binary search */
Packit b099d7
	    register char *s1;
Packit b099d7
	    register char *s2;
Packit b099d7
	    register int middle = (first + last) / 2;
Packit b099d7
Packit b099d7
	    /* Fast inline strchr() */
Packit b099d7
	    s1 = symbol;
Packit b099d7
	    s2 = file->i_defs[middle]->s_name;
Packit b099d7
	    while (*s1++ == *s2++)
Packit b099d7
	        if (s2[-1] == '\0') break;
Packit b099d7
Packit b099d7
	    /* If exact match, we're done */
Packit b099d7
	    if (*--s1 == *--s2) 
Packit b099d7
	    {
Packit b099d7
	        return file->i_defs + middle;
Packit b099d7
	    }
Packit b099d7
Packit b099d7
	    /* If symbol > i_defs[middle] ... */
Packit b099d7
	    if (*s1 > *s2) 
Packit b099d7
	    {
Packit b099d7
	        first = middle + 1;
Packit b099d7
	    }
Packit b099d7
	    /* else ... */
Packit b099d7
	    else
Packit b099d7
	    {
Packit b099d7
	        last = middle - 1;
Packit b099d7
	    }
Packit b099d7
	}
Packit b099d7
	return(NULL);
Packit b099d7
}
Packit b099d7
Packit b099d7
int merge2defines(file1, file2)
Packit b099d7
	struct inclist	*file1;
Packit b099d7
	struct inclist	*file2;
Packit b099d7
{
Packit b099d7
	if ((file1!=NULL) && (file2!=NULL)) 
Packit b099d7
        {
Packit b099d7
		int first1 = 0;
Packit b099d7
		int last1 = file1->i_ndefs - 1;
Packit b099d7
Packit b099d7
		int first2 = 0;
Packit b099d7
		int last2 = file2->i_ndefs - 1;
Packit b099d7
Packit b099d7
                int first=0;
Packit b099d7
                struct symtab** i_defs = NULL;
Packit b099d7
		int deflen=file1->i_ndefs+file2->i_ndefs;
Packit b099d7
Packit b099d7
                if (deflen>0)
Packit b099d7
                { 
Packit b099d7
                	/* make sure deflen % SYMTABINC == 0 is still true */
Packit b099d7
                	deflen += (SYMTABINC - deflen % SYMTABINC) % SYMTABINC;
Packit b099d7
                	i_defs=(struct symtab**)
Packit b099d7
			    malloc(deflen*sizeof(struct symtab*));
Packit b099d7
                	if (i_defs==NULL) return 0;
Packit b099d7
        	}
Packit b099d7
Packit b099d7
        	while ((last1 >= first1) && (last2 >= first2))
Packit b099d7
        	{
Packit b099d7
	    		char *s1=file1->i_defs[first1]->s_name;
Packit b099d7
	    		char *s2=file2->i_defs[first2]->s_name;
Packit b099d7
Packit b099d7
     			if (strcmp(s1,s2) < 0)
Packit b099d7
                        	i_defs[first++]=file1->i_defs[first1++];
Packit b099d7
     			else if (strcmp(s1,s2) > 0)
Packit b099d7
                        	i_defs[first++]=file2->i_defs[first2++];
Packit b099d7
                        else /* equal */
Packit b099d7
                        {
Packit b099d7
                        	i_defs[first++]=file2->i_defs[first2++];
Packit b099d7
                                first1++;
Packit b099d7
                        }
Packit b099d7
        	}
Packit b099d7
        	while (last1 >= first1)
Packit b099d7
        	{
Packit b099d7
                        i_defs[first++]=file1->i_defs[first1++];
Packit b099d7
        	}
Packit b099d7
        	while (last2 >= first2)
Packit b099d7
        	{
Packit b099d7
                        i_defs[first++]=file2->i_defs[first2++];
Packit b099d7
        	}
Packit b099d7
Packit b099d7
                if (file1->i_defs) free(file1->i_defs);
Packit b099d7
                file1->i_defs=i_defs;
Packit b099d7
                file1->i_ndefs=first;
Packit b099d7
                
Packit b099d7
		return 1;
Packit b099d7
  	}
Packit b099d7
	return 0;
Packit b099d7
}
Packit b099d7
Packit b099d7
void
Packit b099d7
undefine(symbol, file)
Packit b099d7
	char	*symbol;
Packit b099d7
	register struct inclist	*file;
Packit b099d7
{
Packit b099d7
	register struct symtab **ptr;
Packit b099d7
	struct inclist *srcfile;
Packit b099d7
	while ((ptr = isdefined(symbol, file, &srcfile)) != NULL)
Packit b099d7
	{
Packit b099d7
	    srcfile->i_ndefs--;
Packit b099d7
	    for (; ptr < srcfile->i_defs + srcfile->i_ndefs; ptr++)
Packit b099d7
		*ptr = ptr[1];
Packit b099d7
	}
Packit b099d7
}
Packit b099d7
Packit b099d7
int
Packit b099d7
find_includes(filep, file, file_red, recursion, failOK)
Packit b099d7
	struct filepointer	*filep;
Packit b099d7
	struct inclist		*file, *file_red;
Packit b099d7
	int			recursion;
Packit b099d7
	boolean			failOK;
Packit b099d7
{
Packit b099d7
	register char	*line;
Packit b099d7
	register int	type;
Packit b099d7
	boolean recfailOK;
Packit b099d7
Packit b099d7
	while (line = getline(filep)) {
Packit b099d7
		switch(type = deftype(line, filep, file_red, file, TRUE)) {
Packit b099d7
		case IF:
Packit b099d7
		doif:
Packit b099d7
			type = find_includes(filep, file,
Packit b099d7
				file_red, recursion+1, failOK);
Packit b099d7
			while ((type == ELIF) || (type == ELIFFALSE) ||
Packit b099d7
			       (type == ELIFGUESSFALSE))
Packit b099d7
				type = gobble(filep, file, file_red);
Packit b099d7
			if (type == ELSE)
Packit b099d7
				gobble(filep, file, file_red);
Packit b099d7
			break;
Packit b099d7
		case IFFALSE:
Packit b099d7
		case IFGUESSFALSE:
Packit b099d7
		    doiffalse:
Packit b099d7
			if (type == IFGUESSFALSE || type == ELIFGUESSFALSE)
Packit b099d7
			    recfailOK = TRUE;
Packit b099d7
			else
Packit b099d7
			    recfailOK = failOK;
Packit b099d7
			type = gobble(filep, file, file_red);
Packit b099d7
			if (type == ELSE)
Packit b099d7
			    find_includes(filep, file,
Packit b099d7
					  file_red, recursion+1, recfailOK);
Packit b099d7
			else
Packit b099d7
			if (type == ELIF)
Packit b099d7
			    goto doif;
Packit b099d7
			else
Packit b099d7
			if ((type == ELIFFALSE) || (type == ELIFGUESSFALSE))
Packit b099d7
			    goto doiffalse;
Packit b099d7
			break;
Packit b099d7
		case IFDEF:
Packit b099d7
		case IFNDEF:
Packit b099d7
			if ((type == IFDEF && isdefined(line, file_red, NULL))
Packit b099d7
			 || (type == IFNDEF && !isdefined(line, file_red, NULL))) {
Packit b099d7
				debug(1,(type == IFNDEF ?
Packit b099d7
				    "line %d: %s !def'd in %s via %s%s\n" : "",
Packit b099d7
				    filep->f_line, line,
Packit b099d7
				    file->i_file, file_red->i_file, ": doit"));
Packit b099d7
				type = find_includes(filep, file,
Packit b099d7
					file_red, recursion+1, failOK);
Packit b099d7
				while (type == ELIF || type == ELIFFALSE || type == ELIFGUESSFALSE)
Packit b099d7
					type = gobble(filep, file, file_red);
Packit b099d7
				if (type == ELSE)
Packit b099d7
					gobble(filep, file, file_red);
Packit b099d7
			}
Packit b099d7
			else {
Packit b099d7
				debug(1,(type == IFDEF ?
Packit b099d7
				    "line %d: %s !def'd in %s via %s%s\n" : "",
Packit b099d7
				    filep->f_line, line,
Packit b099d7
				    file->i_file, file_red->i_file, ": gobble"));
Packit b099d7
				type = gobble(filep, file, file_red);
Packit b099d7
				if (type == ELSE)
Packit b099d7
					find_includes(filep, file,
Packit b099d7
						file_red, recursion+1, failOK);
Packit b099d7
				else if (type == ELIF)
Packit b099d7
				    	goto doif;
Packit b099d7
				else if (type == ELIFFALSE || type == ELIFGUESSFALSE)
Packit b099d7
				    	goto doiffalse;
Packit b099d7
			}
Packit b099d7
			break;
Packit b099d7
		case ELSE:
Packit b099d7
		case ELIFFALSE:
Packit b099d7
		case ELIFGUESSFALSE:
Packit b099d7
		case ELIF:
Packit b099d7
			if (!recursion)
Packit b099d7
				gobble(filep, file, file_red);
Packit b099d7
		case ENDIF:
Packit b099d7
			if (recursion)
Packit b099d7
				return(type);
Packit b099d7
		case DEFINE:
Packit b099d7
			define(line, file);
Packit b099d7
			break;
Packit b099d7
		case UNDEF:
Packit b099d7
			if (!*line) {
Packit b099d7
			    warning("%s, line %d: incomplete undef == \"%s\"\n",
Packit b099d7
				file_red->i_file, filep->f_line, line);
Packit b099d7
			    break;
Packit b099d7
			}
Packit b099d7
			undefine(line, file_red);
Packit b099d7
			break;
Packit b099d7
		case INCLUDE:
Packit b099d7
			add_include(filep, file, file_red, line, FALSE, failOK);
Packit b099d7
			break;
Packit b099d7
		case INCLUDEDOT:
Packit b099d7
			add_include(filep, file, file_red, line, TRUE, failOK);
Packit b099d7
			break;
Packit b099d7
		case ERROR:
Packit b099d7
		case WARNING:
Packit b099d7
		    	warning("%s: %d: %s\n", file_red->i_file,
Packit b099d7
				 filep->f_line, line);
Packit b099d7
		    	break;
Packit b099d7
		    
Packit b099d7
		case PRAGMA:
Packit b099d7
		case IDENT:
Packit b099d7
		case SCCS:
Packit b099d7
		case EJECT:
Packit b099d7
			break;
Packit b099d7
		case -1:
Packit b099d7
			warning("%s", file_red->i_file);
Packit b099d7
			if (file_red != file)
Packit b099d7
			    warning1(" (reading %s)", file->i_file);
Packit b099d7
			warning1(", line %d: unknown directive == \"%s\"\n",
Packit b099d7
				 filep->f_line, line);
Packit b099d7
			break;
Packit b099d7
		case -2:
Packit b099d7
			warning("%s", file_red->i_file);
Packit b099d7
			if (file_red != file)
Packit b099d7
			    warning1(" (reading %s)", file->i_file);
Packit b099d7
			warning1(", line %d: incomplete include == \"%s\"\n",
Packit b099d7
				 filep->f_line, line);
Packit b099d7
			break;
Packit b099d7
		}
Packit b099d7
	}
Packit b099d7
	file->i_flags |= FINISHED;
Packit b099d7
	return(-1);
Packit b099d7
}