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;