00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifdef __WIN32__
00030 #pragma warning(disable : 4996)
00031 #endif
00032
00033 #include "def.h"
00034
00035 #include <string.h>
00036
00037 extern const char *directives[];
00038 extern inclist maininclist;
00039
00040 int find_includes(struct filepointer *filep, inclist *file, inclist *file_red, int recursion, bool failOK)
00041 {
00042 register char *line;
00043 register int type;
00044 bool recfailOK;
00045
00046 while ((line = getline(filep))) {
00047 switch(type = deftype(line, filep, file_red, file, true)) {
00048 case IF:
00049 doif:
00050 type = find_includes(filep, file,
00051 file_red, recursion+1, failOK);
00052 while ((type == ELIF) || (type == ELIFFALSE) ||
00053 (type == ELIFGUESSFALSE))
00054 type = gobble(filep, file, file_red);
00055 if (type == ELSE)
00056 gobble(filep, file, file_red);
00057 break;
00058 case IFFALSE:
00059 case IFGUESSFALSE:
00060 doiffalse:
00061 if (type == IFGUESSFALSE || type == ELIFGUESSFALSE)
00062 recfailOK = true;
00063 else
00064 recfailOK = failOK;
00065 type = gobble(filep, file, file_red);
00066 if (type == ELSE)
00067 find_includes(filep, file,
00068 file_red, recursion+1, recfailOK);
00069 else
00070 if (type == ELIF)
00071 goto doif;
00072 else
00073 if ((type == ELIFFALSE) || (type == ELIFGUESSFALSE))
00074 goto doiffalse;
00075 break;
00076 case IFDEF:
00077 case IFNDEF:
00078 if ((type == IFDEF && isdefined(line, file_red, NULL))
00079 || (type == IFNDEF && !isdefined(line, file_red, NULL))) {
00080 debug(1,(type == IFNDEF ?
00081 "line %d: %s !def'd in %s via %s%s\n" : "",
00082 filep->f_line, line,
00083 file->i_file, file_red->i_file, ": doit"));
00084 type = find_includes(filep, file,
00085 file_red, recursion+1, failOK);
00086 while (type == ELIF || type == ELIFFALSE || type == ELIFGUESSFALSE)
00087 type = gobble(filep, file, file_red);
00088 if (type == ELSE)
00089 gobble(filep, file, file_red);
00090 }
00091 else {
00092 debug(1,(type == IFDEF ?
00093 "line %d: %s !def'd in %s via %s%s\n" : "",
00094 filep->f_line, line,
00095 file->i_file, file_red->i_file, ": gobble"));
00096 type = gobble(filep, file, file_red);
00097 if (type == ELSE)
00098 find_includes(filep, file,
00099 file_red, recursion+1, failOK);
00100 else if (type == ELIF)
00101 goto doif;
00102 else if (type == ELIFFALSE || type == ELIFGUESSFALSE)
00103 goto doiffalse;
00104 }
00105 break;
00106 case ELSE:
00107 case ELIFFALSE:
00108 case ELIFGUESSFALSE:
00109 case ELIF:
00110 if (!recursion)
00111 gobble(filep, file, file_red);
00112 case ENDIF:
00113 if (recursion)
00114 return(type);
00115 case DEFINE:
00116 define(line, file);
00117 break;
00118 case UNDEF:
00119 if (!*line) {
00120 warning("%s, line %d: incomplete undef == \"%s\"\n",
00121 file_red->i_file, filep->f_line, line);
00122 break;
00123 }
00124 undefine(line, file_red);
00125 break;
00126 case INCLUDE:
00127 add_include(filep, file, file_red, line, false, failOK);
00128 break;
00129 case INCLUDEDOT:
00130 add_include(filep, file, file_red, line, true, failOK);
00131 break;
00132 case ERROR:
00133 warning("%s: %d: %s\n", file_red->i_file,
00134 filep->f_line, line);
00135 break;
00136
00137 case PRAGMA:
00138 case IDENT:
00139 case SCCS:
00140 case EJECT:
00141 case IMPORT:
00142 break;
00143 case -1:
00144 warning("%s", file_red->i_file);
00145 if (file_red != file)
00146 warning1(" (reading %s)", file->i_file);
00147 warning1(", line %d: unknown directive == \"%s\"\n",
00148 filep->f_line, line);
00149 break;
00150 case -2:
00151 warning("%s", file_red->i_file);
00152 if (file_red != file)
00153 warning1(" (reading %s)", file->i_file);
00154 warning1(", line %d: incomplete include == \"%s\"\n",
00155 filep->f_line, line);
00156 break;
00157 }
00158 }
00159 return(-1);
00160 }
00161
00162 int gobble(register struct filepointer *filep, inclist *file,
00163 inclist *file_red)
00164 {
00165 register char *line;
00166 register int type;
00167
00168 while ((line = getline(filep))) {
00169 switch(type = deftype(line, filep, file_red, file, false)) {
00170 case IF:
00171 case IFFALSE:
00172 case IFGUESSFALSE:
00173 case IFDEF:
00174 case IFNDEF:
00175 type = gobble(filep, file, file_red);
00176 while ((type == ELIF) || (type == ELIFFALSE) ||
00177 (type == ELIFGUESSFALSE))
00178 type = gobble(filep, file, file_red);
00179 if (type == ELSE)
00180 (void)gobble(filep, file, file_red);
00181 break;
00182 case ELSE:
00183 case ENDIF:
00184 debug(0,("%s, line %d: #%s\n",
00185 file->i_file, filep->f_line,
00186 directives[type]));
00187 return(type);
00188 case DEFINE:
00189 case UNDEF:
00190 case INCLUDE:
00191 case INCLUDEDOT:
00192 case PRAGMA:
00193 case ERROR:
00194 case IDENT:
00195 case SCCS:
00196 case EJECT:
00197 case IMPORT:
00198 break;
00199 case ELIF:
00200 case ELIFFALSE:
00201 case ELIFGUESSFALSE:
00202 return(type);
00203 case -1:
00204 warning("%s, line %d: unknown directive == \"%s\"\n",
00205 file_red->i_file, filep->f_line, line);
00206 break;
00207 }
00208 }
00209 return(-1);
00210 }
00211
00212
00213
00214
00215 int deftype(register char *line, register struct filepointer *filep,
00216 register inclist *file_red, register inclist *file,
00217 int parse_it)
00218 {
00219 register char *p;
00220 char *directive, savechar;
00221 register int ret;
00222
00223
00224
00225
00226 directive=line+1;
00227 while (*directive == ' ' || *directive == '\t')
00228 directive++;
00229
00230 p = directive;
00231 while (*p >= 'a' && *p <= 'z')
00232 p++;
00233 savechar = *p;
00234 *p = '\0';
00235 ret = match(directive, directives);
00236 *p = savechar;
00237
00238
00239
00240
00241
00242
00243
00244 if (ret == ELIF && !parse_it)
00245 {
00246 while (*p == ' ' || *p == '\t')
00247 p++;
00248
00249
00250
00251 debug(0,("%s, line %d: #elif %s ",
00252 file->i_file, filep->f_line, p));
00253 ret = zero_value(p, filep, file_red);
00254 if (ret != IF)
00255 {
00256 debug(0,("false...\n"));
00257 if (ret == IFFALSE)
00258 return(ELIFFALSE);
00259 else
00260 return(ELIFGUESSFALSE);
00261 }
00262 else
00263 {
00264 debug(0,("true...\n"));
00265 return(ELIF);
00266 }
00267 }
00268
00269 if (ret < 0 || ! parse_it)
00270 return(ret);
00271
00272
00273
00274
00275 while (*p == ' ' || *p == '\t')
00276 p++;
00277 switch (ret) {
00278 case IF:
00279
00280
00281
00282 ret = zero_value(p, filep, file_red);
00283 debug(0,("%s, line %d: %s #if %s\n",
00284 file->i_file, filep->f_line, ret?"false":"true", p));
00285 break;
00286 case IFDEF:
00287 case IFNDEF:
00288 debug(0,("%s, line %d: #%s %s\n",
00289 file->i_file, filep->f_line, directives[ret], p));
00290 case UNDEF:
00291
00292
00293
00294 while (isalnum(*p) || *p == '_')
00295 *line++ = *p++;
00296 *line = '\0';
00297 break;
00298 case INCLUDE:
00299 debug(2,("%s, line %d: #include %s\n",
00300 file->i_file, filep->f_line, p));
00301
00302
00303 {
00304 struct symtab *sym = isdefined(p, file_red, NULL);
00305 while (sym) {
00306 p = sym->s_value;
00307 debug(3,("%s : #includes SYMBOL %s = %s\n",
00308 file->i_incstring,
00309 sym -> s_name,
00310 sym -> s_value));
00311
00312 file->i_included_sym = true;
00313 sym = isdefined(p, file_red, NULL);
00314 }
00315 }
00316
00317
00318
00319
00320 while (*p && *p != '"' && *p != '<')
00321 p++;
00322 if (! *p)
00323 return(-2);
00324 if (*p++ == '"') {
00325 ret = INCLUDEDOT;
00326 while (*p && *p != '"')
00327 *line++ = *p++;
00328 } else
00329 while (*p && *p != '>')
00330 *line++ = *p++;
00331 *line = '\0';
00332 break;
00333 case DEFINE:
00334
00335
00336
00337 strcpy (line, p);
00338 break;
00339 case ELSE:
00340 case ENDIF:
00341 case ELIF:
00342 case PRAGMA:
00343 case ERROR:
00344 case IDENT:
00345 case SCCS:
00346 case EJECT:
00347 case IMPORT:
00348 debug(0,("%s, line %d: #%s\n",
00349 file->i_file, filep->f_line, directives[ret]));
00350
00351
00352
00353 break;
00354 }
00355 return(ret);
00356 }
00357
00358 symtab *isdefined(register char *symbol, inclist *file,
00359 inclist **srcfile)
00360 {
00361 register struct symtab *val;
00362
00363 if ((val = slookup(symbol, &maininclist))) {
00364 debug(1,("%s defined on command line\n", symbol));
00365 if (srcfile != NULL) *srcfile = &maininclist;
00366 return(val);
00367 }
00368 if ((val = fdefined(symbol, file, srcfile)))
00369 return(val);
00370 debug(1,("%s not defined in %s\n", symbol, file->i_file));
00371 return(NULL);
00372 }
00373
00374 struct symtab *fdefined(register char *symbol, inclist *file, inclist **srcfile)
00375 {
00376 register inclist **ip;
00377 register struct symtab *val;
00378 register int i;
00379 static int recurse_lvl = 0;
00380
00381 if (file->i_defchecked)
00382 return(NULL);
00383 file->i_defchecked = true;
00384 if ((val = slookup(symbol, file)))
00385 debug(1,("%s defined in %s as %s\n", symbol, file->i_file, val->s_value));
00386 if (val == NULL && file->i_list)
00387 {
00388 for (ip = file->i_list, i=0; i < file->i_listlen; i++, ip++)
00389 if ((val = fdefined(symbol, *ip, srcfile))) {
00390 break;
00391 }
00392 }
00393 else if (val != NULL && srcfile != NULL) *srcfile = file;
00394 recurse_lvl--;
00395 file->i_defchecked = false;
00396
00397 return(val);
00398 }
00399
00400
00401
00402
00403 int zero_value(register char *exp, register struct filepointer *filep,
00404 register inclist *file_red)
00405 {
00406 if (cppsetup(exp, filep, file_red))
00407 return(IFFALSE);
00408 else
00409 return(IF);
00410 }
00411
00412 void define(char *def, inclist *file)
00413 {
00414 char *val;
00415
00416
00417 val = def;
00418 while (isalnum(*val) || *val == '_')
00419 val++;
00420 if (*val)
00421 *val++ = '\0';
00422 while (*val == ' ' || *val == '\t')
00423 val++;
00424
00425 if (!*val)
00426 val = (char *)"1";
00427 define2(def, val, file);
00428 }
00429
00430 void define2(char *name, char *val, inclist *file)
00431 {
00432 int first, last, below;
00433 register struct symtab *sp = NULL, *dest;
00434
00435
00436 if (file->i_defs == NULL)
00437 {
00438 file->i_defs = (struct symtab *)
00439 malloc(sizeof (struct symtab) * SYMTABINC);
00440 file->i_deflen = SYMTABINC;
00441 file->i_ndefs = 0;
00442 }
00443 else if (file->i_ndefs == file->i_deflen)
00444 file->i_defs = (struct symtab *)
00445 realloc(file->i_defs,
00446 sizeof(struct symtab)*(file->i_deflen+=SYMTABINC));
00447
00448 if (file->i_defs == NULL)
00449 fatalerr("malloc()/realloc() failure in insert_defn()\n");
00450
00451 below = first = 0;
00452 last = file->i_ndefs - 1;
00453 while (last >= first)
00454 {
00455
00456 register char *s1;
00457 register char *s2;
00458 register int middle = (first + last) / 2;
00459
00460
00461 s1 = name;
00462 s2 = file->i_defs[middle].s_name;
00463 while (*s1++ == *s2++)
00464 if (s2[-1] == '\0') break;
00465
00466
00467 if (*--s1 == *--s2)
00468 {
00469 sp = file->i_defs + middle;
00470 break;
00471 }
00472
00473
00474 if (*s1 > *s2)
00475 {
00476 below = first;
00477 first = middle + 1;
00478 }
00479
00480 else
00481 {
00482 below = last = middle - 1;
00483 }
00484 }
00485
00486
00487
00488 if (sp != NULL)
00489 {
00490 free(sp->s_value);
00491 sp->s_value = copy(val);
00492 return;
00493 }
00494
00495 sp = file->i_defs + file->i_ndefs++;
00496 dest = file->i_defs + below + 1;
00497 while (sp > dest)
00498 {
00499 *sp = sp[-1];
00500 sp--;
00501 }
00502 sp->s_name = copy(name);
00503 sp->s_value = copy(val);
00504 }
00505
00506 struct symtab *slookup(register char *symbol, register inclist *file)
00507 {
00508 register int first = 0;
00509 register int last = file->i_ndefs - 1;
00510
00511 if (file) while (last >= first)
00512 {
00513
00514 register char *s1;
00515 register char *s2;
00516 register int middle = (first + last) / 2;
00517
00518
00519 s1 = symbol;
00520 s2 = file->i_defs[middle].s_name;
00521 while (*s1++ == *s2++)
00522 if (s2[-1] == '\0') break;
00523
00524
00525 if (*--s1 == *--s2)
00526 {
00527 return file->i_defs + middle;
00528 }
00529
00530
00531 if (*s1 > *s2)
00532 {
00533 first = middle + 1;
00534 }
00535
00536 else
00537 {
00538 last = middle - 1;
00539 }
00540 }
00541 return(NULL);
00542 }
00543
00544 void undefine(char *symbol, register inclist *file)
00545 {
00546 register struct symtab *ptr;
00547 inclist *srcfile;
00548 while ((ptr = isdefined(symbol, file, &srcfile)) != NULL)
00549 {
00550 srcfile->i_ndefs--;
00551 for (; ptr < srcfile->i_defs + srcfile->i_ndefs; ptr++)
00552 *ptr = ptr[1];
00553 }
00554 }