parse.c revision 63165362
11.149Soster/* 21.1Soster 31.1SosterCopyright (c) 1993, 1994, 1998 The Open Group 41.1Soster 51.1SosterPermission to use, copy, modify, distribute, and sell this software and its 61.1Sosterdocumentation for any purpose is hereby granted without fee, provided that 71.1Sosterthe above copyright notice appear in all copies and that both that 81.1Sostercopyright notice and this permission notice appear in supporting 91.1Sosterdocumentation. 101.1Soster 111.1SosterThe above copyright notice and this permission notice shall be included in 121.1Sosterall copies or substantial portions of the Software. 131.1Soster 141.1SosterTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 151.1SosterIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 161.1SosterFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 171.1SosterOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 181.1SosterAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 191.1SosterCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 201.1Soster 211.1SosterExcept as contained in this notice, the name of The Open Group shall not be 221.1Sosterused in advertising or otherwise to promote the sale, use or other dealings 231.1Sosterin this Software without prior written authorization from The Open Group. 241.1Soster 251.1Soster*/ 261.1Soster 271.1Soster#include "def.h" 281.1Soster 291.1Sosterextern const char * const directives[]; 301.1Sosterextern struct inclist inclist[ MAXFILES ], 311.1Soster *inclistnext, 321.1Soster maininclist; 331.1Sosterextern const char *includedirs[ ], 341.1Soster **includedirsnext; 351.1Soster 361.1Sosterstatic int deftype (char *line, struct filepointer *filep, 371.1Soster struct inclist *file_red, struct inclist *file, 381.1Soster int parse_it); 391.1Sosterstatic int zero_value(char *filename, char *exp, struct filepointer *filep, 401.1Soster struct inclist *file_red); 411.1Sosterstatic int merge2defines(struct inclist *file1, struct inclist *file2); 421.1Soster 431.1Sosterstatic int 441.1Sostergobble(struct filepointer *filep, struct inclist *file, 451.1Soster struct inclist *file_red) 461.1Soster{ 471.1Soster char *line; 481.1Soster int type; 491.1Soster 501.1Soster while ((line = getnextline(filep))) { 511.1Soster switch(type = deftype(line, filep, file_red, file, FALSE)) { 521.1Soster case IF: 531.1Soster case IFFALSE: 541.1Soster case IFGUESSFALSE: 551.1Soster case IFDEF: 561.1Soster case IFNDEF: 571.1Soster type = gobble(filep, file, file_red); 581.1Soster while ((type == ELIF) || (type == ELIFFALSE) || 591.1Soster (type == ELIFGUESSFALSE)) 601.1Soster type = gobble(filep, file, file_red); 611.1Soster if (type == ELSE) 621.1Soster (void)gobble(filep, file, file_red); 631.1Soster break; 641.1Soster case ELSE: 651.1Soster case ENDIF: 661.1Soster debug(0,("%s, line %d: #%s\n", 671.1Soster file->i_file, filep->f_line, 681.1Soster directives[type])); 691.1Soster return(type); 701.1Soster case DEFINE: 711.1Soster case UNDEF: 721.1Soster case INCLUDE: 731.1Soster case INCLUDEDOT: 741.1Soster case PRAGMA: 751.1Soster case ERROR: 761.1Soster case IDENT: 771.1Soster case SCCS: 781.1Soster case EJECT: 791.1Soster case WARNING: 801.1Soster case INCLUDENEXT: 811.1Soster case INCLUDENEXTDOT: 821.1Soster break; 831.1Soster case ELIF: 841.1Soster case ELIFFALSE: 851.1Soster case ELIFGUESSFALSE: 861.1Soster return(type); 871.1Soster case -1: 881.1Soster warning("%s", file_red->i_file); 891.1Soster if (file_red != file) 901.1Soster warning1(" (reading %s)", file->i_file); 911.1Soster warning1(", line %ld: unknown directive == \"%s\"\n", 921.1Soster filep->f_line, line); 931.1Soster break; 941.1Soster } 951.1Soster } 961.1Soster return(-1); 971.1Soster} 981.1Soster 991.1Soster/* 1001.1Soster * Decide what type of # directive this line is. 1011.1Soster */ 1021.1Sosterstatic int 1031.1Sosterdeftype (char *line, struct filepointer *filep, 1041.1Soster struct inclist *file_red, struct inclist *file, int parse_it) 1051.1Soster{ 1061.1Soster register char *p; 1071.1Soster char *directive, savechar, *q; 1081.1Soster register int ret; 1091.1Soster 1101.1Soster /* 1111.1Soster * Parse the directive... 1121.1Soster */ 1131.1Soster directive=line+1; 1141.1Soster while (*directive == ' ' || *directive == '\t') 1151.112Slukem directive++; 1161.112Slukem 1171.149Soster p = directive; 1181.1Soster while ((*p == '_') || (*p >= 'a' && *p <= 'z')) 1191.113Slukem p++; 1201.1Soster savechar = *p; 1211.1Soster *p = '\0'; 1221.1Soster ret = match(directive, directives); 1231.1Soster *p = savechar; 1241.1Soster 1251.1Soster /* If we don't recognize this compiler directive or we happen to just 1261.1Soster * be gobbling up text while waiting for an #endif or #elif or #else 1271.1Soster * in the case of an #elif we must check the zero_value and return an 1281.1Soster * ELIF or an ELIFFALSE. 1291.1Soster */ 1301.1Soster 1311.1Soster if (ret == ELIF && !parse_it) 1321.1Soster { 1331.1Soster while (*p == ' ' || *p == '\t') 1341.1Soster p++; 1351.1Soster /* 1361.65Soster * parse an expression. 1371.8Soster */ 1381.110Soster debug(0,("%s, line %d: #elif %s ", 1391.110Soster file->i_file, filep->f_line, p)); 1401.8Soster ret = zero_value(file->i_file, p, filep, file_red); 1411.62Soster if (ret != IF) 1421.1Soster { 1431.44Soster debug(0,("false...\n")); 1441.1Soster if (ret == IFFALSE) 1451.1Soster return(ELIFFALSE); 1461.99Soster else 1471.1Soster return(ELIFGUESSFALSE); 1481.1Soster } 1491.1Soster else 1501.1Soster { 1511.1Soster debug(0,("true...\n")); 1521.1Soster return(ELIF); 1531.1Soster } 1541.1Soster } 1551.1Soster 1561.133Soster if (ret < 0 || ! parse_it) 1571.9Soster return(ret); 1581.1Soster 1591.9Soster /* 1601.1Soster * now decide how to parse the directive, and do it. 1611.9Soster */ 1621.1Soster while (*p == ' ' || *p == '\t') 1631.9Soster p++; 1641.1Soster q = p + strlen(p); 1651.11Soster do { 1661.1Soster q--; 1671.10Soster } while (*q == ' ' || *q == '\t'); 1681.10Soster q[1] = '\0'; 1691.10Soster switch (ret) { 1701.10Soster case IF: 1711.10Soster /* 1721.1Soster * parse an expression. 1731.10Soster */ 1741.10Soster ret = zero_value(file->i_file, p, filep, file_red); 1751.10Soster debug(0,("%s, line %d: %s #if %s\n", 1761.10Soster file->i_file, filep->f_line, ret?"false":"true", p)); 1771.10Soster break; 1781.10Soster case IFDEF: 1791.104Soster case IFNDEF: 1801.1Soster debug(0,("%s, line %d: #%s %s\n", 1811.104Soster file->i_file, filep->f_line, directives[ret], p)); 1821.130Sgehenna case UNDEF: 1831.130Sgehenna /* 1841.130Sgehenna * separate the name of a single symbol. 1851.130Sgehenna */ 1861.130Sgehenna while (isalnum(*p) || *p == '_') 1871.130Sgehenna *line++ = *p++; 1881.130Sgehenna *line = '\0'; 1891.130Sgehenna break; 1901.130Sgehenna case INCLUDE: 1911.130Sgehenna case INCLUDENEXT: 1921.130Sgehenna debug(2,("%s, line %d: #include%s %s\n", 1931.130Sgehenna file->i_file, filep->f_line, 1941.130Sgehenna (ret == INCLUDE) ? "" : "_next", p)); 1951.130Sgehenna 1961.130Sgehenna /* Support ANSI macro substitution */ 1971.130Sgehenna while (1) { 1981.130Sgehenna struct symtab **sym; 1991.144Sjdolecek 2001.130Sgehenna if (!*p || *p == '"' || *p == '<') 2011.1Soster break; 2021.1Soster 2031.1Soster sym = isdefined(p, file_red, NULL); 2041.1Soster if (!sym) 2051.1Soster break; 2061.10Soster 2071.10Soster p = (*sym)->s_value; 2081.10Soster debug(3,("%s : #includes SYMBOL %s = %s\n", 2091.11Soster file->i_incstring, 2101.10Soster (*sym) -> s_name, 2111.1Soster (*sym) -> s_value)); 2121.116Sthorpej /* mark file as having included a 'soft include' */ 2131.116Sthorpej file->i_flags |= INCLUDED_SYM; 2141.1Soster } 2151.9Soster 2161.53Soster /* 2171.59Soster * Separate the name of the include file. 2181.1Soster */ 2191.10Soster while (*p && *p != '"' && *p != '<') 2201.10Soster p++; 2211.10Soster if (! *p) 2221.11Soster return(-2); 2231.10Soster if (*p++ == '"') { 2241.10Soster if (ret == INCLUDE) 2251.125Shannken ret = INCLUDEDOT; 2261.10Soster else 2271.1Soster ret = INCLUDENEXTDOT; 2281.1Soster while (*p && *p != '"') 2291.1Soster *line++ = *p++; 2301.1Soster } else 2311.1Soster while (*p && *p != '>') 2321.1Soster *line++ = *p++; 2331.1Soster *line = '\0'; 2341.1Soster break; 2351.48Soster case DEFINE: 2361.1Soster /* 2371.20Soster * copy the definition back to the beginning of the line. 2381.20Soster */ 2391.20Soster strcpy (line, p); 2401.28Soster break; 2411.28Soster case ELSE: 2421.28Soster case ENDIF: 2431.28Soster case ELIF: 2441.28Soster case PRAGMA: 2451.28Soster case ERROR: 2461.110Soster case IDENT: 2471.28Soster case SCCS: 2481.28Soster case EJECT: 2491.28Soster case WARNING: 2501.28Soster debug(0,("%s, line %d: #%s\n", 2511.28Soster file->i_file, filep->f_line, directives[ret])); 2521.20Soster /* 2531.20Soster * nothing to do. 2541.20Soster */ 2551.28Soster break; 2561.20Soster } 2571.20Soster return(ret); 2581.1Soster} 2591.1Soster 2601.1Sosterstruct symtab ** 2611.1Sosterfdefined(char *symbol, struct inclist *file, struct inclist **srcfile) 2621.10Soster{ 2631.9Soster struct inclist **ip; 2641.104Soster struct symtab **val; 2651.104Soster int i; 2661.104Soster static int recurse_lvl = 0; 2671.104Soster 2681.1Soster if (file->i_flags & DEFCHECKED) 2691.104Soster return(NULL); 2701.104Soster debug(2,("Looking for %s in %s\n", symbol, file->i_file)); 2711.1Soster file->i_flags |= DEFCHECKED; 2721.104Soster if ((val = slookup(symbol, file))) 2731.48Soster debug(1,("%s defined in %s as %s\n", 2741.48Soster symbol, file->i_file, (*val)->s_value)); 2751.1Soster if (val == NULL && file->i_list) 2761.104Soster { 2771.37Soster for (ip = file->i_list, i=0; i < file->i_listlen; i++, ip++) 2781.104Soster if (file->i_merged[i]==FALSE) { 2791.104Soster val = fdefined(symbol, *ip, srcfile); 2801.104Soster file->i_merged[i]=merge2defines(file,*ip); 2811.104Soster if (val!=NULL) break; 2821.142Sthorpej } 2831.142Sthorpej } 2841.104Soster else if (val != NULL && srcfile != NULL) *srcfile = file; 2851.104Soster recurse_lvl--; 2861.104Soster file->i_flags &= ~DEFCHECKED; 2871.104Soster 2881.104Soster return(val); 2891.104Soster} 2901.104Soster 2911.104Sosterstruct symtab ** 2921.104Sosterisdefined(char *symbol, struct inclist *file, struct inclist **srcfile) 2931.104Soster{ 2941.104Soster struct symtab **val; 2951.104Soster 2961.48Soster if ((val = slookup(symbol, &maininclist))) { 2971.48Soster debug(1,("%s defined on command line\n", symbol)); 2981.62Soster if (srcfile != NULL) *srcfile = &maininclist; 2991.62Soster return(val); 3001.62Soster } 3011.62Soster if ((val = fdefined(symbol, file, srcfile))) 3021.37Soster return(val); 3031.10Soster debug(1,("%s not defined in %s\n", symbol, file->i_file)); 3041.10Soster return(NULL); 3051.9Soster} 3061.1Soster 3071.14Soster/* 3081.14Soster * Return type based on if the #if expression evaluates to 0 3091.1Soster */ 3101.1Sosterstatic int 3111.9Sosterzero_value(char *filename, 3121.1Soster char *exp, 3131.1Soster struct filepointer *filep, 3141.1Soster struct inclist *file_red) 3151.1Soster{ 3161.1Soster if (cppsetup(filename, exp, filep, file_red)) 3171.1Soster return(IFFALSE); 3181.1Soster else 3191.1Soster return(IF); 3201.9Soster} 3211.1Soster 3221.50Sostervoid 3231.50Sosterdefine2(char *name, char *val, struct inclist *file) 3241.1Soster{ 3251.1Soster int first, last, below; 3261.1Soster register struct symtab **sp = NULL, **dest; 3271.1Soster struct symtab *stab; 3281.141Sprovos 3291.1Soster /* Make space if it's needed */ 3301.116Sthorpej if (file->i_defs == NULL) 3311.116Sthorpej { 3321.116Sthorpej file->i_defs = (struct symtab **) 3331.117Sthorpej malloc(sizeof (struct symtab*) * SYMTABINC); 3341.116Sthorpej file->i_ndefs = 0; 3351.14Soster } 3361.14Soster else if (!(file->i_ndefs % SYMTABINC)) 3371.14Soster file->i_defs = (struct symtab **) 3381.14Soster realloc(file->i_defs, 3391.14Soster sizeof(struct symtab*)*(file->i_ndefs+SYMTABINC)); 3401.14Soster 3411.14Soster if (file->i_defs == NULL) 3421.58Soster fatalerr("malloc()/realloc() failure in insert_defn()\n"); 3431.14Soster 3441.14Soster below = first = 0; 3451.14Soster last = file->i_ndefs - 1; 3461.14Soster while (last >= first) 3471.14Soster { 3481.141Sprovos /* Fast inline binary search */ 3491.14Soster register char *s1; 3501.9Soster register char *s2; 3511.9Soster register int middle = (first + last) / 2; 3521.1Soster 3531.1Soster /* Fast inline strchr() */ 3541.48Soster s1 = name; 3551.48Soster s2 = file->i_defs[middle]->s_name; 3561.1Soster while (*s1++ == *s2++) 3571.1Soster if (s2[-1] == '\0') break; 3581.1Soster 3591.1Soster /* If exact match, set sp and break */ 3601.50Soster if (*--s1 == *--s2) 3611.108Sthorpej { 3621.34Soster sp = file->i_defs + middle; 3631.48Soster break; 3641.48Soster } 3651.48Soster 3661.141Sprovos /* If name > i_defs[middle] ... */ 3671.48Soster if (*s1 > *s2) 3681.48Soster { 3691.9Soster below = first; 3701.126Shannken first = middle + 1; 3711.48Soster } 3721.48Soster /* else ... */ 3731.48Soster else 3741.48Soster { 3751.48Soster below = last = middle - 1; 3761.48Soster } 3771.48Soster } 3781.48Soster 3791.9Soster /* Search is done. If we found an exact match to the symbol name, 3801.11Soster just replace its s_value */ 3811.9Soster if (sp != NULL) 3821.39Soster { 3831.39Soster debug(1,("redefining %s from %s to %s in file %s\n", 3841.39Soster name, (*sp)->s_value, val, file->i_file)); 3851.1Soster free((*sp)->s_value); 3861.1Soster (*sp)->s_value = copy(val); 3871.48Soster return; 3881.114Slukem } 3891.62Soster 3901.62Soster sp = file->i_defs + file->i_ndefs++; 3911.62Soster dest = file->i_defs + below + 1; 3921.142Sthorpej while (sp > dest) 3931.142Sthorpej { 3941.142Sthorpej *sp = sp[-1]; 3951.142Sthorpej sp--; 3961.142Sthorpej } 3971.142Sthorpej stab = (struct symtab *) malloc(sizeof (struct symtab)); 3981.142Sthorpej if (stab == NULL) 3991.142Sthorpej fatalerr("malloc()/realloc() failure in insert_defn()\n"); 4001.142Sthorpej 4011.142Sthorpej debug(1,("defining %s to %s in file %s\n", name, val, file->i_file)); 4021.142Sthorpej stab->s_name = copy(name); 4031.142Sthorpej stab->s_value = copy(val); 4041.142Sthorpej *sp = stab; 4051.142Sthorpej} 4061.142Sthorpej 4071.142Sthorpejvoid 4081.142Sthorpejdefine(char *def, struct inclist *file) 4091.142Sthorpej{ 4101.142Sthorpej char *val; 4111.142Sthorpej 4121.48Soster /* Separate symbol name and its value */ 4131.142Sthorpej val = def; 4141.142Sthorpej while (isalnum(*val) || *val == '_') 4151.48Soster val++; 4161.48Soster if (*val) 4171.48Soster *val++ = '\0'; 4181.142Sthorpej while (*val == ' ' || *val == '\t') 4191.48Soster val++; 4201.48Soster 4211.142Sthorpej if (!*val) 4221.142Sthorpej val = "1"; 4231.142Sthorpej define2(def, val, file); 4241.142Sthorpej} 4251.142Sthorpej 4261.48Sosterstruct symtab ** 4271.142Sthorpejslookup(char *symbol, struct inclist *file) 4281.48Soster{ 4291.48Soster register int first = 0; 4301.48Soster register int last; 4311.142Sthorpej 4321.48Soster if (file == NULL) 4331.48Soster return NULL; 4341.48Soster 4351.51Soster last = file->i_ndefs - 1; 4361.48Soster 4371.51Soster while (last >= first) 4381.51Soster { 4391.48Soster /* Fast inline binary search */ 4401.101Soster register char *s1; 4411.51Soster register char *s2; 4421.48Soster register int middle = (first + last) / 2; 4431.48Soster 4441.48Soster /* Fast inline strchr() */ 4451.51Soster s1 = symbol; 4461.51Soster s2 = file->i_defs[middle]->s_name; 4471.51Soster while (*s1++ == *s2++) 4481.51Soster if (s2[-1] == '\0') break; 4491.51Soster 4501.51Soster /* If exact match, we're done */ 4511.51Soster if (*--s1 == *--s2) 4521.51Soster { 4531.51Soster return file->i_defs + middle; 4541.51Soster } 4551.51Soster 4561.51Soster /* If symbol > i_defs[middle] ... */ 4571.51Soster if (*s1 > *s2) 4581.51Soster { 4591.48Soster first = middle + 1; 4601.48Soster } 4611.48Soster /* else ... */ 4621.48Soster else 4631.49Soster { 4641.48Soster last = middle - 1; 4651.48Soster } 4661.49Soster } 4671.48Soster return(NULL); 4681.48Soster} 4691.122Soster 4701.122Sosterstatic int 4711.122Sostermerge2defines(struct inclist *file1, struct inclist *file2) 4721.122Soster{ 4731.122Soster int i; 4741.122Soster 4751.122Soster if ((file1==NULL) || (file2==NULL) || 4761.122Soster !(file2->i_flags & FINISHED)) 4771.51Soster return 0; 4781.1Soster 4791.1Soster for (i=0; i < file2->i_listlen; i++) 4801.1Soster if (file2->i_merged[i]==FALSE) 4811.1Soster return 0; 4821.1Soster 4831.9Soster { 4841.1Soster int first1 = 0; 4851.1Soster int last1 = file1->i_ndefs - 1; 4861.1Soster 4871.9Soster int first2 = 0; 4881.1Soster int last2 = file2->i_ndefs - 1; 4891.1Soster 4901.1Soster int first=0; 4911.1Soster struct symtab** i_defs = NULL; 4921.1Soster int deflen=file1->i_ndefs+file2->i_ndefs; 4931.1Soster 4941.1Soster debug(2,("merging %s into %s\n", 4951.1Soster file2->i_file, file1->i_file)); 4961.1Soster 4971.1Soster if (deflen>0) 4981.1Soster { 4991.1Soster /* make sure deflen % SYMTABINC == 0 is still true */ 5001.1Soster deflen += (SYMTABINC - deflen % SYMTABINC) % SYMTABINC; 5011.1Soster i_defs=(struct symtab**) 5021.1Soster malloc(deflen*sizeof(struct symtab*)); 5031.1Soster if (i_defs==NULL) return 0; 5041.1Soster } 5051.1Soster 5061.1Soster while ((last1 >= first1) && (last2 >= first2)) 5071.1Soster { 5081.1Soster char *s1=file1->i_defs[first1]->s_name; 5091.1Soster char *s2=file2->i_defs[first2]->s_name; 5101.1Soster 5111.1Soster if (strcmp(s1,s2) < 0) 5121.1Soster i_defs[first++]=file1->i_defs[first1++]; 5131.1Soster else if (strcmp(s1,s2) > 0) 5141.1Soster i_defs[first++]=file2->i_defs[first2++]; 5151.1Soster else /* equal */ 5161.1Soster { 5171.1Soster i_defs[first++]=file2->i_defs[first2++]; 5181.1Soster first1++; 5191.9Soster } 5201.1Soster } 5211.1Soster while (last1 >= first1) 5221.9Soster { 5231.1Soster i_defs[first++]=file1->i_defs[first1++]; 5241.1Soster } 5251.1Soster while (last2 >= first2) 5261.1Soster { 5271.1Soster i_defs[first++]=file2->i_defs[first2++]; 5281.1Soster } 5291.1Soster 5301.9Soster if (file1->i_defs) free(file1->i_defs); 5311.9Soster file1->i_defs=i_defs; 5321.1Soster file1->i_ndefs=first; 5331.1Soster 5341.9Soster return 1; 5351.1Soster } 5361.1Soster} 5371.9Soster 5381.9Sostervoid 5391.9Sosterundefine(char *symbol, struct inclist *file) 5401.1Soster{ 5411.1Soster register struct symtab **ptr; 5421.1Soster struct inclist *srcfile; 5431.1Soster while ((ptr = isdefined(symbol, file, &srcfile)) != NULL) 5441.1Soster { 5451.9Soster srcfile->i_ndefs--; 5461.1Soster for (; ptr < srcfile->i_defs + srcfile->i_ndefs; ptr++) 5471.1Soster *ptr = ptr[1]; 5481.1Soster } 5491.1Soster} 5501.1Soster 5511.1Sosterint 5521.1Sosterfind_includes(struct filepointer *filep, struct inclist *file, 5531.9Soster struct inclist *file_red, int recursion, boolean failOK) 5541.1Soster{ 5551.1Soster struct inclist *inclistp; 5561.1Soster const char **includedirsp; 5571.1Soster register char *line; 5581.1Soster register int type; 5591.1Soster boolean recfailOK; 5601.9Soster 5611.1Soster while ((line = getnextline(filep))) { 5621.1Soster switch(type = deftype(line, filep, file_red, file, TRUE)) { 5631.9Soster case IF: 5641.1Soster doif: 5651.1Soster type = find_includes(filep, file, 5661.1Soster file_red, recursion+1, failOK); 5671.1Soster while ((type == ELIF) || (type == ELIFFALSE) || 5681.1Soster (type == ELIFGUESSFALSE)) 5691.1Soster type = gobble(filep, file, file_red); 5701.1Soster if (type == ELSE) 5711.1Soster gobble(filep, file, file_red); 5721.1Soster break; 5731.1Soster case IFFALSE: 5741.1Soster case IFGUESSFALSE: 5751.1Soster doiffalse: 5761.13Soster if (type == IFGUESSFALSE || type == ELIFGUESSFALSE) 5771.13Soster recfailOK = TRUE; 5781.13Soster else 5791.13Soster recfailOK = failOK; 5801.13Soster type = gobble(filep, file, file_red); 5811.13Soster if (type == ELSE) 5821.13Soster find_includes(filep, file, 5831.13Soster file_red, recursion+1, recfailOK); 5841.13Soster else 5851.13Soster if (type == ELIF) 5861.13Soster goto doif; 5871.13Soster else 5881.13Soster if ((type == ELIFFALSE) || (type == ELIFGUESSFALSE)) 5891.13Soster goto doiffalse; 5901.13Soster break; 5911.1Soster case IFDEF: 5921.1Soster case IFNDEF: 5931.1Soster if ((type == IFDEF && isdefined(line, file_red, NULL)) 5941.1Soster || (type == IFNDEF && !isdefined(line, file_red, NULL))) { 5951.1Soster debug(1,(type == IFNDEF ? 5961.9Soster "line %d: %s !def'd in %s via %s%s\n" : "", 5971.1Soster filep->f_line, line, 5981.1Soster file->i_file, file_red->i_file, ": doit")); 5991.1Soster type = find_includes(filep, file, 6001.1Soster file_red, recursion+1, failOK); 6011.1Soster while (type == ELIF || type == ELIFFALSE || type == ELIFGUESSFALSE) 6021.1Soster type = gobble(filep, file, file_red); 6031.9Soster if (type == ELSE) 6041.9Soster gobble(filep, file, file_red); 6051.1Soster } 6061.1Soster else { 6071.9Soster debug(1,(type == IFDEF ? 6081.1Soster "line %d: %s !def'd in %s via %s%s\n" : "", 6091.9Soster filep->f_line, line, 6101.9Soster file->i_file, file_red->i_file, ": gobble")); 6111.1Soster type = gobble(filep, file, file_red); 6121.1Soster if (type == ELSE) 6131.1Soster find_includes(filep, file, 6141.1Soster file_red, recursion+1, failOK); 6151.1Soster else if (type == ELIF) 6161.1Soster goto doif; 6171.1Soster else if (type == ELIFFALSE || type == ELIFGUESSFALSE) 6181.1Soster goto doiffalse; 6191.1Soster } 6201.1Soster break; 6211.1Soster case ELSE: 6221.1Soster case ELIFFALSE: 6231.1Soster case ELIFGUESSFALSE: 6241.1Soster case ELIF: 6251.1Soster if (!recursion) 6261.1Soster gobble(filep, file, file_red); 6271.1Soster case ENDIF: 6281.1Soster if (recursion) 6291.1Soster return(type); 6301.1Soster case DEFINE: 6311.1Soster define(line, file); 6321.1Soster break; 6331.13Soster case UNDEF: 6341.13Soster if (!*line) { 6351.13Soster warning("%s", file_red->i_file); 6361.13Soster if (file_red != file) 6371.13Soster warning1(" (reading %s)", file->i_file); 6381.13Soster warning1(", line %ld: incomplete undef == \"%s\"\n", 6391.13Soster filep->f_line, line); 6401.147Soster break; 6411.91Soster } 6421.91Soster undefine(line, file_red); 6431.107Soster break; 6441.107Soster case INCLUDE: 6451.107Soster case INCLUDEDOT: 6461.107Soster case INCLUDENEXT: 6471.107Soster case INCLUDENEXTDOT: 6481.107Soster inclistp = inclistnext; 6491.107Soster includedirsp = includedirsnext; 6501.107Soster debug(2,("%s, reading %s, includes %s\n", 6511.107Soster file_red->i_file, file->i_file, line)); 6521.107Soster add_include(filep, file, file_red, line, type, failOK); 6531.107Soster inclistnext = inclistp; 6541.13Soster includedirsnext = includedirsp; 6551.1Soster break; 6561.1Soster case ERROR: 6571.1Soster case WARNING: 6581.1Soster warning("%s", file_red->i_file); 6591.1Soster if (file_red != file) 6601.1Soster warning1(" (reading %s)", file->i_file); 6611.1Soster warning1(", line %ld: %s\n", 6621.1Soster filep->f_line, line); 6631.74Saugustss break; 6641.1Soster 6651.74Saugustss case PRAGMA: 6661.1Soster case IDENT: 6671.1Soster case SCCS: 6681.1Soster case EJECT: 6691.1Soster break; 6701.1Soster case -1: 6711.9Soster warning("%s", file_red->i_file); 6721.1Soster if (file_red != file) 6731.30Soster warning1(" (reading %s)", file->i_file); 6741.30Soster warning1(", line %ld: unknown directive == \"%s\"\n", 6751.100Schs filep->f_line, line); 6761.30Soster break; 6771.30Soster case -2: 6781.1Soster warning("%s", file_red->i_file); 6791.30Soster if (file_red != file) 6801.1Soster warning1(" (reading %s)", file->i_file); 6811.1Soster warning1(", line %ld: incomplete include == \"%s\"\n", 6821.1Soster filep->f_line, line); 6831.1Soster break; 6841.1Soster } 6851.1Soster } 6861.1Soster file->i_flags |= FINISHED; 6871.1Soster debug(2,("finished with %s\n", file->i_file)); 6881.1Soster return(-1); 6891.1Soster} 6901.1Soster