security/nss/coreconf/mkdepend/parse.c

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/security/nss/coreconf/mkdepend/parse.c	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,686 @@
     1.4 +/* $Xorg: parse.c,v 1.6 2001/02/09 02:03:16 xorgcvs Exp $ */
     1.5 +/*
     1.6 +
     1.7 +Copyright (c) 1993, 1994, 1998 The Open Group
     1.8 +
     1.9 +Permission to use, copy, modify, distribute, and sell this software and its
    1.10 +documentation for any purpose is hereby granted without fee, provided that
    1.11 +the above copyright notice appear in all copies and that both that
    1.12 +copyright notice and this permission notice appear in supporting
    1.13 +documentation.
    1.14 +
    1.15 +The above copyright notice and this permission notice shall be included in
    1.16 +all copies or substantial portions of the Software.
    1.17 +
    1.18 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    1.19 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    1.20 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
    1.21 +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
    1.22 +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
    1.23 +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    1.24 +
    1.25 +Except as contained in this notice, the name of The Open Group shall not be
    1.26 +used in advertising or otherwise to promote the sale, use or other dealings
    1.27 +in this Software without prior written authorization from The Open Group.
    1.28 +
    1.29 +*/
    1.30 +/* $XFree86: xc/config/makedepend/parse.c,v 1.12 2002/02/26 05:09:10 tsi Exp $ */
    1.31 +
    1.32 +#include "def.h"
    1.33 +
    1.34 +extern char	*directives[];
    1.35 +extern struct inclist	inclist[ MAXFILES ],
    1.36 +			*inclistnext,
    1.37 +			maininclist;
    1.38 +extern char	*includedirs[ ],
    1.39 +		**includedirsnext;
    1.40 +
    1.41 +static int deftype (char *line, struct filepointer *filep,
    1.42 +		    struct inclist *file_red, struct inclist *file,
    1.43 +		    int parse_it);
    1.44 +static int zero_value(char *filename, char *exp, struct filepointer *filep,
    1.45 +		    struct inclist *file_red);
    1.46 +static int merge2defines(struct inclist *file1, struct inclist *file2);
    1.47 +
    1.48 +static int
    1.49 +gobble(struct filepointer *filep, struct inclist *file,
    1.50 +       struct inclist *file_red)
    1.51 +{
    1.52 +	char	*line;
    1.53 +	int	type;
    1.54 +
    1.55 +	while ((line = getnextline(filep))) {
    1.56 +		switch(type = deftype(line, filep, file_red, file, FALSE)) {
    1.57 +		case IF:
    1.58 +		case IFFALSE:
    1.59 +		case IFGUESSFALSE:
    1.60 +		case IFDEF:
    1.61 +		case IFNDEF:
    1.62 +			type = gobble(filep, file, file_red);
    1.63 +			while ((type == ELIF) || (type == ELIFFALSE) ||
    1.64 +			       (type == ELIFGUESSFALSE))
    1.65 +			    type = gobble(filep, file, file_red);
    1.66 +			if (type == ELSE)
    1.67 +			        (void)gobble(filep, file, file_red);
    1.68 +			break;
    1.69 +		case ELSE:
    1.70 +		case ENDIF:
    1.71 +			debug(0,("%s, line %d: #%s\n",
    1.72 +				file->i_file, filep->f_line,
    1.73 +				directives[type]));
    1.74 +			return(type);
    1.75 +		case DEFINE:
    1.76 +		case UNDEF:
    1.77 +		case INCLUDE:
    1.78 +		case INCLUDEDOT:
    1.79 +		case PRAGMA:
    1.80 +		case ERROR:
    1.81 +		case IDENT:
    1.82 +		case SCCS:
    1.83 +		case EJECT:
    1.84 +		case WARNING:
    1.85 +		case INCLUDENEXT:
    1.86 +		case INCLUDENEXTDOT:
    1.87 +			break;
    1.88 +		case ELIF:
    1.89 +		case ELIFFALSE:
    1.90 +		case ELIFGUESSFALSE:
    1.91 +			return(type);
    1.92 +		case -1:
    1.93 +			warning("%s", file_red->i_file);
    1.94 +			if (file_red != file)
    1.95 +				warning1(" (reading %s)", file->i_file);
    1.96 +			warning1(", line %d: unknown directive == \"%s\"\n",
    1.97 +				filep->f_line, line);
    1.98 +			break;
    1.99 +		}
   1.100 +	}
   1.101 +	return(-1);
   1.102 +}
   1.103 +
   1.104 +/*
   1.105 + * Decide what type of # directive this line is.
   1.106 + */
   1.107 +static int 
   1.108 +deftype (char *line, struct filepointer *filep, 
   1.109 +	     struct inclist *file_red, struct inclist *file, int parse_it)
   1.110 +{
   1.111 +	register char	*p;
   1.112 +	char	*directive, savechar, *q;
   1.113 +	register int	ret;
   1.114 +
   1.115 +	/*
   1.116 +	 * Parse the directive...
   1.117 +	 */
   1.118 +	directive=line+1;
   1.119 +	while (*directive == ' ' || *directive == '\t')
   1.120 +		directive++;
   1.121 +
   1.122 +	p = directive;
   1.123 +	while ((*p == '_') || (*p >= 'a' && *p <= 'z'))
   1.124 +		p++;
   1.125 +	savechar = *p;
   1.126 +	*p = '\0';
   1.127 +	ret = match(directive, directives);
   1.128 +	*p = savechar;
   1.129 +
   1.130 +	/* If we don't recognize this compiler directive or we happen to just
   1.131 +	 * be gobbling up text while waiting for an #endif or #elif or #else
   1.132 +	 * in the case of an #elif we must check the zero_value and return an
   1.133 +	 * ELIF or an ELIFFALSE.
   1.134 +	 */
   1.135 +
   1.136 +	if (ret == ELIF && !parse_it)
   1.137 +	{
   1.138 +	    while (*p == ' ' || *p == '\t')
   1.139 +		p++;
   1.140 +	    /*
   1.141 +	     * parse an expression.
   1.142 +	     */
   1.143 +	    debug(0,("%s, line %d: #elif %s ",
   1.144 +		   file->i_file, filep->f_line, p));
   1.145 +	    ret = zero_value(file->i_file, p, filep, file_red);
   1.146 +	    if (ret != IF)
   1.147 +	    {
   1.148 +		debug(0,("false...\n"));
   1.149 +		if (ret == IFFALSE)
   1.150 +		    return(ELIFFALSE);
   1.151 +		else
   1.152 +		    return(ELIFGUESSFALSE);
   1.153 +	    }
   1.154 +	    else
   1.155 +	    {
   1.156 +		debug(0,("true...\n"));
   1.157 +		return(ELIF);
   1.158 +	    }
   1.159 +	}
   1.160 +
   1.161 +	if (ret < 0 || ! parse_it)
   1.162 +		return(ret);
   1.163 +
   1.164 +	/*
   1.165 +	 * now decide how to parse the directive, and do it.
   1.166 +	 */
   1.167 +	while (*p == ' ' || *p == '\t')
   1.168 +		p++;
   1.169 +	q = p + strlen(p);
   1.170 +	do {
   1.171 +		q--;
   1.172 +	} while (*q == ' ' || *q == '\t');
   1.173 +	q[1] = '\0';
   1.174 +	switch (ret) {
   1.175 +	case IF:
   1.176 +		/*
   1.177 +		 * parse an expression.
   1.178 +		 */
   1.179 +		ret = zero_value(file->i_file, p, filep, file_red);
   1.180 +		debug(0,("%s, line %d: %s #if %s\n",
   1.181 +			 file->i_file, filep->f_line, ret?"false":"true", p));
   1.182 +		break;
   1.183 +	case IFDEF:
   1.184 +	case IFNDEF:
   1.185 +		debug(0,("%s, line %d: #%s %s\n",
   1.186 +			file->i_file, filep->f_line, directives[ret], p));
   1.187 +	case UNDEF:
   1.188 +		/*
   1.189 +		 * separate the name of a single symbol.
   1.190 +		 */
   1.191 +		while (isalnum(*p) || *p == '_')
   1.192 +			*line++ = *p++;
   1.193 +		*line = '\0';
   1.194 +		break;
   1.195 +	case INCLUDE:
   1.196 +	case INCLUDENEXT:
   1.197 +		debug(2,("%s, line %d: #include%s %s\n",
   1.198 +			file->i_file, filep->f_line,
   1.199 +			(ret == INCLUDE) ? "" : "_next", p));
   1.200 +
   1.201 +		/* Support ANSI macro substitution */
   1.202 +		while (1) {
   1.203 +			struct symtab **sym;
   1.204 +
   1.205 +			if (!*p || *p == '"' || *p == '<')
   1.206 +				break;
   1.207 +
   1.208 +		    	sym = isdefined(p, file_red, NULL);
   1.209 +			if (!sym)
   1.210 +				break;
   1.211 +
   1.212 +			p = (*sym)->s_value;
   1.213 +			debug(3,("%s : #includes SYMBOL %s = %s\n",
   1.214 +			       file->i_incstring,
   1.215 +			       (*sym) -> s_name,
   1.216 +			       (*sym) -> s_value));
   1.217 +			/* mark file as having included a 'soft include' */
   1.218 +			file->i_flags |= INCLUDED_SYM; 
   1.219 +		}
   1.220 +
   1.221 +		/*
   1.222 +		 * Separate the name of the include file.
   1.223 +		 */
   1.224 +		while (*p && *p != '"' && *p != '<')
   1.225 +			p++;
   1.226 +		if (! *p)
   1.227 +			return(-2);
   1.228 +		if (*p++ == '"') {
   1.229 +			if (ret == INCLUDE)
   1.230 +				ret = INCLUDEDOT;
   1.231 +			else
   1.232 +				ret = INCLUDENEXTDOT;
   1.233 +			while (*p && *p != '"')
   1.234 +				*line++ = *p++;
   1.235 +		} else
   1.236 +			while (*p && *p != '>')
   1.237 +				*line++ = *p++;
   1.238 +		*line = '\0';
   1.239 +		break;
   1.240 +	case DEFINE:
   1.241 +		/*
   1.242 +		 * copy the definition back to the beginning of the line.
   1.243 +		 */
   1.244 +		strcpy (line, p);
   1.245 +		break;
   1.246 +	case ELSE:
   1.247 +	case ENDIF:
   1.248 +	case ELIF:
   1.249 +	case PRAGMA:
   1.250 +	case ERROR:
   1.251 +	case IDENT:
   1.252 +	case SCCS:
   1.253 +	case EJECT:
   1.254 +	case WARNING:
   1.255 +		debug(0,("%s, line %d: #%s\n",
   1.256 +			file->i_file, filep->f_line, directives[ret]));
   1.257 +		/*
   1.258 +		 * nothing to do.
   1.259 +		 */
   1.260 +		break;
   1.261 +	}
   1.262 +	return(ret);
   1.263 +}
   1.264 +
   1.265 +struct symtab **
   1.266 +fdefined(char *symbol, struct inclist *file, struct inclist **srcfile)
   1.267 +{
   1.268 +	struct inclist	**ip;
   1.269 +	struct symtab	**val;
   1.270 +	int	i;
   1.271 +	static int	recurse_lvl = 0;
   1.272 +
   1.273 +	if (file->i_flags & DEFCHECKED)
   1.274 +		return(NULL);
   1.275 +	debug(2,("Looking for %s in %s\n", symbol, file->i_file));
   1.276 +	file->i_flags |= DEFCHECKED;
   1.277 +	if ((val = slookup(symbol, file)))
   1.278 +		debug(1,("%s defined in %s as %s\n",
   1.279 +			 symbol, file->i_file, (*val)->s_value));
   1.280 +	if (val == NULL && file->i_list)
   1.281 +	{
   1.282 +		for (ip = file->i_list, i=0; i < file->i_listlen; i++, ip++)
   1.283 +			if (file->i_merged[i]==FALSE) {
   1.284 +				val = fdefined(symbol, *ip, srcfile);
   1.285 +				file->i_merged[i]=merge2defines(file,*ip);
   1.286 +				if (val!=NULL) break;
   1.287 +			}
   1.288 +	}
   1.289 +	else if (val != NULL && srcfile != NULL) *srcfile = file;
   1.290 +	recurse_lvl--;
   1.291 +	file->i_flags &= ~DEFCHECKED;
   1.292 +
   1.293 +	return(val);
   1.294 +}
   1.295 +
   1.296 +struct symtab **
   1.297 +isdefined(char *symbol, struct inclist *file, struct inclist **srcfile)
   1.298 +{
   1.299 +	struct symtab	**val;
   1.300 +
   1.301 +	if ((val = slookup(symbol, &maininclist))) {
   1.302 +		debug(1,("%s defined on command line\n", symbol));
   1.303 +		if (srcfile != NULL) *srcfile = &maininclist;
   1.304 +		return(val);
   1.305 +	}
   1.306 +	if ((val = fdefined(symbol, file, srcfile)))
   1.307 +		return(val);
   1.308 +	debug(1,("%s not defined in %s\n", symbol, file->i_file));
   1.309 +	return(NULL);
   1.310 +}
   1.311 +
   1.312 +/*
   1.313 + * Return type based on if the #if expression evaluates to 0
   1.314 + */
   1.315 +static int
   1.316 +zero_value(char *filename,
   1.317 +	   char *exp,
   1.318 +	   struct filepointer *filep,
   1.319 +	   struct inclist *file_red)
   1.320 +{
   1.321 +	if (cppsetup(filename, exp, filep, file_red))
   1.322 +	    return(IFFALSE);
   1.323 +	else
   1.324 +	    return(IF);
   1.325 +}
   1.326 +
   1.327 +void
   1.328 +define2(char *name, char *val, struct inclist *file)
   1.329 +{
   1.330 +    int first, last, below;
   1.331 +    register struct symtab **sp = NULL, **dest;
   1.332 +    struct symtab *stab;
   1.333 +
   1.334 +    /* Make space if it's needed */
   1.335 +    if (file->i_defs == NULL)
   1.336 +    {
   1.337 +	file->i_defs = (struct symtab **)
   1.338 +			malloc(sizeof (struct symtab*) * SYMTABINC);
   1.339 +	file->i_ndefs = 0;
   1.340 +    }
   1.341 +    else if (!(file->i_ndefs % SYMTABINC))
   1.342 +	file->i_defs = (struct symtab **)
   1.343 +			realloc(file->i_defs,
   1.344 +			   sizeof(struct symtab*)*(file->i_ndefs+SYMTABINC));
   1.345 +
   1.346 +    if (file->i_defs == NULL)
   1.347 +	fatalerr("malloc()/realloc() failure in insert_defn()\n");
   1.348 +
   1.349 +    below = first = 0;
   1.350 +    last = file->i_ndefs - 1;
   1.351 +    while (last >= first)
   1.352 +    {
   1.353 +	/* Fast inline binary search */
   1.354 +	register char *s1;
   1.355 +	register char *s2;
   1.356 +	register int middle = (first + last) / 2;
   1.357 +
   1.358 +	/* Fast inline strchr() */
   1.359 +	s1 = name;
   1.360 +	s2 = file->i_defs[middle]->s_name;
   1.361 +	while (*s1++ == *s2++)
   1.362 +	    if (s2[-1] == '\0') break;
   1.363 +
   1.364 +	/* If exact match, set sp and break */
   1.365 +	if (*--s1 == *--s2) 
   1.366 +	{
   1.367 +	    sp = file->i_defs + middle;
   1.368 +	    break;
   1.369 +	}
   1.370 +
   1.371 +	/* If name > i_defs[middle] ... */
   1.372 +	if (*s1 > *s2) 
   1.373 +	{
   1.374 +	    below = first;
   1.375 +	    first = middle + 1;
   1.376 +	}
   1.377 +	/* else ... */
   1.378 +	else
   1.379 +	{
   1.380 +	    below = last = middle - 1;
   1.381 +	}
   1.382 +    }
   1.383 +
   1.384 +    /* Search is done.  If we found an exact match to the symbol name,
   1.385 +       just replace its s_value */
   1.386 +    if (sp != NULL)
   1.387 +    {
   1.388 +	debug(1,("redefining %s from %s to %s in file %s\n",
   1.389 +		name, (*sp)->s_value, val, file->i_file));
   1.390 +	free((*sp)->s_value);
   1.391 +	(*sp)->s_value = copy(val);
   1.392 +	return;
   1.393 +    }
   1.394 +
   1.395 +    sp = file->i_defs + file->i_ndefs++;
   1.396 +    dest = file->i_defs + below + 1;
   1.397 +    while (sp > dest)
   1.398 +    {
   1.399 +	*sp = sp[-1];
   1.400 +	sp--;
   1.401 +    }
   1.402 +    stab = (struct symtab *) malloc(sizeof (struct symtab));
   1.403 +    if (stab == NULL)
   1.404 +	fatalerr("malloc()/realloc() failure in insert_defn()\n");
   1.405 +
   1.406 +    debug(1,("defining %s to %s in file %s\n", name, val, file->i_file));
   1.407 +    stab->s_name = copy(name);
   1.408 +    stab->s_value = copy(val);
   1.409 +    *sp = stab;
   1.410 +}
   1.411 +
   1.412 +void
   1.413 +define(char *def, struct inclist *file)
   1.414 +{
   1.415 +    char *val;
   1.416 +
   1.417 +    /* Separate symbol name and its value */
   1.418 +    val = def;
   1.419 +    while (isalnum(*val) || *val == '_')
   1.420 +	val++;
   1.421 +    if (*val)
   1.422 +	*val++ = '\0';
   1.423 +    while (*val == ' ' || *val == '\t')
   1.424 +	val++;
   1.425 +
   1.426 +    if (!*val)
   1.427 +	val = "1";
   1.428 +    define2(def, val, file);
   1.429 +}
   1.430 +
   1.431 +struct symtab **
   1.432 +slookup(char *symbol, struct inclist *file)
   1.433 +{
   1.434 +	register int first = 0;
   1.435 +	register int last = file->i_ndefs - 1;
   1.436 +
   1.437 +	if (file) while (last >= first)
   1.438 +	{
   1.439 +	    /* Fast inline binary search */
   1.440 +	    register char *s1;
   1.441 +	    register char *s2;
   1.442 +	    register int middle = (first + last) / 2;
   1.443 +
   1.444 +	    /* Fast inline strchr() */
   1.445 +	    s1 = symbol;
   1.446 +	    s2 = file->i_defs[middle]->s_name;
   1.447 +	    while (*s1++ == *s2++)
   1.448 +	        if (s2[-1] == '\0') break;
   1.449 +
   1.450 +	    /* If exact match, we're done */
   1.451 +	    if (*--s1 == *--s2) 
   1.452 +	    {
   1.453 +	        return file->i_defs + middle;
   1.454 +	    }
   1.455 +
   1.456 +	    /* If symbol > i_defs[middle] ... */
   1.457 +	    if (*s1 > *s2) 
   1.458 +	    {
   1.459 +	        first = middle + 1;
   1.460 +	    }
   1.461 +	    /* else ... */
   1.462 +	    else
   1.463 +	    {
   1.464 +	        last = middle - 1;
   1.465 +	    }
   1.466 +	}
   1.467 +	return(NULL);
   1.468 +}
   1.469 +
   1.470 +static int 
   1.471 +merge2defines(struct inclist *file1, struct inclist *file2)
   1.472 +{
   1.473 +	int i;
   1.474 +
   1.475 +	if ((file1==NULL) || (file2==NULL) ||
   1.476 +	    !(file2->i_flags & FINISHED))
   1.477 +		return 0;
   1.478 +
   1.479 +	for (i=0; i < file2->i_listlen; i++)
   1.480 +		if (file2->i_merged[i]==FALSE)
   1.481 +			return 0;
   1.482 +
   1.483 +	{
   1.484 +		int first1 = 0;
   1.485 +		int last1 = file1->i_ndefs - 1;
   1.486 +
   1.487 +		int first2 = 0;
   1.488 +		int last2 = file2->i_ndefs - 1;
   1.489 +
   1.490 +                int first=0;
   1.491 +                struct symtab** i_defs = NULL;
   1.492 +		int deflen=file1->i_ndefs+file2->i_ndefs;
   1.493 +
   1.494 +		debug(2,("merging %s into %s\n",
   1.495 +			file2->i_file, file1->i_file));
   1.496 +
   1.497 +                if (deflen>0)
   1.498 +                { 
   1.499 +                	/* make sure deflen % SYMTABINC == 0 is still true */
   1.500 +                	deflen += (SYMTABINC - deflen % SYMTABINC) % SYMTABINC;
   1.501 +                	i_defs=(struct symtab**)
   1.502 +			    malloc(deflen*sizeof(struct symtab*));
   1.503 +                	if (i_defs==NULL) return 0;
   1.504 +        	}
   1.505 +
   1.506 +        	while ((last1 >= first1) && (last2 >= first2))
   1.507 +        	{
   1.508 +	    		char *s1=file1->i_defs[first1]->s_name;
   1.509 +	    		char *s2=file2->i_defs[first2]->s_name;
   1.510 +
   1.511 +     			if (strcmp(s1,s2) < 0)
   1.512 +                        	i_defs[first++]=file1->i_defs[first1++];
   1.513 +     			else if (strcmp(s1,s2) > 0)
   1.514 +                        	i_defs[first++]=file2->i_defs[first2++];
   1.515 +                        else /* equal */
   1.516 +                        {
   1.517 +                        	i_defs[first++]=file2->i_defs[first2++];
   1.518 +                                first1++;
   1.519 +                        }
   1.520 +        	}
   1.521 +        	while (last1 >= first1)
   1.522 +        	{
   1.523 +                        i_defs[first++]=file1->i_defs[first1++];
   1.524 +        	}
   1.525 +        	while (last2 >= first2)
   1.526 +        	{
   1.527 +                        i_defs[first++]=file2->i_defs[first2++];
   1.528 +        	}
   1.529 +
   1.530 +                if (file1->i_defs) free(file1->i_defs);
   1.531 +                file1->i_defs=i_defs;
   1.532 +                file1->i_ndefs=first;
   1.533 +                
   1.534 +		return 1;
   1.535 +  	}
   1.536 +}
   1.537 +
   1.538 +void
   1.539 +undefine(char *symbol, struct inclist *file)
   1.540 +{
   1.541 +	register struct symtab **ptr;
   1.542 +	struct inclist *srcfile;
   1.543 +	while ((ptr = isdefined(symbol, file, &srcfile)) != NULL)
   1.544 +	{
   1.545 +	    srcfile->i_ndefs--;
   1.546 +	    for (; ptr < srcfile->i_defs + srcfile->i_ndefs; ptr++)
   1.547 +		*ptr = ptr[1];
   1.548 +	}
   1.549 +}
   1.550 +
   1.551 +int
   1.552 +find_includes(struct filepointer *filep, struct inclist *file, 
   1.553 +	      struct inclist *file_red, int recursion, boolean failOK)
   1.554 +{
   1.555 +	struct inclist	*inclistp;
   1.556 +	char		**includedirsp;
   1.557 +	register char	*line;
   1.558 +	register int	type;
   1.559 +	boolean recfailOK;
   1.560 +
   1.561 +	while ((line = getnextline(filep))) {
   1.562 +		switch(type = deftype(line, filep, file_red, file, TRUE)) {
   1.563 +		case IF:
   1.564 +		doif:
   1.565 +			type = find_includes(filep, file,
   1.566 +				file_red, recursion+1, failOK);
   1.567 +			while ((type == ELIF) || (type == ELIFFALSE) ||
   1.568 +			       (type == ELIFGUESSFALSE))
   1.569 +				type = gobble(filep, file, file_red);
   1.570 +			if (type == ELSE)
   1.571 +				gobble(filep, file, file_red);
   1.572 +			break;
   1.573 +		case IFFALSE:
   1.574 +		case IFGUESSFALSE:
   1.575 +		    doiffalse:
   1.576 +			if (type == IFGUESSFALSE || type == ELIFGUESSFALSE)
   1.577 +			    recfailOK = TRUE;
   1.578 +			else
   1.579 +			    recfailOK = failOK;
   1.580 +			type = gobble(filep, file, file_red);
   1.581 +			if (type == ELSE)
   1.582 +			    find_includes(filep, file,
   1.583 +					  file_red, recursion+1, recfailOK);
   1.584 +			else
   1.585 +			if (type == ELIF)
   1.586 +			    goto doif;
   1.587 +			else
   1.588 +			if ((type == ELIFFALSE) || (type == ELIFGUESSFALSE))
   1.589 +			    goto doiffalse;
   1.590 +			break;
   1.591 +		case IFDEF:
   1.592 +		case IFNDEF:
   1.593 +			if ((type == IFDEF && isdefined(line, file_red, NULL))
   1.594 +			 || (type == IFNDEF && !isdefined(line, file_red, NULL))) {
   1.595 +				debug(1,(type == IFNDEF ?
   1.596 +				    "line %d: %s !def'd in %s via %s%s\n" : "",
   1.597 +				    filep->f_line, line,
   1.598 +				    file->i_file, file_red->i_file, ": doit"));
   1.599 +				type = find_includes(filep, file,
   1.600 +					file_red, recursion+1, failOK);
   1.601 +				while (type == ELIF || type == ELIFFALSE || type == ELIFGUESSFALSE)
   1.602 +					type = gobble(filep, file, file_red);
   1.603 +				if (type == ELSE)
   1.604 +					gobble(filep, file, file_red);
   1.605 +			}
   1.606 +			else {
   1.607 +				debug(1,(type == IFDEF ?
   1.608 +				    "line %d: %s !def'd in %s via %s%s\n" : "",
   1.609 +				    filep->f_line, line,
   1.610 +				    file->i_file, file_red->i_file, ": gobble"));
   1.611 +				type = gobble(filep, file, file_red);
   1.612 +				if (type == ELSE)
   1.613 +					find_includes(filep, file,
   1.614 +						file_red, recursion+1, failOK);
   1.615 +				else if (type == ELIF)
   1.616 +				    	goto doif;
   1.617 +				else if (type == ELIFFALSE || type == ELIFGUESSFALSE)
   1.618 +				    	goto doiffalse;
   1.619 +			}
   1.620 +			break;
   1.621 +		case ELSE:
   1.622 +		case ELIFFALSE:
   1.623 +		case ELIFGUESSFALSE:
   1.624 +		case ELIF:
   1.625 +			if (!recursion)
   1.626 +				gobble(filep, file, file_red);
   1.627 +		case ENDIF:
   1.628 +			if (recursion)
   1.629 +				return(type);
   1.630 +		case DEFINE:
   1.631 +			define(line, file);
   1.632 +			break;
   1.633 +		case UNDEF:
   1.634 +			if (!*line) {
   1.635 +			    warning("%s", file_red->i_file);
   1.636 +			    if (file_red != file)
   1.637 +				warning1(" (reading %s)", file->i_file);
   1.638 +			    warning1(", line %d: incomplete undef == \"%s\"\n",
   1.639 +				filep->f_line, line);
   1.640 +			    break;
   1.641 +			}
   1.642 +			undefine(line, file_red);
   1.643 +			break;
   1.644 +		case INCLUDE:
   1.645 +		case INCLUDEDOT:
   1.646 +		case INCLUDENEXT:
   1.647 +		case INCLUDENEXTDOT:
   1.648 +			inclistp = inclistnext;
   1.649 +			includedirsp = includedirsnext;
   1.650 +			debug(2,("%s, reading %s, includes %s\n",
   1.651 +				file_red->i_file, file->i_file, line));
   1.652 +			add_include(filep, file, file_red, line, type, failOK);
   1.653 +			inclistnext = inclistp;
   1.654 +			includedirsnext = includedirsp;
   1.655 +			break;
   1.656 +		case ERROR:
   1.657 +		case WARNING:
   1.658 +		    	warning("%s", file_red->i_file);
   1.659 +			if (file_red != file)
   1.660 +				warning1(" (reading %s)", file->i_file);
   1.661 +			warning1(", line %d: %s\n",
   1.662 +				 filep->f_line, line);
   1.663 +		    	break;
   1.664 +		    
   1.665 +		case PRAGMA:
   1.666 +		case IDENT:
   1.667 +		case SCCS:
   1.668 +		case EJECT:
   1.669 +			break;
   1.670 +		case -1:
   1.671 +			warning("%s", file_red->i_file);
   1.672 +			if (file_red != file)
   1.673 +			    warning1(" (reading %s)", file->i_file);
   1.674 +			warning1(", line %d: unknown directive == \"%s\"\n",
   1.675 +				 filep->f_line, line);
   1.676 +			break;
   1.677 +		case -2:
   1.678 +			warning("%s", file_red->i_file);
   1.679 +			if (file_red != file)
   1.680 +			    warning1(" (reading %s)", file->i_file);
   1.681 +			warning1(", line %d: incomplete include == \"%s\"\n",
   1.682 +				 filep->f_line, line);
   1.683 +			break;
   1.684 +		}
   1.685 +	}
   1.686 +	file->i_flags |= FINISHED;
   1.687 +	debug(2,("finished with %s\n", file->i_file));
   1.688 +	return(-1);
   1.689 +}

mercurial