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