|
|
1.1 ! root 1: /* ! 2: * $Header: parse.c,v 1.1 87/09/11 08:13:35 toddb Exp $ ! 3: * ! 4: * $Log: parse.c,v $ ! 5: * Revision 1.1 87/09/11 08:13:35 toddb ! 6: * Initial revision ! 7: * ! 8: * Revision 1.1 87/04/08 16:40:53 rich ! 9: * Initial revision ! 10: * ! 11: * Revision 1.3 86/09/13 10:14:25 toddb ! 12: * Previous fix could cause problems if the number of defines in a ! 13: * file was an integral multiple of SYMTABINC: there would be no ! 14: * s_name = NULL at the end. ! 15: * ! 16: * Revision 1.2 86/09/04 12:45:35 toddb ! 17: * The way that define() allocated new define slots, every tenth entry had ! 18: * a null s_name and s_value. The effect was that slookup() only checked ! 19: * the first ten defines in any file. ! 20: * ! 21: * Revision 1.1 86/04/15 08:34:40 toddb ! 22: * Initial revision ! 23: * ! 24: */ ! 25: #include "def.h" ! 26: #include <sys/signal.h> ! 27: ! 28: extern char *directives[]; ! 29: extern struct symtab deflist[]; ! 30: ! 31: find_includes(filep, file, file_red, recursion) ! 32: struct filepointer *filep; ! 33: struct inclist *file, *file_red; ! 34: int recursion; ! 35: { ! 36: register char *line; ! 37: register int type; ! 38: ! 39: while (line = getline(filep)) { ! 40: switch(type = deftype(line, filep, file_red, file, TRUE)) { ! 41: case IF: ! 42: type = find_includes(filep, file, ! 43: file_red, recursion+1); ! 44: if (type == ELSE) ! 45: gobble(filep, file, file_red); ! 46: break; ! 47: case IFFALSE: ! 48: type = gobble(filep, file, file_red); ! 49: if (type == ELSE) ! 50: find_includes(filep, file, ! 51: file_red, recursion+1); ! 52: break; ! 53: case IFDEF: ! 54: case IFNDEF: ! 55: if ((type == IFDEF && defined(line, file_red)) ! 56: || (type == IFNDEF && !defined(line, file_red))) { ! 57: debug1(type == IFNDEF ? ! 58: "line %d: %s !def'd in %s via %s%s\n" : "", ! 59: filep->f_line, line, ! 60: file->i_file, file_red->i_file, ": doit"); ! 61: type = find_includes(filep, file, ! 62: file_red, recursion+1); ! 63: if (type == ELSE) ! 64: gobble(filep, file, file_red); ! 65: } ! 66: else { ! 67: debug1(type == IFDEF ? ! 68: "line %d: %s !def'd in %s via %s%s\n" : "", ! 69: filep->f_line, line, ! 70: file->i_file, file_red->i_file, ": gobble"); ! 71: type = gobble(filep, file, file_red); ! 72: if (type == ELSE) ! 73: find_includes(filep, file, ! 74: file_red, recursion+1); ! 75: } ! 76: break; ! 77: case ELSE: ! 78: if (!recursion) ! 79: gobble(filep, file, file_red); ! 80: case ENDIF: ! 81: if (recursion) ! 82: return(type); ! 83: case DEFINE: ! 84: define(line, file); ! 85: break; ! 86: case UNDEF: ! 87: break; ! 88: case INCLUDE: ! 89: add_include(file, file_red, line, FALSE); ! 90: break; ! 91: case INCLUDEDOT: ! 92: add_include(file, file_red, line, TRUE); ! 93: break; ! 94: case -1: ! 95: log("%s, line %d: unknown directive == \"%s\"\n", ! 96: file_red->i_file, filep->f_line, line); ! 97: break; ! 98: case -2: ! 99: log("%s, line %d: incomplete include == \"%s\"\n", ! 100: file_red->i_file, filep->f_line, line); ! 101: break; ! 102: } ! 103: } ! 104: return(-1); ! 105: } ! 106: ! 107: gobble(filep, file, file_red) ! 108: register struct filepointer *filep; ! 109: struct inclist *file, *file_red; ! 110: { ! 111: register char *line; ! 112: register int type; ! 113: ! 114: while (line = getline(filep)) { ! 115: switch(type = deftype(line, filep, file_red, file, FALSE)) { ! 116: case IF: ! 117: case IFFALSE: ! 118: case IFDEF: ! 119: case IFNDEF: ! 120: type = gobble(filep, file, file_red); ! 121: if (type == ELSE) ! 122: type = gobble(filep, file, file_red); ! 123: break; ! 124: case ELSE: ! 125: case ENDIF: ! 126: debug0("%s, line %d: #%s\n", ! 127: file->i_file, filep->f_line, ! 128: directives[type]); ! 129: return(type); ! 130: case DEFINE: ! 131: case UNDEF: ! 132: case INCLUDE: ! 133: case INCLUDEDOT: ! 134: break; ! 135: case -1: ! 136: log("%s, line %d: unknown directive == \"%s\"\n", ! 137: file_red->i_file, filep->f_line, line); ! 138: break; ! 139: } ! 140: } ! 141: return(-1); ! 142: } ! 143: ! 144: /* ! 145: * Decide what type of # directive this line is. ! 146: */ ! 147: deftype(line, filep, file_red, file, parse_it) ! 148: register char *line; ! 149: register struct filepointer *filep; ! 150: register struct inclist *file_red, *file; ! 151: int parse_it; ! 152: { ! 153: register char *p; ! 154: char *directive, savechar; ! 155: register int ret; ! 156: ! 157: /* ! 158: * Parse the directive... ! 159: */ ! 160: directive=line+1; ! 161: while (*directive == ' ' || *directive == '\t') ! 162: directive++; ! 163: ! 164: p = directive; ! 165: while (*p >= 'a' && *p <= 'z') ! 166: p++; ! 167: savechar = *p; ! 168: *p = '\0'; ! 169: ret = match(directive, directives); ! 170: *p = savechar; ! 171: ! 172: /* ! 173: * If we don't recognize this compiler directive or we happen ! 174: * to just be gobbling up text while waiting for an #endif or ! 175: * a #else, then we don't need to parse this line. ! 176: */ ! 177: if (ret < 0 || ! parse_it) ! 178: return(ret); ! 179: ! 180: /* ! 181: * now decide how to parse the directive, and do it. ! 182: */ ! 183: while (*p == ' ' || *p == '\t') ! 184: p++; ! 185: switch (ret) { ! 186: case IF: ! 187: /* ! 188: * parse an expression. ! 189: */ ! 190: debug0("%s, line %d: #if %s\n", ! 191: file->i_file, filep->f_line, p); ! 192: if (zero_value(p, filep, file_red)) ! 193: ret = IFFALSE; ! 194: break; ! 195: case IFDEF: ! 196: case IFNDEF: ! 197: debug0("%s, line %d: #%s %s\n", ! 198: file->i_file, filep->f_line, directives[ret], p); ! 199: case UNDEF: ! 200: /* ! 201: * separate the name of a single symbol. ! 202: */ ! 203: while (isalnum(*p) || *p == '_') ! 204: *line++ = *p++; ! 205: *line = '\0'; ! 206: break; ! 207: case INCLUDE: ! 208: debug2("%s, line %d: #include %s\n", ! 209: file->i_file, filep->f_line, p); ! 210: /* ! 211: * Separate the name of the include file. ! 212: */ ! 213: while (*p && *p != '"' && *p != '<') ! 214: p++; ! 215: if (! *p) ! 216: return(-2); ! 217: if (*p++ == '"') { ! 218: ret = INCLUDEDOT; ! 219: while (*p && *p != '"') ! 220: *line++ = *p++; ! 221: } else ! 222: while (*p && *p != '>') ! 223: *line++ = *p++; ! 224: *line = '\0'; ! 225: break; ! 226: case DEFINE: ! 227: /* ! 228: * copy the definition back to the beginning of the line. ! 229: */ ! 230: strcpy (line, p); ! 231: break; ! 232: case ELSE: ! 233: case ENDIF: ! 234: debug0("%s, line %d: #%s\n", ! 235: file->i_file, filep->f_line, directives[ret]); ! 236: /* ! 237: * nothing to do. ! 238: */ ! 239: break; ! 240: } ! 241: return(ret); ! 242: } ! 243: ! 244: struct symtab *defined(symbol, file) ! 245: register char *symbol; ! 246: struct inclist *file; ! 247: { ! 248: register struct symtab *val; ! 249: ! 250: if (val = slookup(symbol, deflist)) { ! 251: debug1("%s defined on command line\n", symbol); ! 252: return(val); ! 253: } ! 254: if (val = fdefined(symbol, file)) ! 255: return(val); ! 256: debug1("%s not defined in %s\n", symbol, file->i_file); ! 257: return(NULL); ! 258: } ! 259: ! 260: struct symtab *fdefined(symbol, file) ! 261: register char *symbol; ! 262: struct inclist *file; ! 263: { ! 264: register struct inclist **ip; ! 265: register struct symtab *val; ! 266: register int i; ! 267: static int recurse_lvl = 0; ! 268: ! 269: if (file->i_defchecked) ! 270: return(NULL); ! 271: file->i_defchecked = TRUE; ! 272: if (val = slookup(symbol, file->i_defs)) ! 273: debug1("%s defined in %s\n", symbol, file->i_file); ! 274: if (val == NULL && file->i_list) ! 275: for (ip = file->i_list, i=0; i < file->i_listlen; i++, ip++) ! 276: if (val = fdefined(symbol, *ip)) { ! 277: debug1("%s defined in %s\n", ! 278: symbol, (*ip)->i_file); ! 279: break; ! 280: } ! 281: recurse_lvl--; ! 282: file->i_defchecked = FALSE; ! 283: ! 284: return(val); ! 285: } ! 286: ! 287: struct symtab *slookup(symbol, stab) ! 288: register char *symbol; ! 289: register struct symtab *stab; ! 290: { ! 291: if (stab) ! 292: for (; stab->s_name; stab++) ! 293: if (strcmp(symbol, stab->s_name) == 0) ! 294: return(stab); ! 295: return(NULL); ! 296: } ! 297: ! 298: /* ! 299: * Return true if the #if expression evaluates to 0 ! 300: */ ! 301: zero_value(exp, filep, file_red) ! 302: register char *exp; ! 303: register struct filepointer *filep; ! 304: register struct inclist *file_red; ! 305: { ! 306: #ifdef CPP ! 307: return (cppsetup(exp, filep, file_red) == 0); ! 308: #else CPP ! 309: return(TRUE); ! 310: #endif CPP ! 311: } ! 312: ! 313: define(def, file) ! 314: register char *def; ! 315: register struct inclist *file; ! 316: { ! 317: register char *p; ! 318: struct symtab *sp = file->i_lastdef++; ! 319: register int i; ! 320: ! 321: /* ! 322: * If we are out of space, allocate some more. ! 323: */ ! 324: if (file->i_defs == NULL ! 325: || file->i_lastdef == file->i_defs + file->i_deflen) { ! 326: if (file->i_defs) ! 327: file->i_defs = (struct symtab *) realloc(file->i_defs, ! 328: sizeof(struct symtab)*(file->i_deflen+SYMTABINC)); ! 329: else ! 330: file->i_defs = (struct symtab *) ! 331: malloc(sizeof (struct symtab) * SYMTABINC); ! 332: i=file->i_deflen; ! 333: file->i_deflen += SYMTABINC; ! 334: while (i < file->i_deflen) ! 335: file->i_defs[ i++ ].s_name = NULL; ! 336: file->i_lastdef = file->i_defs + file->i_deflen - SYMTABINC; ! 337: if (sp) /* be sure we use last cell in previous group */ ! 338: file->i_lastdef--; ! 339: sp = file->i_lastdef++; ! 340: } ! 341: else if (file->i_lastdef > file->i_defs + file->i_deflen) ! 342: log_fatal("define() botch\n"); ! 343: ! 344: /* ! 345: * copy the symbol being defined. ! 346: */ ! 347: p = def; ! 348: while (isalnum(*p) || *p == '_') ! 349: p++; ! 350: if (*p) ! 351: *p++ = '\0'; ! 352: sp->s_name = copy(def); ! 353: ! 354: /* ! 355: * And copy its value. ! 356: */ ! 357: while (*p == ' ' && *p == '\t') ! 358: p++; ! 359: sp->s_value = copy(p); ! 360: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.