PageRenderTime 95ms CodeModel.GetById 34ms app.highlight 52ms RepoModel.GetById 2ms app.codeStats 0ms

/js/lib/Socket.IO-node/support/expresso/deps/jscoverage/js/config/mkdepend/parse.c

http://github.com/onedayitwillmake/RealtimeMultiplayerNodeJs
C | 686 lines | 557 code | 54 blank | 75 comment | 187 complexity | 9838371bb6f9ffc61b4305b4693e2fd7 MD5 | raw file
  1/* $Xorg: parse.c,v 1.6 2001/02/09 02:03:16 xorgcvs Exp $ */
  2/*
  3
  4Copyright (c) 1993, 1994, 1998 The Open Group
  5
  6Permission to use, copy, modify, distribute, and sell this software and its
  7documentation for any purpose is hereby granted without fee, provided that
  8the above copyright notice appear in all copies and that both that
  9copyright notice and this permission notice appear in supporting
 10documentation.
 11
 12The above copyright notice and this permission notice shall be included in
 13all copies or substantial portions of the Software.
 14
 15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 17FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
 18OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
 19AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 20CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 21
 22Except as contained in this notice, the name of The Open Group shall not be
 23used in advertising or otherwise to promote the sale, use or other dealings
 24in this Software without prior written authorization from The Open Group.
 25
 26*/
 27/* $XFree86: xc/config/makedepend/parse.c,v 1.12 2002/02/26 05:09:10 tsi Exp $ */
 28
 29#include "def.h"
 30
 31extern char	*directives[];
 32extern struct inclist	inclist[ MAXFILES ],
 33			*inclistnext,
 34			maininclist;
 35extern char	*includedirs[ ],
 36		**includedirsnext;
 37
 38static int deftype (char *line, struct filepointer *filep,
 39		    struct inclist *file_red, struct inclist *file,
 40		    int parse_it);
 41static int zero_value(char *filename, char *exp, struct filepointer *filep,
 42		    struct inclist *file_red);
 43static int merge2defines(struct inclist *file1, struct inclist *file2);
 44
 45static int
 46gobble(struct filepointer *filep, struct inclist *file,
 47       struct inclist *file_red)
 48{
 49	char	*line;
 50	int	type;
 51
 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}
100
101/*
102 * Decide what type of # directive this line is.
103 */
104static int 
105deftype (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;
111
112	/*
113	 * Parse the directive...
114	 */
115	directive=line+1;
116	while (*directive == ' ' || *directive == '\t')
117		directive++;
118
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;
126
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	 */
132
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	}
157
158	if (ret < 0 || ! parse_it)
159		return(ret);
160
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));
197
198		/* Support ANSI macro substitution */
199		while (1) {
200			struct symtab **sym;
201
202			if (!*p || *p == '"' || *p == '<')
203				break;
204
205		    	sym = isdefined(p, file_red, NULL);
206			if (!sym)
207				break;
208
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		}
217
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}
261
262struct symtab **
263fdefined(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;
269
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;
289
290	return(val);
291}
292
293struct symtab **
294isdefined(char *symbol, struct inclist *file, struct inclist **srcfile)
295{
296	struct symtab	**val;
297
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}
308
309/*
310 * Return type based on if the #if expression evaluates to 0
311 */
312static int
313zero_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}
323
324void
325define2(char *name, char *val, struct inclist *file)
326{
327    int first, last, below;
328    register struct symtab **sp = NULL, **dest;
329    struct symtab *stab;
330
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));
342
343    if (file->i_defs == NULL)
344	fatalerr("malloc()/realloc() failure in insert_defn()\n");
345
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;
354
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;
360
361	/* If exact match, set sp and break */
362	if (*--s1 == *--s2) 
363	{
364	    sp = file->i_defs + middle;
365	    break;
366	}
367
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    }
380
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    }
391
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");
402
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}
408
409void
410define(char *def, struct inclist *file)
411{
412    char *val;
413
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++;
422
423    if (!*val)
424	val = "1";
425    define2(def, val, file);
426}
427
428struct symtab **
429slookup(char *symbol, struct inclist *file)
430{
431	register int first = 0;
432	register int last = file->i_ndefs - 1;
433
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;
440
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;
446
447	    /* If exact match, we're done */
448	    if (*--s1 == *--s2) 
449	    {
450	        return file->i_defs + middle;
451	    }
452
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}
466
467static int 
468merge2defines(struct inclist *file1, struct inclist *file2)
469{
470	int i;
471
472	if ((file1==NULL) || (file2==NULL) ||
473	    !(file2->i_flags & FINISHED))
474		return 0;
475
476	for (i=0; i < file2->i_listlen; i++)
477		if (file2->i_merged[i]==FALSE)
478			return 0;
479
480	{
481		int first1 = 0;
482		int last1 = file1->i_ndefs - 1;
483
484		int first2 = 0;
485		int last2 = file2->i_ndefs - 1;
486
487                int first=0;
488                struct symtab** i_defs = NULL;
489		int deflen=file1->i_ndefs+file2->i_ndefs;
490
491		debug(2,("merging %s into %s\n",
492			file2->i_file, file1->i_file));
493
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        	}
502
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;
507
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        	}
526
527                if (file1->i_defs) free(file1->i_defs);
528                file1->i_defs=i_defs;
529                file1->i_ndefs=first;
530                
531		return 1;
532  	}
533}
534
535void
536undefine(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}
547
548int
549find_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;
557
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;
661		    
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}