Mercurial > hg > index.cgi
comparison lwcc/preproc.c @ 306:b08787e5b9f3 ccdev
Add include search paths and command line macro definitions
Added command line macro definitions. Also implemented include paths. There
is no default include path; that will be supplied by the driver program.
author | William Astle <lost@l-w.ca> |
---|---|
date | Wed, 18 Sep 2013 20:41:41 -0600 |
parents | 54f213c8fb81 |
children | 9e342c4e4b66 |
comparison
equal
deleted
inserted
replaced
305:54f213c8fb81 | 306:b08787e5b9f3 |
---|---|
20 */ | 20 */ |
21 | 21 |
22 #include <stdio.h> | 22 #include <stdio.h> |
23 #include <stdlib.h> | 23 #include <stdlib.h> |
24 #include <string.h> | 24 #include <string.h> |
25 #include <unistd.h> | |
25 | 26 |
26 #include <lw_alloc.h> | 27 #include <lw_alloc.h> |
27 #include <lw_string.h> | 28 #include <lw_string.h> |
28 | 29 |
29 #include "cpp.h" | 30 #include "cpp.h" |
30 #include "strbuf.h" | 31 #include "strbuf.h" |
32 #include "strpool.h" | |
31 #include "symbol.h" | 33 #include "symbol.h" |
32 #include "token.h" | 34 #include "token.h" |
33 | 35 |
34 static int expand_macro(struct preproc_info *, char *); | 36 static int expand_macro(struct preproc_info *, char *); |
35 static void process_directive(struct preproc_info *); | 37 static void process_directive(struct preproc_info *); |
278 if (ct -> ttype != TOK_IDENT) | 280 if (ct -> ttype != TOK_IDENT) |
279 goto baddefine; | 281 goto baddefine; |
280 | 282 |
281 mname = lw_strdup(ct -> strval); | 283 mname = lw_strdup(ct -> strval); |
282 ct = preproc_next_token(pp); | 284 ct = preproc_next_token(pp); |
283 | |
284 if (ct -> ttype == TOK_WSPACE) | 285 if (ct -> ttype == TOK_WSPACE) |
285 { | 286 { |
286 /* object like macro */ | 287 /* object like macro */ |
287 } | 288 } |
288 else if (ct -> ttype == TOK_EOL) | 289 else if (ct -> ttype == TOK_EOL) |
336 } | 337 } |
337 } | 338 } |
338 else | 339 else |
339 { | 340 { |
340 baddefine: | 341 baddefine: |
341 preproc_throw_error(pp, "bad #define"); | 342 preproc_throw_error(pp, "bad #define", ct -> ttype); |
342 baddefine2: | 343 baddefine2: |
343 token_list_destroy(tl); | 344 token_list_destroy(tl); |
344 skip_eol(pp); | 345 skip_eol(pp); |
345 lw_free(mname); | 346 lw_free(mname); |
346 while (nargs > 0) | 347 while (nargs > 0) |
351 | 352 |
352 tl = token_list_create(); | 353 tl = token_list_create(); |
353 for (;;) | 354 for (;;) |
354 { | 355 { |
355 ct = preproc_next_token(pp); | 356 ct = preproc_next_token(pp); |
357 | |
356 if (ct -> ttype == TOK_EOL) | 358 if (ct -> ttype == TOK_EOL) |
357 break; | 359 break; |
358 token_list_append(tl, token_dup(ct)); | 360 token_list_append(tl, token_dup(ct)); |
359 } | 361 } |
360 out: | 362 out: |
376 lw_free(arglist[--nargs]); | 378 lw_free(arglist[--nargs]); |
377 lw_free(arglist); | 379 lw_free(arglist); |
378 /* no need to check for EOL here */ | 380 /* no need to check for EOL here */ |
379 } | 381 } |
380 | 382 |
383 void preproc_add_macro(struct preproc_info *pp, char *str) | |
384 { | |
385 char *s; | |
386 | |
387 pp -> lexstr = lw_strdup(str); | |
388 pp -> lexstrloc = 0; | |
389 s = strchr(pp -> lexstr, '='); | |
390 if (s) | |
391 *s = ' '; | |
392 | |
393 dir_define(pp); | |
394 | |
395 lw_free(pp -> lexstr); | |
396 pp -> lexstr = NULL; | |
397 pp -> lexstrloc = 0; | |
398 } | |
399 | |
381 static void dir_undef(struct preproc_info *pp) | 400 static void dir_undef(struct preproc_info *pp) |
382 { | 401 { |
383 struct token *ct; | 402 struct token *ct; |
384 if (pp -> skip_level) | 403 if (pp -> skip_level) |
385 { | 404 { |
449 } | 468 } |
450 | 469 |
451 s = streol(pp); | 470 s = streol(pp); |
452 preproc_throw_warning(pp, "%s", s); | 471 preproc_throw_warning(pp, "%s", s); |
453 lw_free(s); | 472 lw_free(s); |
473 } | |
474 | |
475 static char *preproc_file_exists_in_dir(char *dir, char *fn) | |
476 { | |
477 int l; | |
478 char *f; | |
479 | |
480 l = snprintf(NULL, 0, "%s/%s", dir, fn); | |
481 f = lw_alloc(l + 1); | |
482 snprintf(f, l + 1, "%s/%s", dir, fn); | |
483 | |
484 if (access(f, R_OK) == 0) | |
485 return f; | |
486 lw_free(f); | |
487 return NULL; | |
488 } | |
489 | |
490 static char *preproc_find_file(struct preproc_info *pp, char *fn, int sys) | |
491 { | |
492 char *tstr; | |
493 char *pref; | |
494 char *rfn; | |
495 | |
496 /* pass through absolute paths, dumb as they are */ | |
497 if (fn[0] == '/') | |
498 return lw_strdup(fn); | |
499 | |
500 if (!sys) | |
501 { | |
502 /* look in the directory with the current file */ | |
503 tstr = strchr(pp -> fn, '/'); | |
504 if (!tstr) | |
505 pref = lw_strdup("."); | |
506 else | |
507 { | |
508 pref = lw_alloc(tstr - pp -> fn + 1); | |
509 memcpy(pref, pp -> fn, tstr - pp -> fn); | |
510 pref[tstr - pp -> fn] = 0; | |
511 } | |
512 rfn = preproc_file_exists_in_dir(pref, fn); | |
513 lw_free(pref); | |
514 if (rfn) | |
515 return rfn; | |
516 | |
517 /* look in the "quote" dir list */ | |
518 lw_stringlist_reset(pp -> quotelist); | |
519 for (pref = lw_stringlist_current(pp -> quotelist); pref; pref = lw_stringlist_next(pp -> quotelist)) | |
520 { | |
521 rfn = preproc_file_exists_in_dir(pref, fn); | |
522 if (rfn) | |
523 return rfn; | |
524 } | |
525 } | |
526 | |
527 /* look in the "include" dir list */ | |
528 lw_stringlist_reset(pp -> inclist); | |
529 for (pref = lw_stringlist_current(pp -> inclist); pref; pref = lw_stringlist_next(pp -> inclist)) | |
530 { | |
531 rfn = preproc_file_exists_in_dir(pref, fn); | |
532 if (rfn) | |
533 return rfn; | |
534 } | |
535 | |
536 /* the default search list is provided by the driver program */ | |
537 return NULL; | |
454 } | 538 } |
455 | 539 |
456 static void dir_include(struct preproc_info *pp) | 540 static void dir_include(struct preproc_info *pp) |
457 { | 541 { |
458 FILE *fp; | 542 FILE *fp; |
548 preproc_throw_error(pp, "Bad #include"); | 632 preproc_throw_error(pp, "Bad #include"); |
549 return; | 633 return; |
550 } | 634 } |
551 } | 635 } |
552 doinc: | 636 doinc: |
553 // fn = preproc_find_file(pp, fn, sys); | 637 fn = preproc_find_file(pp, fn, sys); |
638 if (!fn) | |
639 goto badfile; | |
554 fp = fopen(fn, "rb"); | 640 fp = fopen(fn, "rb"); |
555 if (!fp) | 641 if (!fp) |
556 { | 642 { |
643 lw_free(fn); | |
644 badfile: | |
557 preproc_throw_error(pp, "Cannot open #include file %s - this is fatal", fn); | 645 preproc_throw_error(pp, "Cannot open #include file %s - this is fatal", fn); |
558 exit(1); | 646 exit(1); |
559 } | 647 } |
560 | 648 |
561 /* save the current include file state, etc. */ | 649 /* save the current include file state, etc. */ |
562 fs = lw_alloc(sizeof(struct preproc_info)); | 650 fs = lw_alloc(sizeof(struct preproc_info)); |
563 *fs = *pp; | 651 *fs = *pp; |
564 fs -> n = pp -> filestack; | 652 fs -> n = pp -> filestack; |
565 pp -> curtok = NULL; | 653 pp -> curtok = NULL; |
566 pp -> filestack = fs; | 654 pp -> filestack = fs; |
567 pp -> fn = fn; | 655 pp -> fn = strpool_strdup(pp -> strpool, fn); |
656 lw_free(fn); | |
568 pp -> fp = fp; | 657 pp -> fp = fp; |
569 pp -> ra = CPP_NOUNG; | 658 pp -> ra = CPP_NOUNG; |
570 pp -> ppeolseen = 1; | 659 pp -> ppeolseen = 1; |
571 pp -> eolstate = 0; | 660 pp -> eolstate = 0; |
572 pp -> lineno = 1; | 661 pp -> lineno = 1; |