security/nss/coreconf/mkdepend/parse.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* $Xorg: parse.c,v 1.6 2001/02/09 02:03:16 xorgcvs Exp $ */
     2 /*
     4 Copyright (c) 1993, 1994, 1998 The Open Group
     6 Permission to use, copy, modify, distribute, and sell this software and its
     7 documentation for any purpose is hereby granted without fee, provided that
     8 the above copyright notice appear in all copies and that both that
     9 copyright notice and this permission notice appear in supporting
    10 documentation.
    12 The above copyright notice and this permission notice shall be included in
    13 all copies or substantial portions of the Software.
    15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
    18 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
    19 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
    20 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    22 Except as contained in this notice, the name of The Open Group shall not be
    23 used in advertising or otherwise to promote the sale, use or other dealings
    24 in this Software without prior written authorization from The Open Group.
    26 */
    27 /* $XFree86: xc/config/makedepend/parse.c,v 1.12 2002/02/26 05:09:10 tsi Exp $ */
    29 #include "def.h"
    31 extern char	*directives[];
    32 extern struct inclist	inclist[ MAXFILES ],
    33 			*inclistnext,
    34 			maininclist;
    35 extern char	*includedirs[ ],
    36 		**includedirsnext;
    38 static int deftype (char *line, struct filepointer *filep,
    39 		    struct inclist *file_red, struct inclist *file,
    40 		    int parse_it);
    41 static int zero_value(char *filename, char *exp, struct filepointer *filep,
    42 		    struct inclist *file_red);
    43 static int merge2defines(struct inclist *file1, struct inclist *file2);
    45 static int
    46 gobble(struct filepointer *filep, struct inclist *file,
    47        struct inclist *file_red)
    48 {
    49 	char	*line;
    50 	int	type;
    52 	while ((line = getnextline(filep))) {
    53 		switch(type = deftype(line, filep, file_red, file, FALSE)) {
    54 		case IF:
    55 		case IFFALSE:
    56 		case IFGUESSFALSE:
    57 		case IFDEF:
    58 		case IFNDEF:
    59 			type = gobble(filep, file, file_red);
    60 			while ((type == ELIF) || (type == ELIFFALSE) ||
    61 			       (type == ELIFGUESSFALSE))
    62 			    type = gobble(filep, file, file_red);
    63 			if (type == ELSE)
    64 			        (void)gobble(filep, file, file_red);
    65 			break;
    66 		case ELSE:
    67 		case ENDIF:
    68 			debug(0,("%s, line %d: #%s\n",
    69 				file->i_file, filep->f_line,
    70 				directives[type]));
    71 			return(type);
    72 		case DEFINE:
    73 		case UNDEF:
    74 		case INCLUDE:
    75 		case INCLUDEDOT:
    76 		case PRAGMA:
    77 		case ERROR:
    78 		case IDENT:
    79 		case SCCS:
    80 		case EJECT:
    81 		case WARNING:
    82 		case INCLUDENEXT:
    83 		case INCLUDENEXTDOT:
    84 			break;
    85 		case ELIF:
    86 		case ELIFFALSE:
    87 		case ELIFGUESSFALSE:
    88 			return(type);
    89 		case -1:
    90 			warning("%s", file_red->i_file);
    91 			if (file_red != file)
    92 				warning1(" (reading %s)", file->i_file);
    93 			warning1(", line %d: unknown directive == \"%s\"\n",
    94 				filep->f_line, line);
    95 			break;
    96 		}
    97 	}
    98 	return(-1);
    99 }
   101 /*
   102  * Decide what type of # directive this line is.
   103  */
   104 static int 
   105 deftype (char *line, struct filepointer *filep, 
   106 	     struct inclist *file_red, struct inclist *file, int parse_it)
   107 {
   108 	register char	*p;
   109 	char	*directive, savechar, *q;
   110 	register int	ret;
   112 	/*
   113 	 * Parse the directive...
   114 	 */
   115 	directive=line+1;
   116 	while (*directive == ' ' || *directive == '\t')
   117 		directive++;
   119 	p = directive;
   120 	while ((*p == '_') || (*p >= 'a' && *p <= 'z'))
   121 		p++;
   122 	savechar = *p;
   123 	*p = '\0';
   124 	ret = match(directive, directives);
   125 	*p = savechar;
   127 	/* If we don't recognize this compiler directive or we happen to just
   128 	 * be gobbling up text while waiting for an #endif or #elif or #else
   129 	 * in the case of an #elif we must check the zero_value and return an
   130 	 * ELIF or an ELIFFALSE.
   131 	 */
   133 	if (ret == ELIF && !parse_it)
   134 	{
   135 	    while (*p == ' ' || *p == '\t')
   136 		p++;
   137 	    /*
   138 	     * parse an expression.
   139 	     */
   140 	    debug(0,("%s, line %d: #elif %s ",
   141 		   file->i_file, filep->f_line, p));
   142 	    ret = zero_value(file->i_file, p, filep, file_red);
   143 	    if (ret != IF)
   144 	    {
   145 		debug(0,("false...\n"));
   146 		if (ret == IFFALSE)
   147 		    return(ELIFFALSE);
   148 		else
   149 		    return(ELIFGUESSFALSE);
   150 	    }
   151 	    else
   152 	    {
   153 		debug(0,("true...\n"));
   154 		return(ELIF);
   155 	    }
   156 	}
   158 	if (ret < 0 || ! parse_it)
   159 		return(ret);
   161 	/*
   162 	 * now decide how to parse the directive, and do it.
   163 	 */
   164 	while (*p == ' ' || *p == '\t')
   165 		p++;
   166 	q = p + strlen(p);
   167 	do {
   168 		q--;
   169 	} while (*q == ' ' || *q == '\t');
   170 	q[1] = '\0';
   171 	switch (ret) {
   172 	case IF:
   173 		/*
   174 		 * parse an expression.
   175 		 */
   176 		ret = zero_value(file->i_file, p, filep, file_red);
   177 		debug(0,("%s, line %d: %s #if %s\n",
   178 			 file->i_file, filep->f_line, ret?"false":"true", p));
   179 		break;
   180 	case IFDEF:
   181 	case IFNDEF:
   182 		debug(0,("%s, line %d: #%s %s\n",
   183 			file->i_file, filep->f_line, directives[ret], p));
   184 	case UNDEF:
   185 		/*
   186 		 * separate the name of a single symbol.
   187 		 */
   188 		while (isalnum(*p) || *p == '_')
   189 			*line++ = *p++;
   190 		*line = '\0';
   191 		break;
   192 	case INCLUDE:
   193 	case INCLUDENEXT:
   194 		debug(2,("%s, line %d: #include%s %s\n",
   195 			file->i_file, filep->f_line,
   196 			(ret == INCLUDE) ? "" : "_next", p));
   198 		/* Support ANSI macro substitution */
   199 		while (1) {
   200 			struct symtab **sym;
   202 			if (!*p || *p == '"' || *p == '<')
   203 				break;
   205 		    	sym = isdefined(p, file_red, NULL);
   206 			if (!sym)
   207 				break;
   209 			p = (*sym)->s_value;
   210 			debug(3,("%s : #includes SYMBOL %s = %s\n",
   211 			       file->i_incstring,
   212 			       (*sym) -> s_name,
   213 			       (*sym) -> s_value));
   214 			/* mark file as having included a 'soft include' */
   215 			file->i_flags |= INCLUDED_SYM; 
   216 		}
   218 		/*
   219 		 * Separate the name of the include file.
   220 		 */
   221 		while (*p && *p != '"' && *p != '<')
   222 			p++;
   223 		if (! *p)
   224 			return(-2);
   225 		if (*p++ == '"') {
   226 			if (ret == INCLUDE)
   227 				ret = INCLUDEDOT;
   228 			else
   229 				ret = INCLUDENEXTDOT;
   230 			while (*p && *p != '"')
   231 				*line++ = *p++;
   232 		} else
   233 			while (*p && *p != '>')
   234 				*line++ = *p++;
   235 		*line = '\0';
   236 		break;
   237 	case DEFINE:
   238 		/*
   239 		 * copy the definition back to the beginning of the line.
   240 		 */
   241 		strcpy (line, p);
   242 		break;
   243 	case ELSE:
   244 	case ENDIF:
   245 	case ELIF:
   246 	case PRAGMA:
   247 	case ERROR:
   248 	case IDENT:
   249 	case SCCS:
   250 	case EJECT:
   251 	case WARNING:
   252 		debug(0,("%s, line %d: #%s\n",
   253 			file->i_file, filep->f_line, directives[ret]));
   254 		/*
   255 		 * nothing to do.
   256 		 */
   257 		break;
   258 	}
   259 	return(ret);
   260 }
   262 struct symtab **
   263 fdefined(char *symbol, struct inclist *file, struct inclist **srcfile)
   264 {
   265 	struct inclist	**ip;
   266 	struct symtab	**val;
   267 	int	i;
   268 	static int	recurse_lvl = 0;
   270 	if (file->i_flags & DEFCHECKED)
   271 		return(NULL);
   272 	debug(2,("Looking for %s in %s\n", symbol, file->i_file));
   273 	file->i_flags |= DEFCHECKED;
   274 	if ((val = slookup(symbol, file)))
   275 		debug(1,("%s defined in %s as %s\n",
   276 			 symbol, file->i_file, (*val)->s_value));
   277 	if (val == NULL && file->i_list)
   278 	{
   279 		for (ip = file->i_list, i=0; i < file->i_listlen; i++, ip++)
   280 			if (file->i_merged[i]==FALSE) {
   281 				val = fdefined(symbol, *ip, srcfile);
   282 				file->i_merged[i]=merge2defines(file,*ip);
   283 				if (val!=NULL) break;
   284 			}
   285 	}
   286 	else if (val != NULL && srcfile != NULL) *srcfile = file;
   287 	recurse_lvl--;
   288 	file->i_flags &= ~DEFCHECKED;
   290 	return(val);
   291 }
   293 struct symtab **
   294 isdefined(char *symbol, struct inclist *file, struct inclist **srcfile)
   295 {
   296 	struct symtab	**val;
   298 	if ((val = slookup(symbol, &maininclist))) {
   299 		debug(1,("%s defined on command line\n", symbol));
   300 		if (srcfile != NULL) *srcfile = &maininclist;
   301 		return(val);
   302 	}
   303 	if ((val = fdefined(symbol, file, srcfile)))
   304 		return(val);
   305 	debug(1,("%s not defined in %s\n", symbol, file->i_file));
   306 	return(NULL);
   307 }
   309 /*
   310  * Return type based on if the #if expression evaluates to 0
   311  */
   312 static int
   313 zero_value(char *filename,
   314 	   char *exp,
   315 	   struct filepointer *filep,
   316 	   struct inclist *file_red)
   317 {
   318 	if (cppsetup(filename, exp, filep, file_red))
   319 	    return(IFFALSE);
   320 	else
   321 	    return(IF);
   322 }
   324 void
   325 define2(char *name, char *val, struct inclist *file)
   326 {
   327     int first, last, below;
   328     register struct symtab **sp = NULL, **dest;
   329     struct symtab *stab;
   331     /* Make space if it's needed */
   332     if (file->i_defs == NULL)
   333     {
   334 	file->i_defs = (struct symtab **)
   335 			malloc(sizeof (struct symtab*) * SYMTABINC);
   336 	file->i_ndefs = 0;
   337     }
   338     else if (!(file->i_ndefs % SYMTABINC))
   339 	file->i_defs = (struct symtab **)
   340 			realloc(file->i_defs,
   341 			   sizeof(struct symtab*)*(file->i_ndefs+SYMTABINC));
   343     if (file->i_defs == NULL)
   344 	fatalerr("malloc()/realloc() failure in insert_defn()\n");
   346     below = first = 0;
   347     last = file->i_ndefs - 1;
   348     while (last >= first)
   349     {
   350 	/* Fast inline binary search */
   351 	register char *s1;
   352 	register char *s2;
   353 	register int middle = (first + last) / 2;
   355 	/* Fast inline strchr() */
   356 	s1 = name;
   357 	s2 = file->i_defs[middle]->s_name;
   358 	while (*s1++ == *s2++)
   359 	    if (s2[-1] == '\0') break;
   361 	/* If exact match, set sp and break */
   362 	if (*--s1 == *--s2) 
   363 	{
   364 	    sp = file->i_defs + middle;
   365 	    break;
   366 	}
   368 	/* If name > i_defs[middle] ... */
   369 	if (*s1 > *s2) 
   370 	{
   371 	    below = first;
   372 	    first = middle + 1;
   373 	}
   374 	/* else ... */
   375 	else
   376 	{
   377 	    below = last = middle - 1;
   378 	}
   379     }
   381     /* Search is done.  If we found an exact match to the symbol name,
   382        just replace its s_value */
   383     if (sp != NULL)
   384     {
   385 	debug(1,("redefining %s from %s to %s in file %s\n",
   386 		name, (*sp)->s_value, val, file->i_file));
   387 	free((*sp)->s_value);
   388 	(*sp)->s_value = copy(val);
   389 	return;
   390     }
   392     sp = file->i_defs + file->i_ndefs++;
   393     dest = file->i_defs + below + 1;
   394     while (sp > dest)
   395     {
   396 	*sp = sp[-1];
   397 	sp--;
   398     }
   399     stab = (struct symtab *) malloc(sizeof (struct symtab));
   400     if (stab == NULL)
   401 	fatalerr("malloc()/realloc() failure in insert_defn()\n");
   403     debug(1,("defining %s to %s in file %s\n", name, val, file->i_file));
   404     stab->s_name = copy(name);
   405     stab->s_value = copy(val);
   406     *sp = stab;
   407 }
   409 void
   410 define(char *def, struct inclist *file)
   411 {
   412     char *val;
   414     /* Separate symbol name and its value */
   415     val = def;
   416     while (isalnum(*val) || *val == '_')
   417 	val++;
   418     if (*val)
   419 	*val++ = '\0';
   420     while (*val == ' ' || *val == '\t')
   421 	val++;
   423     if (!*val)
   424 	val = "1";
   425     define2(def, val, file);
   426 }
   428 struct symtab **
   429 slookup(char *symbol, struct inclist *file)
   430 {
   431 	register int first = 0;
   432 	register int last = file->i_ndefs - 1;
   434 	if (file) while (last >= first)
   435 	{
   436 	    /* Fast inline binary search */
   437 	    register char *s1;
   438 	    register char *s2;
   439 	    register int middle = (first + last) / 2;
   441 	    /* Fast inline strchr() */
   442 	    s1 = symbol;
   443 	    s2 = file->i_defs[middle]->s_name;
   444 	    while (*s1++ == *s2++)
   445 	        if (s2[-1] == '\0') break;
   447 	    /* If exact match, we're done */
   448 	    if (*--s1 == *--s2) 
   449 	    {
   450 	        return file->i_defs + middle;
   451 	    }
   453 	    /* If symbol > i_defs[middle] ... */
   454 	    if (*s1 > *s2) 
   455 	    {
   456 	        first = middle + 1;
   457 	    }
   458 	    /* else ... */
   459 	    else
   460 	    {
   461 	        last = middle - 1;
   462 	    }
   463 	}
   464 	return(NULL);
   465 }
   467 static int 
   468 merge2defines(struct inclist *file1, struct inclist *file2)
   469 {
   470 	int i;
   472 	if ((file1==NULL) || (file2==NULL) ||
   473 	    !(file2->i_flags & FINISHED))
   474 		return 0;
   476 	for (i=0; i < file2->i_listlen; i++)
   477 		if (file2->i_merged[i]==FALSE)
   478 			return 0;
   480 	{
   481 		int first1 = 0;
   482 		int last1 = file1->i_ndefs - 1;
   484 		int first2 = 0;
   485 		int last2 = file2->i_ndefs - 1;
   487                 int first=0;
   488                 struct symtab** i_defs = NULL;
   489 		int deflen=file1->i_ndefs+file2->i_ndefs;
   491 		debug(2,("merging %s into %s\n",
   492 			file2->i_file, file1->i_file));
   494                 if (deflen>0)
   495                 { 
   496                 	/* make sure deflen % SYMTABINC == 0 is still true */
   497                 	deflen += (SYMTABINC - deflen % SYMTABINC) % SYMTABINC;
   498                 	i_defs=(struct symtab**)
   499 			    malloc(deflen*sizeof(struct symtab*));
   500                 	if (i_defs==NULL) return 0;
   501         	}
   503         	while ((last1 >= first1) && (last2 >= first2))
   504         	{
   505 	    		char *s1=file1->i_defs[first1]->s_name;
   506 	    		char *s2=file2->i_defs[first2]->s_name;
   508      			if (strcmp(s1,s2) < 0)
   509                         	i_defs[first++]=file1->i_defs[first1++];
   510      			else if (strcmp(s1,s2) > 0)
   511                         	i_defs[first++]=file2->i_defs[first2++];
   512                         else /* equal */
   513                         {
   514                         	i_defs[first++]=file2->i_defs[first2++];
   515                                 first1++;
   516                         }
   517         	}
   518         	while (last1 >= first1)
   519         	{
   520                         i_defs[first++]=file1->i_defs[first1++];
   521         	}
   522         	while (last2 >= first2)
   523         	{
   524                         i_defs[first++]=file2->i_defs[first2++];
   525         	}
   527                 if (file1->i_defs) free(file1->i_defs);
   528                 file1->i_defs=i_defs;
   529                 file1->i_ndefs=first;
   531 		return 1;
   532   	}
   533 }
   535 void
   536 undefine(char *symbol, struct inclist *file)
   537 {
   538 	register struct symtab **ptr;
   539 	struct inclist *srcfile;
   540 	while ((ptr = isdefined(symbol, file, &srcfile)) != NULL)
   541 	{
   542 	    srcfile->i_ndefs--;
   543 	    for (; ptr < srcfile->i_defs + srcfile->i_ndefs; ptr++)
   544 		*ptr = ptr[1];
   545 	}
   546 }
   548 int
   549 find_includes(struct filepointer *filep, struct inclist *file, 
   550 	      struct inclist *file_red, int recursion, boolean failOK)
   551 {
   552 	struct inclist	*inclistp;
   553 	char		**includedirsp;
   554 	register char	*line;
   555 	register int	type;
   556 	boolean recfailOK;
   558 	while ((line = getnextline(filep))) {
   559 		switch(type = deftype(line, filep, file_red, file, TRUE)) {
   560 		case IF:
   561 		doif:
   562 			type = find_includes(filep, file,
   563 				file_red, recursion+1, failOK);
   564 			while ((type == ELIF) || (type == ELIFFALSE) ||
   565 			       (type == ELIFGUESSFALSE))
   566 				type = gobble(filep, file, file_red);
   567 			if (type == ELSE)
   568 				gobble(filep, file, file_red);
   569 			break;
   570 		case IFFALSE:
   571 		case IFGUESSFALSE:
   572 		    doiffalse:
   573 			if (type == IFGUESSFALSE || type == ELIFGUESSFALSE)
   574 			    recfailOK = TRUE;
   575 			else
   576 			    recfailOK = failOK;
   577 			type = gobble(filep, file, file_red);
   578 			if (type == ELSE)
   579 			    find_includes(filep, file,
   580 					  file_red, recursion+1, recfailOK);
   581 			else
   582 			if (type == ELIF)
   583 			    goto doif;
   584 			else
   585 			if ((type == ELIFFALSE) || (type == ELIFGUESSFALSE))
   586 			    goto doiffalse;
   587 			break;
   588 		case IFDEF:
   589 		case IFNDEF:
   590 			if ((type == IFDEF && isdefined(line, file_red, NULL))
   591 			 || (type == IFNDEF && !isdefined(line, file_red, NULL))) {
   592 				debug(1,(type == IFNDEF ?
   593 				    "line %d: %s !def'd in %s via %s%s\n" : "",
   594 				    filep->f_line, line,
   595 				    file->i_file, file_red->i_file, ": doit"));
   596 				type = find_includes(filep, file,
   597 					file_red, recursion+1, failOK);
   598 				while (type == ELIF || type == ELIFFALSE || type == ELIFGUESSFALSE)
   599 					type = gobble(filep, file, file_red);
   600 				if (type == ELSE)
   601 					gobble(filep, file, file_red);
   602 			}
   603 			else {
   604 				debug(1,(type == IFDEF ?
   605 				    "line %d: %s !def'd in %s via %s%s\n" : "",
   606 				    filep->f_line, line,
   607 				    file->i_file, file_red->i_file, ": gobble"));
   608 				type = gobble(filep, file, file_red);
   609 				if (type == ELSE)
   610 					find_includes(filep, file,
   611 						file_red, recursion+1, failOK);
   612 				else if (type == ELIF)
   613 				    	goto doif;
   614 				else if (type == ELIFFALSE || type == ELIFGUESSFALSE)
   615 				    	goto doiffalse;
   616 			}
   617 			break;
   618 		case ELSE:
   619 		case ELIFFALSE:
   620 		case ELIFGUESSFALSE:
   621 		case ELIF:
   622 			if (!recursion)
   623 				gobble(filep, file, file_red);
   624 		case ENDIF:
   625 			if (recursion)
   626 				return(type);
   627 		case DEFINE:
   628 			define(line, file);
   629 			break;
   630 		case UNDEF:
   631 			if (!*line) {
   632 			    warning("%s", file_red->i_file);
   633 			    if (file_red != file)
   634 				warning1(" (reading %s)", file->i_file);
   635 			    warning1(", line %d: incomplete undef == \"%s\"\n",
   636 				filep->f_line, line);
   637 			    break;
   638 			}
   639 			undefine(line, file_red);
   640 			break;
   641 		case INCLUDE:
   642 		case INCLUDEDOT:
   643 		case INCLUDENEXT:
   644 		case INCLUDENEXTDOT:
   645 			inclistp = inclistnext;
   646 			includedirsp = includedirsnext;
   647 			debug(2,("%s, reading %s, includes %s\n",
   648 				file_red->i_file, file->i_file, line));
   649 			add_include(filep, file, file_red, line, type, failOK);
   650 			inclistnext = inclistp;
   651 			includedirsnext = includedirsp;
   652 			break;
   653 		case ERROR:
   654 		case WARNING:
   655 		    	warning("%s", file_red->i_file);
   656 			if (file_red != file)
   657 				warning1(" (reading %s)", file->i_file);
   658 			warning1(", line %d: %s\n",
   659 				 filep->f_line, line);
   660 		    	break;
   662 		case PRAGMA:
   663 		case IDENT:
   664 		case SCCS:
   665 		case EJECT:
   666 			break;
   667 		case -1:
   668 			warning("%s", file_red->i_file);
   669 			if (file_red != file)
   670 			    warning1(" (reading %s)", file->i_file);
   671 			warning1(", line %d: unknown directive == \"%s\"\n",
   672 				 filep->f_line, line);
   673 			break;
   674 		case -2:
   675 			warning("%s", file_red->i_file);
   676 			if (file_red != file)
   677 			    warning1(" (reading %s)", file->i_file);
   678 			warning1(", line %d: incomplete include == \"%s\"\n",
   679 				 filep->f_line, line);
   680 			break;
   681 		}
   682 	}
   683 	file->i_flags |= FINISHED;
   684 	debug(2,("finished with %s\n", file->i_file));
   685 	return(-1);
   686 }

mercurial