parse.c revision 0eb10989
10eb10989Smrg/* $Xorg: parse.c,v 1.6 2001/02/09 02:03:16 xorgcvs Exp $ */ 20eb10989Smrg/* 30eb10989Smrg 40eb10989SmrgCopyright (c) 1993, 1994, 1998 The Open Group 50eb10989Smrg 60eb10989SmrgPermission to use, copy, modify, distribute, and sell this software and its 70eb10989Smrgdocumentation for any purpose is hereby granted without fee, provided that 80eb10989Smrgthe above copyright notice appear in all copies and that both that 90eb10989Smrgcopyright notice and this permission notice appear in supporting 100eb10989Smrgdocumentation. 110eb10989Smrg 120eb10989SmrgThe above copyright notice and this permission notice shall be included in 130eb10989Smrgall copies or substantial portions of the Software. 140eb10989Smrg 150eb10989SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 160eb10989SmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 170eb10989SmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 180eb10989SmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 190eb10989SmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 200eb10989SmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 210eb10989Smrg 220eb10989SmrgExcept as contained in this notice, the name of The Open Group shall not be 230eb10989Smrgused in advertising or otherwise to promote the sale, use or other dealings 240eb10989Smrgin this Software without prior written authorization from The Open Group. 250eb10989Smrg 260eb10989Smrg*/ 270eb10989Smrg/* $XFree86: xc/config/makedepend/parse.c,v 1.11 2001/12/17 20:52:22 dawes Exp $ */ 280eb10989Smrg 290eb10989Smrg#include "def.h" 300eb10989Smrg 310eb10989Smrgextern char *directives[]; 320eb10989Smrgextern struct inclist inclist[ MAXFILES ], 330eb10989Smrg *inclistnext, 340eb10989Smrg maininclist; 350eb10989Smrgextern char *includedirs[ ], 360eb10989Smrg **includedirsnext; 370eb10989Smrg 380eb10989Smrgstatic int deftype (char *line, struct filepointer *filep, 390eb10989Smrg struct inclist *file_red, struct inclist *file, 400eb10989Smrg int parse_it); 410eb10989Smrgstatic int zero_value(char *filename, char *exp, struct filepointer *filep, 420eb10989Smrg struct inclist *file_red); 430eb10989Smrgstatic int merge2defines(struct inclist *file1, struct inclist *file2); 440eb10989Smrg 450eb10989Smrgstatic int 460eb10989Smrggobble(struct filepointer *filep, struct inclist *file, 470eb10989Smrg struct inclist *file_red) 480eb10989Smrg{ 490eb10989Smrg char *line; 500eb10989Smrg int type; 510eb10989Smrg 520eb10989Smrg while ((line = getnextline(filep))) { 530eb10989Smrg switch(type = deftype(line, filep, file_red, file, FALSE)) { 540eb10989Smrg case IF: 550eb10989Smrg case IFFALSE: 560eb10989Smrg case IFGUESSFALSE: 570eb10989Smrg case IFDEF: 580eb10989Smrg case IFNDEF: 590eb10989Smrg type = gobble(filep, file, file_red); 600eb10989Smrg while ((type == ELIF) || (type == ELIFFALSE) || 610eb10989Smrg (type == ELIFGUESSFALSE)) 620eb10989Smrg type = gobble(filep, file, file_red); 630eb10989Smrg if (type == ELSE) 640eb10989Smrg (void)gobble(filep, file, file_red); 650eb10989Smrg break; 660eb10989Smrg case ELSE: 670eb10989Smrg case ENDIF: 680eb10989Smrg debug(0,("%s, line %d: #%s\n", 690eb10989Smrg file->i_file, filep->f_line, 700eb10989Smrg directives[type])); 710eb10989Smrg return(type); 720eb10989Smrg case DEFINE: 730eb10989Smrg case UNDEF: 740eb10989Smrg case INCLUDE: 750eb10989Smrg case INCLUDEDOT: 760eb10989Smrg case PRAGMA: 770eb10989Smrg case ERROR: 780eb10989Smrg case IDENT: 790eb10989Smrg case SCCS: 800eb10989Smrg case EJECT: 810eb10989Smrg case WARNING: 820eb10989Smrg case INCLUDENEXT: 830eb10989Smrg case INCLUDENEXTDOT: 840eb10989Smrg break; 850eb10989Smrg case ELIF: 860eb10989Smrg case ELIFFALSE: 870eb10989Smrg case ELIFGUESSFALSE: 880eb10989Smrg return(type); 890eb10989Smrg case -1: 900eb10989Smrg warning("%s", file_red->i_file); 910eb10989Smrg if (file_red != file) 920eb10989Smrg warning1(" (reading %s)", file->i_file); 930eb10989Smrg warning1(", line %d: unknown directive == \"%s\"\n", 940eb10989Smrg filep->f_line, line); 950eb10989Smrg break; 960eb10989Smrg } 970eb10989Smrg } 980eb10989Smrg return(-1); 990eb10989Smrg} 1000eb10989Smrg 1010eb10989Smrg/* 1020eb10989Smrg * Decide what type of # directive this line is. 1030eb10989Smrg */ 1040eb10989Smrgstatic int 1050eb10989Smrgdeftype (char *line, struct filepointer *filep, 1060eb10989Smrg struct inclist *file_red, struct inclist *file, int parse_it) 1070eb10989Smrg{ 1080eb10989Smrg register char *p; 1090eb10989Smrg char *directive, savechar, *q; 1100eb10989Smrg register int ret; 1110eb10989Smrg 1120eb10989Smrg /* 1130eb10989Smrg * Parse the directive... 1140eb10989Smrg */ 1150eb10989Smrg directive=line+1; 1160eb10989Smrg while (*directive == ' ' || *directive == '\t') 1170eb10989Smrg directive++; 1180eb10989Smrg 1190eb10989Smrg p = directive; 1200eb10989Smrg while ((*p == '_') || (*p >= 'a' && *p <= 'z')) 1210eb10989Smrg p++; 1220eb10989Smrg savechar = *p; 1230eb10989Smrg *p = '\0'; 1240eb10989Smrg ret = match(directive, directives); 1250eb10989Smrg *p = savechar; 1260eb10989Smrg 1270eb10989Smrg /* If we don't recognize this compiler directive or we happen to just 1280eb10989Smrg * be gobbling up text while waiting for an #endif or #elif or #else 1290eb10989Smrg * in the case of an #elif we must check the zero_value and return an 1300eb10989Smrg * ELIF or an ELIFFALSE. 1310eb10989Smrg */ 1320eb10989Smrg 1330eb10989Smrg if (ret == ELIF && !parse_it) 1340eb10989Smrg { 1350eb10989Smrg while (*p == ' ' || *p == '\t') 1360eb10989Smrg p++; 1370eb10989Smrg /* 1380eb10989Smrg * parse an expression. 1390eb10989Smrg */ 1400eb10989Smrg debug(0,("%s, line %d: #elif %s ", 1410eb10989Smrg file->i_file, filep->f_line, p)); 1420eb10989Smrg ret = zero_value(file->i_file, p, filep, file_red); 1430eb10989Smrg if (ret != IF) 1440eb10989Smrg { 1450eb10989Smrg debug(0,("false...\n")); 1460eb10989Smrg if (ret == IFFALSE) 1470eb10989Smrg return(ELIFFALSE); 1480eb10989Smrg else 1490eb10989Smrg return(ELIFGUESSFALSE); 1500eb10989Smrg } 1510eb10989Smrg else 1520eb10989Smrg { 1530eb10989Smrg debug(0,("true...\n")); 1540eb10989Smrg return(ELIF); 1550eb10989Smrg } 1560eb10989Smrg } 1570eb10989Smrg 1580eb10989Smrg if (ret < 0 || ! parse_it) 1590eb10989Smrg return(ret); 1600eb10989Smrg 1610eb10989Smrg /* 1620eb10989Smrg * now decide how to parse the directive, and do it. 1630eb10989Smrg */ 1640eb10989Smrg while (*p == ' ' || *p == '\t') 1650eb10989Smrg p++; 1660eb10989Smrg q = p + strlen(p); 1670eb10989Smrg do { 1680eb10989Smrg q--; 1690eb10989Smrg } while (*q == ' ' || *q == '\t'); 1700eb10989Smrg q[1] = '\0'; 1710eb10989Smrg switch (ret) { 1720eb10989Smrg case IF: 1730eb10989Smrg /* 1740eb10989Smrg * parse an expression. 1750eb10989Smrg */ 1760eb10989Smrg ret = zero_value(file->i_file, p, filep, file_red); 1770eb10989Smrg debug(0,("%s, line %d: %s #if %s\n", 1780eb10989Smrg file->i_file, filep->f_line, ret?"false":"true", p)); 1790eb10989Smrg break; 1800eb10989Smrg case IFDEF: 1810eb10989Smrg case IFNDEF: 1820eb10989Smrg debug(0,("%s, line %d: #%s %s\n", 1830eb10989Smrg file->i_file, filep->f_line, directives[ret], p)); 1840eb10989Smrg case UNDEF: 1850eb10989Smrg /* 1860eb10989Smrg * separate the name of a single symbol. 1870eb10989Smrg */ 1880eb10989Smrg while (isalnum(*p) || *p == '_') 1890eb10989Smrg *line++ = *p++; 1900eb10989Smrg *line = '\0'; 1910eb10989Smrg break; 1920eb10989Smrg case INCLUDE: 1930eb10989Smrg case INCLUDENEXT: 1940eb10989Smrg debug(2,("%s, line %d: #include%s %s\n", 1950eb10989Smrg file->i_file, filep->f_line, 1960eb10989Smrg (ret == INCLUDE) ? "" : "_next", p)); 1970eb10989Smrg 1980eb10989Smrg /* Support ANSI macro substitution */ 1990eb10989Smrg while (1) { 2000eb10989Smrg struct symtab **sym; 2010eb10989Smrg 2020eb10989Smrg if (!*p || *p == '"' || *p == '<') 2030eb10989Smrg break; 2040eb10989Smrg 2050eb10989Smrg sym = isdefined(p, file_red, NULL); 2060eb10989Smrg if (!sym) 2070eb10989Smrg break; 2080eb10989Smrg 2090eb10989Smrg p = (*sym)->s_value; 2100eb10989Smrg debug(3,("%s : #includes SYMBOL %s = %s\n", 2110eb10989Smrg file->i_incstring, 2120eb10989Smrg (*sym) -> s_name, 2130eb10989Smrg (*sym) -> s_value)); 2140eb10989Smrg /* mark file as having included a 'soft include' */ 2150eb10989Smrg file->i_flags |= INCLUDED_SYM; 2160eb10989Smrg } 2170eb10989Smrg 2180eb10989Smrg /* 2190eb10989Smrg * Separate the name of the include file. 2200eb10989Smrg */ 2210eb10989Smrg while (*p && *p != '"' && *p != '<') 2220eb10989Smrg p++; 2230eb10989Smrg if (! *p) 2240eb10989Smrg return(-2); 2250eb10989Smrg if (*p++ == '"') { 2260eb10989Smrg if (ret == INCLUDE) 2270eb10989Smrg ret = INCLUDEDOT; 2280eb10989Smrg else 2290eb10989Smrg ret = INCLUDENEXTDOT; 2300eb10989Smrg while (*p && *p != '"') 2310eb10989Smrg *line++ = *p++; 2320eb10989Smrg } else 2330eb10989Smrg while (*p && *p != '>') 2340eb10989Smrg *line++ = *p++; 2350eb10989Smrg *line = '\0'; 2360eb10989Smrg break; 2370eb10989Smrg case DEFINE: 2380eb10989Smrg /* 2390eb10989Smrg * copy the definition back to the beginning of the line. 2400eb10989Smrg */ 2410eb10989Smrg strcpy (line, p); 2420eb10989Smrg break; 2430eb10989Smrg case ELSE: 2440eb10989Smrg case ENDIF: 2450eb10989Smrg case ELIF: 2460eb10989Smrg case PRAGMA: 2470eb10989Smrg case ERROR: 2480eb10989Smrg case IDENT: 2490eb10989Smrg case SCCS: 2500eb10989Smrg case EJECT: 2510eb10989Smrg case WARNING: 2520eb10989Smrg debug(0,("%s, line %d: #%s\n", 2530eb10989Smrg file->i_file, filep->f_line, directives[ret])); 2540eb10989Smrg /* 2550eb10989Smrg * nothing to do. 2560eb10989Smrg */ 2570eb10989Smrg break; 2580eb10989Smrg } 2590eb10989Smrg return(ret); 2600eb10989Smrg} 2610eb10989Smrg 2620eb10989Smrgstruct symtab ** 2630eb10989Smrgfdefined(char *symbol, struct inclist *file, struct inclist **srcfile) 2640eb10989Smrg{ 2650eb10989Smrg struct inclist **ip; 2660eb10989Smrg struct symtab **val; 2670eb10989Smrg int i; 2680eb10989Smrg static int recurse_lvl = 0; 2690eb10989Smrg 2700eb10989Smrg if (file->i_flags & DEFCHECKED) 2710eb10989Smrg return(NULL); 2720eb10989Smrg debug(2,("Looking for %s in %s\n", symbol, file->i_file)); 2730eb10989Smrg file->i_flags |= DEFCHECKED; 2740eb10989Smrg if ((val = slookup(symbol, file))) 2750eb10989Smrg debug(1,("%s defined in %s as %s\n", 2760eb10989Smrg symbol, file->i_file, (*val)->s_value)); 2770eb10989Smrg if (val == NULL && file->i_list) 2780eb10989Smrg { 2790eb10989Smrg for (ip = file->i_list, i=0; i < file->i_listlen; i++, ip++) 2800eb10989Smrg if (file->i_merged[i]==FALSE) { 2810eb10989Smrg val = fdefined(symbol, *ip, srcfile); 2820eb10989Smrg file->i_merged[i]=merge2defines(file,*ip); 2830eb10989Smrg if (val!=NULL) break; 2840eb10989Smrg } 2850eb10989Smrg } 2860eb10989Smrg else if (val != NULL && srcfile != NULL) *srcfile = file; 2870eb10989Smrg recurse_lvl--; 2880eb10989Smrg file->i_flags &= ~DEFCHECKED; 2890eb10989Smrg 2900eb10989Smrg return(val); 2910eb10989Smrg} 2920eb10989Smrg 2930eb10989Smrgstruct symtab ** 2940eb10989Smrgisdefined(char *symbol, struct inclist *file, struct inclist **srcfile) 2950eb10989Smrg{ 2960eb10989Smrg struct symtab **val; 2970eb10989Smrg 2980eb10989Smrg if ((val = slookup(symbol, &maininclist))) { 2990eb10989Smrg debug(1,("%s defined on command line\n", symbol)); 3000eb10989Smrg if (srcfile != NULL) *srcfile = &maininclist; 3010eb10989Smrg return(val); 3020eb10989Smrg } 3030eb10989Smrg if ((val = fdefined(symbol, file, srcfile))) 3040eb10989Smrg return(val); 3050eb10989Smrg debug(1,("%s not defined in %s\n", symbol, file->i_file)); 3060eb10989Smrg return(NULL); 3070eb10989Smrg} 3080eb10989Smrg 3090eb10989Smrg/* 3100eb10989Smrg * Return type based on if the #if expression evaluates to 0 3110eb10989Smrg */ 3120eb10989Smrgstatic int 3130eb10989Smrgzero_value(char *filename, 3140eb10989Smrg char *exp, 3150eb10989Smrg struct filepointer *filep, 3160eb10989Smrg struct inclist *file_red) 3170eb10989Smrg{ 3180eb10989Smrg if (cppsetup(filename, exp, filep, file_red)) 3190eb10989Smrg return(IFFALSE); 3200eb10989Smrg else 3210eb10989Smrg return(IF); 3220eb10989Smrg} 3230eb10989Smrg 3240eb10989Smrgvoid 3250eb10989Smrgdefine2(char *name, char *val, struct inclist *file) 3260eb10989Smrg{ 3270eb10989Smrg int first, last, below; 3280eb10989Smrg register struct symtab **sp = NULL, **dest; 3290eb10989Smrg struct symtab *stab; 3300eb10989Smrg 3310eb10989Smrg /* Make space if it's needed */ 3320eb10989Smrg if (file->i_defs == NULL) 3330eb10989Smrg { 3340eb10989Smrg file->i_defs = (struct symtab **) 3350eb10989Smrg malloc(sizeof (struct symtab*) * SYMTABINC); 3360eb10989Smrg file->i_ndefs = 0; 3370eb10989Smrg } 3380eb10989Smrg else if (!(file->i_ndefs % SYMTABINC)) 3390eb10989Smrg file->i_defs = (struct symtab **) 3400eb10989Smrg realloc(file->i_defs, 3410eb10989Smrg sizeof(struct symtab*)*(file->i_ndefs+SYMTABINC)); 3420eb10989Smrg 3430eb10989Smrg if (file->i_defs == NULL) 3440eb10989Smrg fatalerr("malloc()/realloc() failure in insert_defn()\n"); 3450eb10989Smrg 3460eb10989Smrg below = first = 0; 3470eb10989Smrg last = file->i_ndefs - 1; 3480eb10989Smrg while (last >= first) 3490eb10989Smrg { 3500eb10989Smrg /* Fast inline binary search */ 3510eb10989Smrg register char *s1; 3520eb10989Smrg register char *s2; 3530eb10989Smrg register int middle = (first + last) / 2; 3540eb10989Smrg 3550eb10989Smrg /* Fast inline strchr() */ 3560eb10989Smrg s1 = name; 3570eb10989Smrg s2 = file->i_defs[middle]->s_name; 3580eb10989Smrg while (*s1++ == *s2++) 3590eb10989Smrg if (s2[-1] == '\0') break; 3600eb10989Smrg 3610eb10989Smrg /* If exact match, set sp and break */ 3620eb10989Smrg if (*--s1 == *--s2) 3630eb10989Smrg { 3640eb10989Smrg sp = file->i_defs + middle; 3650eb10989Smrg break; 3660eb10989Smrg } 3670eb10989Smrg 3680eb10989Smrg /* If name > i_defs[middle] ... */ 3690eb10989Smrg if (*s1 > *s2) 3700eb10989Smrg { 3710eb10989Smrg below = first; 3720eb10989Smrg first = middle + 1; 3730eb10989Smrg } 3740eb10989Smrg /* else ... */ 3750eb10989Smrg else 3760eb10989Smrg { 3770eb10989Smrg below = last = middle - 1; 3780eb10989Smrg } 3790eb10989Smrg } 3800eb10989Smrg 3810eb10989Smrg /* Search is done. If we found an exact match to the symbol name, 3820eb10989Smrg just replace its s_value */ 3830eb10989Smrg if (sp != NULL) 3840eb10989Smrg { 3850eb10989Smrg debug(1,("redefining %s from %s to %s in file %s\n", 3860eb10989Smrg name, (*sp)->s_value, val, file->i_file)); 3870eb10989Smrg free((*sp)->s_value); 3880eb10989Smrg (*sp)->s_value = copy(val); 3890eb10989Smrg return; 3900eb10989Smrg } 3910eb10989Smrg 3920eb10989Smrg sp = file->i_defs + file->i_ndefs++; 3930eb10989Smrg dest = file->i_defs + below + 1; 3940eb10989Smrg while (sp > dest) 3950eb10989Smrg { 3960eb10989Smrg *sp = sp[-1]; 3970eb10989Smrg sp--; 3980eb10989Smrg } 3990eb10989Smrg stab = (struct symtab *) malloc(sizeof (struct symtab)); 4000eb10989Smrg if (stab == NULL) 4010eb10989Smrg fatalerr("malloc()/realloc() failure in insert_defn()\n"); 4020eb10989Smrg 4030eb10989Smrg debug(1,("defining %s to %s in file %s\n", name, val, file->i_file)); 4040eb10989Smrg stab->s_name = copy(name); 4050eb10989Smrg stab->s_value = copy(val); 4060eb10989Smrg *sp = stab; 4070eb10989Smrg} 4080eb10989Smrg 4090eb10989Smrgvoid 4100eb10989Smrgdefine(char *def, struct inclist *file) 4110eb10989Smrg{ 4120eb10989Smrg char *val; 4130eb10989Smrg 4140eb10989Smrg /* Separate symbol name and its value */ 4150eb10989Smrg val = def; 4160eb10989Smrg while (isalnum(*val) || *val == '_') 4170eb10989Smrg val++; 4180eb10989Smrg if (*val) 4190eb10989Smrg *val++ = '\0'; 4200eb10989Smrg while (*val == ' ' || *val == '\t') 4210eb10989Smrg val++; 4220eb10989Smrg 4230eb10989Smrg if (!*val) 4240eb10989Smrg val = "1"; 4250eb10989Smrg define2(def, val, file); 4260eb10989Smrg} 4270eb10989Smrg 4280eb10989Smrgstruct symtab ** 4290eb10989Smrgslookup(char *symbol, struct inclist *file) 4300eb10989Smrg{ 4310eb10989Smrg register int first = 0; 4320eb10989Smrg register int last; 4330eb10989Smrg 4340eb10989Smrg if (file == NULL) 4350eb10989Smrg return NULL; 4360eb10989Smrg 4370eb10989Smrg last = file->i_ndefs - 1; 4380eb10989Smrg 4390eb10989Smrg while (last >= first) 4400eb10989Smrg { 4410eb10989Smrg /* Fast inline binary search */ 4420eb10989Smrg register char *s1; 4430eb10989Smrg register char *s2; 4440eb10989Smrg register int middle = (first + last) / 2; 4450eb10989Smrg 4460eb10989Smrg /* Fast inline strchr() */ 4470eb10989Smrg s1 = symbol; 4480eb10989Smrg s2 = file->i_defs[middle]->s_name; 4490eb10989Smrg while (*s1++ == *s2++) 4500eb10989Smrg if (s2[-1] == '\0') break; 4510eb10989Smrg 4520eb10989Smrg /* If exact match, we're done */ 4530eb10989Smrg if (*--s1 == *--s2) 4540eb10989Smrg { 4550eb10989Smrg return file->i_defs + middle; 4560eb10989Smrg } 4570eb10989Smrg 4580eb10989Smrg /* If symbol > i_defs[middle] ... */ 4590eb10989Smrg if (*s1 > *s2) 4600eb10989Smrg { 4610eb10989Smrg first = middle + 1; 4620eb10989Smrg } 4630eb10989Smrg /* else ... */ 4640eb10989Smrg else 4650eb10989Smrg { 4660eb10989Smrg last = middle - 1; 4670eb10989Smrg } 4680eb10989Smrg } 4690eb10989Smrg return(NULL); 4700eb10989Smrg} 4710eb10989Smrg 4720eb10989Smrgstatic int 4730eb10989Smrgmerge2defines(struct inclist *file1, struct inclist *file2) 4740eb10989Smrg{ 4750eb10989Smrg int i; 4760eb10989Smrg 4770eb10989Smrg if ((file1==NULL) || (file2==NULL) || 4780eb10989Smrg !(file2->i_flags & FINISHED)) 4790eb10989Smrg return 0; 4800eb10989Smrg 4810eb10989Smrg for (i=0; i < file2->i_listlen; i++) 4820eb10989Smrg if (file2->i_merged[i]==FALSE) 4830eb10989Smrg return 0; 4840eb10989Smrg 4850eb10989Smrg { 4860eb10989Smrg int first1 = 0; 4870eb10989Smrg int last1 = file1->i_ndefs - 1; 4880eb10989Smrg 4890eb10989Smrg int first2 = 0; 4900eb10989Smrg int last2 = file2->i_ndefs - 1; 4910eb10989Smrg 4920eb10989Smrg int first=0; 4930eb10989Smrg struct symtab** i_defs = NULL; 4940eb10989Smrg int deflen=file1->i_ndefs+file2->i_ndefs; 4950eb10989Smrg 4960eb10989Smrg debug(2,("merging %s into %s\n", 4970eb10989Smrg file2->i_file, file1->i_file)); 4980eb10989Smrg 4990eb10989Smrg if (deflen>0) 5000eb10989Smrg { 5010eb10989Smrg /* make sure deflen % SYMTABINC == 0 is still true */ 5020eb10989Smrg deflen += (SYMTABINC - deflen % SYMTABINC) % SYMTABINC; 5030eb10989Smrg i_defs=(struct symtab**) 5040eb10989Smrg malloc(deflen*sizeof(struct symtab*)); 5050eb10989Smrg if (i_defs==NULL) return 0; 5060eb10989Smrg } 5070eb10989Smrg 5080eb10989Smrg while ((last1 >= first1) && (last2 >= first2)) 5090eb10989Smrg { 5100eb10989Smrg char *s1=file1->i_defs[first1]->s_name; 5110eb10989Smrg char *s2=file2->i_defs[first2]->s_name; 5120eb10989Smrg 5130eb10989Smrg if (strcmp(s1,s2) < 0) 5140eb10989Smrg i_defs[first++]=file1->i_defs[first1++]; 5150eb10989Smrg else if (strcmp(s1,s2) > 0) 5160eb10989Smrg i_defs[first++]=file2->i_defs[first2++]; 5170eb10989Smrg else /* equal */ 5180eb10989Smrg { 5190eb10989Smrg i_defs[first++]=file2->i_defs[first2++]; 5200eb10989Smrg first1++; 5210eb10989Smrg } 5220eb10989Smrg } 5230eb10989Smrg while (last1 >= first1) 5240eb10989Smrg { 5250eb10989Smrg i_defs[first++]=file1->i_defs[first1++]; 5260eb10989Smrg } 5270eb10989Smrg while (last2 >= first2) 5280eb10989Smrg { 5290eb10989Smrg i_defs[first++]=file2->i_defs[first2++]; 5300eb10989Smrg } 5310eb10989Smrg 5320eb10989Smrg if (file1->i_defs) free(file1->i_defs); 5330eb10989Smrg file1->i_defs=i_defs; 5340eb10989Smrg file1->i_ndefs=first; 5350eb10989Smrg 5360eb10989Smrg return 1; 5370eb10989Smrg } 5380eb10989Smrg} 5390eb10989Smrg 5400eb10989Smrgvoid 5410eb10989Smrgundefine(char *symbol, struct inclist *file) 5420eb10989Smrg{ 5430eb10989Smrg register struct symtab **ptr; 5440eb10989Smrg struct inclist *srcfile; 5450eb10989Smrg while ((ptr = isdefined(symbol, file, &srcfile)) != NULL) 5460eb10989Smrg { 5470eb10989Smrg srcfile->i_ndefs--; 5480eb10989Smrg for (; ptr < srcfile->i_defs + srcfile->i_ndefs; ptr++) 5490eb10989Smrg *ptr = ptr[1]; 5500eb10989Smrg } 5510eb10989Smrg} 5520eb10989Smrg 5530eb10989Smrgint 5540eb10989Smrgfind_includes(struct filepointer *filep, struct inclist *file, 5550eb10989Smrg struct inclist *file_red, int recursion, boolean failOK) 5560eb10989Smrg{ 5570eb10989Smrg struct inclist *inclistp; 5580eb10989Smrg char **includedirsp; 5590eb10989Smrg register char *line; 5600eb10989Smrg register int type; 5610eb10989Smrg boolean recfailOK; 5620eb10989Smrg 5630eb10989Smrg while ((line = getnextline(filep))) { 5640eb10989Smrg switch(type = deftype(line, filep, file_red, file, TRUE)) { 5650eb10989Smrg case IF: 5660eb10989Smrg doif: 5670eb10989Smrg type = find_includes(filep, file, 5680eb10989Smrg file_red, recursion+1, failOK); 5690eb10989Smrg while ((type == ELIF) || (type == ELIFFALSE) || 5700eb10989Smrg (type == ELIFGUESSFALSE)) 5710eb10989Smrg type = gobble(filep, file, file_red); 5720eb10989Smrg if (type == ELSE) 5730eb10989Smrg gobble(filep, file, file_red); 5740eb10989Smrg break; 5750eb10989Smrg case IFFALSE: 5760eb10989Smrg case IFGUESSFALSE: 5770eb10989Smrg doiffalse: 5780eb10989Smrg if (type == IFGUESSFALSE || type == ELIFGUESSFALSE) 5790eb10989Smrg recfailOK = TRUE; 5800eb10989Smrg else 5810eb10989Smrg recfailOK = failOK; 5820eb10989Smrg type = gobble(filep, file, file_red); 5830eb10989Smrg if (type == ELSE) 5840eb10989Smrg find_includes(filep, file, 5850eb10989Smrg file_red, recursion+1, recfailOK); 5860eb10989Smrg else 5870eb10989Smrg if (type == ELIF) 5880eb10989Smrg goto doif; 5890eb10989Smrg else 5900eb10989Smrg if ((type == ELIFFALSE) || (type == ELIFGUESSFALSE)) 5910eb10989Smrg goto doiffalse; 5920eb10989Smrg break; 5930eb10989Smrg case IFDEF: 5940eb10989Smrg case IFNDEF: 5950eb10989Smrg if ((type == IFDEF && isdefined(line, file_red, NULL)) 5960eb10989Smrg || (type == IFNDEF && !isdefined(line, file_red, NULL))) { 5970eb10989Smrg debug(1,(type == IFNDEF ? 5980eb10989Smrg "line %d: %s !def'd in %s via %s%s\n" : "", 5990eb10989Smrg filep->f_line, line, 6000eb10989Smrg file->i_file, file_red->i_file, ": doit")); 6010eb10989Smrg type = find_includes(filep, file, 6020eb10989Smrg file_red, recursion+1, failOK); 6030eb10989Smrg while (type == ELIF || type == ELIFFALSE || type == ELIFGUESSFALSE) 6040eb10989Smrg type = gobble(filep, file, file_red); 6050eb10989Smrg if (type == ELSE) 6060eb10989Smrg gobble(filep, file, file_red); 6070eb10989Smrg } 6080eb10989Smrg else { 6090eb10989Smrg debug(1,(type == IFDEF ? 6100eb10989Smrg "line %d: %s !def'd in %s via %s%s\n" : "", 6110eb10989Smrg filep->f_line, line, 6120eb10989Smrg file->i_file, file_red->i_file, ": gobble")); 6130eb10989Smrg type = gobble(filep, file, file_red); 6140eb10989Smrg if (type == ELSE) 6150eb10989Smrg find_includes(filep, file, 6160eb10989Smrg file_red, recursion+1, failOK); 6170eb10989Smrg else if (type == ELIF) 6180eb10989Smrg goto doif; 6190eb10989Smrg else if (type == ELIFFALSE || type == ELIFGUESSFALSE) 6200eb10989Smrg goto doiffalse; 6210eb10989Smrg } 6220eb10989Smrg break; 6230eb10989Smrg case ELSE: 6240eb10989Smrg case ELIFFALSE: 6250eb10989Smrg case ELIFGUESSFALSE: 6260eb10989Smrg case ELIF: 6270eb10989Smrg if (!recursion) 6280eb10989Smrg gobble(filep, file, file_red); 6290eb10989Smrg case ENDIF: 6300eb10989Smrg if (recursion) 6310eb10989Smrg return(type); 6320eb10989Smrg case DEFINE: 6330eb10989Smrg define(line, file); 6340eb10989Smrg break; 6350eb10989Smrg case UNDEF: 6360eb10989Smrg if (!*line) { 6370eb10989Smrg warning("%s", file_red->i_file); 6380eb10989Smrg if (file_red != file) 6390eb10989Smrg warning1(" (reading %s)", file->i_file); 6400eb10989Smrg warning1(", line %d: incomplete undef == \"%s\"\n", 6410eb10989Smrg filep->f_line, line); 6420eb10989Smrg break; 6430eb10989Smrg } 6440eb10989Smrg undefine(line, file_red); 6450eb10989Smrg break; 6460eb10989Smrg case INCLUDE: 6470eb10989Smrg case INCLUDEDOT: 6480eb10989Smrg case INCLUDENEXT: 6490eb10989Smrg case INCLUDENEXTDOT: 6500eb10989Smrg inclistp = inclistnext; 6510eb10989Smrg includedirsp = includedirsnext; 6520eb10989Smrg debug(2,("%s, reading %s, includes %s\n", 6530eb10989Smrg file_red->i_file, file->i_file, line)); 6540eb10989Smrg add_include(filep, file, file_red, line, type, failOK); 6550eb10989Smrg inclistnext = inclistp; 6560eb10989Smrg includedirsnext = includedirsp; 6570eb10989Smrg break; 6580eb10989Smrg case ERROR: 6590eb10989Smrg case WARNING: 6600eb10989Smrg warning("%s", file_red->i_file); 6610eb10989Smrg if (file_red != file) 6620eb10989Smrg warning1(" (reading %s)", file->i_file); 6630eb10989Smrg warning1(", line %d: %s\n", 6640eb10989Smrg filep->f_line, line); 6650eb10989Smrg break; 6660eb10989Smrg 6670eb10989Smrg case PRAGMA: 6680eb10989Smrg case IDENT: 6690eb10989Smrg case SCCS: 6700eb10989Smrg case EJECT: 6710eb10989Smrg break; 6720eb10989Smrg case -1: 6730eb10989Smrg warning("%s", file_red->i_file); 6740eb10989Smrg if (file_red != file) 6750eb10989Smrg warning1(" (reading %s)", file->i_file); 6760eb10989Smrg warning1(", line %d: unknown directive == \"%s\"\n", 6770eb10989Smrg filep->f_line, line); 6780eb10989Smrg break; 6790eb10989Smrg case -2: 6800eb10989Smrg warning("%s", file_red->i_file); 6810eb10989Smrg if (file_red != file) 6820eb10989Smrg warning1(" (reading %s)", file->i_file); 6830eb10989Smrg warning1(", line %d: incomplete include == \"%s\"\n", 6840eb10989Smrg filep->f_line, line); 6850eb10989Smrg break; 6860eb10989Smrg } 6870eb10989Smrg } 6880eb10989Smrg file->i_flags |= FINISHED; 6890eb10989Smrg debug(2,("finished with %s\n", file->i_file)); 6900eb10989Smrg return(-1); 6910eb10989Smrg} 692