Changeset 5522 for trunk/tools/wrc/preproc.c
- Timestamp:
- Apr 16, 2001, 7:11:03 PM (24 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/tools/wrc/preproc.c
r3476 r5522 9 9 #include <stdlib.h> 10 10 #include <string.h> 11 #include <assert.h> 11 12 12 13 #include "wrc.h" 13 14 #include "utils.h" 14 15 #include "preproc.h" 15 #include "parser.h"16 16 17 17 18 18 extern void set_pp_ignore(int); /* From parser.l */ 19 19 20 static char *current_define;21 22 20 #define HASHKEY 2039 23 static struct pp_entry*pp_defines[HASHKEY];21 static pp_entry_t *pp_defines[HASHKEY]; 24 22 25 23 #define MAXIFSTACK 64 26 static struct if_state ifstack[MAXIFSTACK];27 static int if stackidx = 0;24 static if_state_t if_stack[MAXIFSTACK]; 25 static int if_stack_idx = 0; 28 26 29 27 #if 0 28 void pp_status(void) __attribute__((destructor)); 30 29 void pp_status(void) 31 30 { … … 33 32 int sum; 34 33 int total = 0; 35 struct pp_entry*ppp;36 37 printf("Defines statistics:\n");34 pp_entry_t *ppp; 35 36 fprintf(stderr, "Defines statistics:\n"); 38 37 for(i = 0; i < HASHKEY; i++) 39 38 { … … 42 41 sum++; 43 42 total += sum; 44 printf("%4d, %3d\n", i, sum); 45 } 46 printf("Total defines: %d\n", total); 47 } 48 #pragma exit pp_status 43 fprintf(stderr, "%4d, %3d\n", i, sum); 44 } 45 fprintf(stderr, "Total defines: %d\n", total); 46 } 49 47 #endif 50 48 51 49 /* Don't comment on the hash, its primitive but functional... */ 52 int pp _hash(char *str)50 int pphash(char *str) 53 51 { 54 52 int sum = 0; … … 58 56 } 59 57 60 struct pp_entry *pp_lookup(char *ident) 61 { 62 int index = pp_hash(ident); 63 struct pp_entry *ppp; 64 for(ppp = pp_defines[index]; ppp; ppp = ppp->next) 58 pp_entry_t *pplookup(char *ident) 59 { 60 int idx = pphash(ident); 61 pp_entry_t *ppp; 62 63 for(ppp = pp_defines[idx]; ppp; ppp = ppp->next) 65 64 { 66 65 if(!strcmp(ident, ppp->ident)) … … 70 69 } 71 70 72 void set_define(char *name)73 {74 current_define = xstrdup(name);75 }76 77 71 void del_define(char *name) 78 72 { 79 int i ndex;80 struct pp_entry*ppp;81 82 if((ppp = pp _lookup(name)) == NULL)73 int idx; 74 pp_entry_t *ppp; 75 76 if((ppp = pplookup(name)) == NULL) 83 77 { 84 78 if(pedantic) … … 87 81 } 88 82 89 index = pp_hash(name); 90 if(pp_defines[index] == ppp) 91 { 92 pp_defines[index] = ppp->next; 93 if(pp_defines[index]) 94 pp_defines[index]->prev = NULL; 83 if(ppp->iep) 84 { 85 if(debuglevel & DEBUGLEVEL_PPMSG) 86 fprintf(stderr, "del_define: %s:%d: includelogic removed, include_ppp='%s', file=%s\n", input_name, line_number, name, ppp->iep->filename); 87 if(ppp->iep == includelogiclist) 88 { 89 includelogiclist = ppp->iep->next; 90 if(includelogiclist) 91 includelogiclist->prev = NULL; 92 } 93 else 94 { 95 ppp->iep->prev->next = ppp->iep->next; 96 if(ppp->iep->next) 97 ppp->iep->next->prev = ppp->iep->prev; 98 } 99 free(ppp->iep->filename); 100 free(ppp->iep); 101 } 102 103 idx = pphash(name); 104 if(pp_defines[idx] == ppp) 105 { 106 pp_defines[idx] = ppp->next; 107 if(pp_defines[idx]) 108 pp_defines[idx]->prev = NULL; 95 109 } 96 110 else … … 100 114 ppp->next->prev = ppp->prev; 101 115 } 116 102 117 free(ppp); 103 } 104 105 void add_define(char *text) 118 119 if(debuglevel & DEBUGLEVEL_PPMSG) 120 printf("Deleted (%s, %d) <%s>\n", input_name, line_number, name); 121 } 122 123 pp_entry_t *add_define(char *def, char *text) 106 124 { 107 125 int len; 108 126 char *cptr; 109 int index = pp_hash(current_define); 110 struct pp_entry *ppp; 111 if(pp_lookup(current_define) != NULL) 127 int idx = pphash(def); 128 pp_entry_t *ppp; 129 130 if((ppp = pplookup(def)) != NULL) 112 131 { 113 132 if(pedantic) 114 yywarning("Redefinition of %s", current_define); 115 del_define(current_define); 116 } 117 ppp = (struct pp_entry *)xmalloc(sizeof(struct pp_entry)); 118 ppp->ident = current_define; 119 ppp->subst = xstrdup(text); 120 ppp->next = pp_defines[index]; 121 pp_defines[index] = ppp; 133 yywarning("Redefinition of %s\n\tPrevious definition: %s:%d", def, ppp->filename, ppp->linenumber); 134 del_define(def); 135 } 136 ppp = (pp_entry_t *)xmalloc(sizeof(pp_entry_t)); 137 ppp->ident = def; 138 ppp->type = def_define; 139 ppp->subst.text = text; 140 ppp->filename = input_name ? xstrdup(input_name) : "<internal or cmdline>"; 141 ppp->linenumber = input_name ? line_number : 0; 142 ppp->next = pp_defines[idx]; 143 pp_defines[idx] = ppp; 122 144 if(ppp->next) 123 145 ppp->next->prev = ppp; 124 /* Strip trailing white space from subst text */ 125 len = strlen(ppp->subst); 126 while(len && strchr(" \t\r\n", ppp->subst[len-1])) 127 { 128 ppp->subst[--len] = '\0'; 129 } 130 /* Strip leading white space from subst text */ 131 for(cptr = ppp->subst; *cptr && strchr(" \t\r", *cptr); cptr++) 146 if(text) 147 { 148 /* Strip trailing white space from subst text */ 149 len = strlen(text); 150 while(len && strchr(" \t\r\n", text[len-1])) 151 { 152 text[--len] = '\0'; 153 } 154 /* Strip leading white space from subst text */ 155 for(cptr = text; *cptr && strchr(" \t\r", *cptr); cptr++) 132 156 ; 133 if(ppp->subst != cptr) 134 memmove(ppp->subst, cptr, strlen(cptr)+1); 135 if(yydebug) 136 printf("Added (%s, %d) <%s> to <%s>\n", input_name, line_number, ppp->ident, ppp->subst); 137 } 138 139 void add_cmdline_define(char *set) 157 if(text != cptr) 158 memmove(text, cptr, strlen(cptr)+1); 159 } 160 if(debuglevel & DEBUGLEVEL_PPMSG) 161 printf("Added define (%s, %d) <%s> to <%s>\n", input_name, line_number, ppp->ident, text ? text : "(null)"); 162 163 return ppp; 164 } 165 166 pp_entry_t *add_cmdline_define(char *set) 140 167 { 141 168 char *cpy = xstrdup(set); /* Because gcc passes a R/O string */ … … 143 170 if(cptr) 144 171 *cptr = '\0'; 145 set_define(cpy); 146 add_define(cptr ? cptr+1 : ""); 147 free(cpy); 148 } 149 150 /*kso added test for __SEMICOLON__ since __WIN32OS2__ isn't defined! */ 151 #if defined(__SEMICOLON__) || defined(_Windows) || defined(__MSDOS__) || defined(__WIN32OS2__) 172 return add_define(cpy, xstrdup(cptr ? cptr+1 : "")); 173 } 174 175 pp_entry_t *add_special_define(char *id) 176 { 177 pp_entry_t *ppp = add_define(xstrdup(id), xstrdup("")); 178 ppp->type = def_special; 179 return ppp; 180 } 181 182 pp_entry_t *add_macro(char *id, marg_t *args[], int nargs, mtext_t *exp) 183 { 184 int idx = pphash(id); 185 pp_entry_t *ppp; 186 187 if((ppp = pplookup(id)) != NULL) 188 { 189 if(pedantic) 190 yywarning("Redefinition of %s\n\tPrevious definition: %s:%d", id, ppp->filename, ppp->linenumber); 191 del_define(id); 192 } 193 ppp = (pp_entry_t *)xmalloc(sizeof(pp_entry_t)); 194 ppp->ident = id; 195 ppp->type = def_macro; 196 ppp->margs = args; 197 ppp->nargs = nargs; 198 ppp->subst.mtext= exp; 199 ppp->filename = input_name ? xstrdup(input_name) : "<internal or cmdline>"; 200 ppp->linenumber = input_name ? line_number : 0; 201 ppp->next = pp_defines[idx]; 202 pp_defines[idx] = ppp; 203 if(ppp->next) 204 ppp->next->prev = ppp; 205 206 if(debuglevel & DEBUGLEVEL_PPMSG) 207 { 208 fprintf(stderr, "Added macro (%s, %d) <%s(%d)> to <", input_name, line_number, ppp->ident, nargs); 209 for(; exp; exp = exp->next) 210 { 211 switch(exp->type) 212 { 213 case exp_text: 214 fprintf(stderr, " \"%s\" ", exp->subst.text); 215 break; 216 case exp_stringize: 217 fprintf(stderr, " #(%d) ", exp->subst.argidx); 218 break; 219 case exp_concat: 220 fprintf(stderr, "##"); 221 break; 222 case exp_subst: 223 fprintf(stderr, " <%d> ", exp->subst.argidx); 224 break; 225 } 226 } 227 fprintf(stderr, ">\n"); 228 } 229 return ppp; 230 } 231 232 233 /* 234 *------------------------------------------------------------------------- 235 * Include management 236 *------------------------------------------------------------------------- 237 */ 238 #if defined(_Windows) || defined(__MSDOS__) 152 239 #define INCLUDESEPARATOR ";" 153 #warning "Using ; as include separator"154 240 #else 155 #warning "Using : as include separator"156 241 #define INCLUDESEPARATOR ":" 157 242 #endif … … 192 277 } 193 278 194 FILE *open_include(const char *name, int search )279 FILE *open_include(const char *name, int search, char **newpath) 195 280 { 196 281 char *cpy = xstrdup(name); … … 212 297 { 213 298 /* Search current dir and then -I path */ 214 fp = fopen( name, "rt");299 fp = fopen(cpy, "rb"); 215 300 if(fp) 216 301 { 217 if( yydebug)302 if(debuglevel & DEBUGLEVEL_PPMSG) 218 303 printf("Going to include <%s>\n", name); 219 free(cpy); 304 if(newpath) 305 *newpath = cpy; 306 else 307 free(cpy); 220 308 return fp; 221 309 } … … 229 317 strcat(path, "/"); 230 318 strcat(path, cpy); 231 fp = fopen(path, "r t");232 if(fp && yydebug)319 fp = fopen(path, "rb"); 320 if(fp && (debuglevel & DEBUGLEVEL_PPMSG)) 233 321 printf("Going to include <%s>\n", path); 234 free(path);235 322 if(fp) 236 323 { 324 if(newpath) 325 *newpath = path; 326 else 327 free(path); 237 328 free(cpy); 238 329 return fp; 239 330 } 240 331 free(path); 241 332 } 242 333 free(cpy); 334 if(newpath) 335 *newpath = NULL; 243 336 return NULL; 244 337 } 245 338 246 void push_if(int truecase, int wastrue, int nevertrue) 247 { 248 if(ifstackidx >= MAXIFSTACK-1) 249 internal_error(__FILE__, __LINE__, "#if stack overflow"); 250 ifstack[ifstackidx].current = truecase && !wastrue; 251 ifstack[ifstackidx].hasbeentrue = wastrue; 252 ifstack[ifstackidx].nevertrue = nevertrue; 253 if(nevertrue || !(truecase && !wastrue)) 254 set_pp_ignore(1); 255 if(yydebug) 256 printf("push_if: %d %d %d (%d %d %d)\n", 257 truecase, 258 wastrue, 259 nevertrue, 260 ifstack[ifstackidx].current, 261 ifstack[ifstackidx].hasbeentrue, 262 ifstack[ifstackidx].nevertrue); 263 ifstackidx++; 264 } 265 266 int pop_if(void) 267 { 268 if(ifstackidx <= 0) 269 yyerror("#endif without #if|#ifdef|#ifndef (#if stack underflow)"); 270 ifstackidx--; 271 if(yydebug) 272 printf("pop_if: %d %d %d\n", 273 ifstack[ifstackidx].current, 274 ifstack[ifstackidx].hasbeentrue, 275 ifstack[ifstackidx].nevertrue); 276 if(ifstack[ifstackidx].nevertrue || !ifstack[ifstackidx].current) 277 set_pp_ignore(0); 278 return ifstack[ifstackidx].hasbeentrue || ifstack[ifstackidx].current; 279 } 280 281 int isnevertrue_if(void) 282 { 283 return ifstackidx > 0 && ifstack[ifstackidx-1].nevertrue; 284 } 285 339 /* 340 *------------------------------------------------------------------------- 341 * #if, #ifdef, #ifndef, #else, #elif and #endif state management 342 * 343 * #if state transitions are made on basis of the current TOS and the next 344 * required state. The state transitions are required to housekeep because 345 * #if:s can be nested. The ignore case is activated to prevent output from 346 * within a false clause. 347 * Some special cases come from the fact that the #elif cases are not 348 * binary, but three-state. The problem is that all other elif-cases must 349 * be false when one true one has been found. A second problem is that the 350 * #else clause is a final clause. No extra #else:s may follow. 351 * 352 * The states mean: 353 * if_true Process input to output 354 * if_false Process input but no output 355 * if_ignore Process input but no output 356 * if_elif Process input but no output 357 * if_elsefalse Process input but no output 358 * if_elsettrue Process input to output 359 * 360 * The possible state-sequences are [state(stack depth)] (rest can be deduced): 361 * TOS #if 1 #else #endif 362 * if_true(n) if_true(n+1) if_elsefalse(n+1) 363 * if_false(n) if_ignore(n+1) if_ignore(n+1) 364 * if_elsetrue(n) if_true(n+1) if_elsefalse(n+1) 365 * if_elsefalse(n) if_ignore(n+1) if_ignore(n+1) 366 * if_elif(n) if_ignore(n+1) if_ignore(n+1) 367 * if_ignore(n) if_ignore(n+1) if_ignore(n+1) 368 * 369 * TOS #if 1 #elif 0 #else #endif 370 * if_true(n) if_true(n+1) if_elif(n+1) if_elif(n+1) 371 * if_false(n) if_ignore(n+1) if_ignore(n+1) if_ignore(n+1) 372 * if_elsetrue(n) if_true(n+1) if_elif(n+1) if_elif(n+1) 373 * if_elsefalse(n) if_ignore(n+1) if_ignore(n+1) if_ignore(n+1) 374 * if_elif(n) if_ignore(n+1) if_ignore(n+1) if_ignore(n+1) 375 * if_ignore(n) if_ignore(n+1) if_ignore(n+1) if_ignore(n+1) 376 * 377 * TOS #if 0 #elif 1 #else #endif 378 * if_true(n) if_false(n+1) if_true(n+1) if_elsefalse(n+1) 379 * if_false(n) if_ignore(n+1) if_ignore(n+1) if_ignore(n+1) 380 * if_elsetrue(n) if_false(n+1) if_true(n+1) if_elsefalse(n+1) 381 * if_elsefalse(n) if_ignore(n+1) if_ignore(n+1) if_ignore(n+1) 382 * if_elif(n) if_ignore(n+1) if_ignore(n+1) if_ignore(n+1) 383 * if_ignore(n) if_ignore(n+1) if_ignore(n+1) if_ignore(n+1) 384 * 385 *------------------------------------------------------------------------- 386 */ 387 static char *if_state_str[] = { 388 "if_false", 389 "if_true", 390 "if_elif", 391 "if_elsefalse", 392 "if_elsetrue", 393 "if_ignore" 394 }; 395 396 void push_if(if_state_t s) 397 { 398 if(if_stack_idx >= MAXIFSTACK) 399 internal_error(__FILE__, __LINE__, "#if-stack overflow; #{if,ifdef,ifndef} nested too deeply (> %d)", MAXIFSTACK); 400 401 if(debuglevel & DEBUGLEVEL_PPLEX) 402 fprintf(stderr, "Push if %s:%d: %s(%d) -> %s(%d)\n", input_name, line_number, if_state_str[if_state()], if_stack_idx, if_state_str[s], if_stack_idx+1); 403 404 if_stack[if_stack_idx++] = s; 405 406 switch(s) 407 { 408 case if_true: 409 case if_elsetrue: 410 break; 411 case if_false: 412 case if_elsefalse: 413 case if_elif: 414 case if_ignore: 415 push_ignore_state(); 416 break; 417 } 418 } 419 420 if_state_t pop_if(void) 421 { 422 if(if_stack_idx <= 0) 423 yyerror("#{endif,else,elif} without #{if,ifdef,ifndef} (#if-stack underflow)"); 424 425 switch(if_state()) 426 { 427 case if_true: 428 case if_elsetrue: 429 break; 430 case if_false: 431 case if_elsefalse: 432 case if_elif: 433 case if_ignore: 434 pop_ignore_state(); 435 break; 436 } 437 438 if(debuglevel & DEBUGLEVEL_PPLEX) 439 fprintf(stderr, "Pop if %s:%d: %s(%d) -> %s(%d)\n", 440 input_name, 441 line_number, 442 if_state_str[if_state()], 443 if_stack_idx, 444 if_state_str[if_stack[if_stack_idx <= 1 ? if_true : if_stack_idx-2]], 445 if_stack_idx-1); 446 447 return if_stack[--if_stack_idx]; 448 } 449 450 if_state_t if_state(void) 451 { 452 if(!if_stack_idx) 453 return if_true; 454 else 455 return if_stack[if_stack_idx-1]; 456 } 457 458 459 void next_if_state(int i) 460 { 461 switch(if_state()) 462 { 463 case if_true: 464 case if_elsetrue: 465 push_if(i ? if_true : if_false); 466 break; 467 case if_false: 468 case if_elsefalse: 469 case if_elif: 470 case if_ignore: 471 push_if(if_ignore); 472 break; 473 default: 474 internal_error(__FILE__, __LINE__, "Invalid if_state (%d) in #{if,ifdef,ifndef} directive", (int)if_state()); 475 } 476 } 477 478 int get_if_depth(void) 479 { 480 return if_stack_idx; 481 } 482
Note:
See TracChangeset
for help on using the changeset viewer.