comparison lwcc/preproc.c @ 300:8d6c47395653 ccdev

Implemented #include and #line Theoretically, directives are now implemented.
author William Astle <lost@l-w.ca>
date Sun, 15 Sep 2013 13:49:00 -0600
parents 856caf91ffaa
children 6f7fe78bb868
comparison
equal deleted inserted replaced
299:856caf91ffaa 300:8d6c47395653
17 17
18 You should have received a copy of the GNU General Public License along with 18 You should have received a copy of the GNU General Public License along with
19 this program. If not, see <http://www.gnu.org/licenses/>. 19 this program. If not, see <http://www.gnu.org/licenses/>.
20 */ 20 */
21 21
22 #include <stdio.h>
23 #include <stdlib.h>
22 #include <string.h> 24 #include <string.h>
23 25
24 #include <lw_alloc.h> 26 #include <lw_alloc.h>
25 #include <lw_string.h> 27 #include <lw_string.h>
26 28
446 lw_free(s); 448 lw_free(s);
447 } 449 }
448 450
449 static void dir_include(struct preproc_info *pp) 451 static void dir_include(struct preproc_info *pp)
450 { 452 {
453 FILE *fp;
454 struct token *ct;
455 int sys = 0;
456 char *fn;
457 struct strbuf *strbuf;
458 int i;
459 struct preproc_info *fs;
460
461 ct = preproc_next_token_nws(pp);
462 if (ct -> ttype == TOK_STRING)
463 {
464 usrinc:
465 sys = strlen(ct -> strval);
466 fn = lw_alloc(sys - 1);
467 memcpy(fn, ct -> strval + 1, sys - 2);
468 fn[sys - 1] = 0;
469 sys = 0;
470 goto doinc;
471 }
472 else if (ct -> ttype == TOK_LT)
473 {
474 strbuf = strbuf_new();
475 for (;;)
476 {
477 ct = preproc_next_token(pp);
478 if (ct -> ttype == TOK_GT)
479 break;
480 if (ct -> ttype == TOK_EOL)
481 {
482 preproc_throw_error(pp, "Bad #include");
483 lw_free(strbuf_end(strbuf));
484 return;
485 }
486 for (i = 0; ct -> strval[i]; ct++)
487 {
488 strbuf_add(strbuf, ct -> strval[i]);
489 }
490 }
491 ct = preproc_next_token_nws(pp);
492 if (ct -> ttype != TOK_EOL)
493 {
494 preproc_throw_error(pp, "Bad #include");
495 skip_eol(pp);
496 lw_free(strbuf_end(strbuf));
497 return;
498 }
499 sys = 1;
500 fn = strbuf_end(strbuf);
501 goto doinc;
502 }
503 else
504 {
505 preproc_unget_token(pp, ct);
506 // computed include
507 ct = preproc_next_processed_token_nws(pp);
508 if (ct -> ttype == TOK_STRING)
509 goto usrinc;
510 else if (ct -> ttype == TOK_LT)
511 {
512 strbuf = strbuf_new();
513 for (;;)
514 {
515 ct = preproc_next_processed_token(pp);
516 if (ct -> ttype == TOK_GT)
517 break;
518 if (ct -> ttype == TOK_EOL)
519 {
520 preproc_throw_error(pp, "Bad #include");
521 lw_free(strbuf_end(strbuf));
522 return;
523 }
524 for (i = 0; ct -> strval[i]; ct++)
525 {
526 strbuf_add(strbuf, ct -> strval[i]);
527 }
528 }
529 ct = preproc_next_processed_token_nws(pp);
530 if (ct -> ttype != TOK_EOL)
531 {
532 preproc_throw_error(pp, "Bad #include");
533 skip_eol(pp);
534 lw_free(strbuf_end(strbuf));
535 return;
536 }
537 sys = 1;
538 fn = strbuf_end(strbuf);
539 goto doinc;
540 }
541 else
542 {
543 skip_eol(pp);
544 preproc_throw_error(pp, "Bad #include");
545 return;
546 }
547 }
548 doinc:
549 // fn = preproc_find_file(pp, fn, sys);
550 fp = fopen(fn, "rb");
551 if (!fp)
552 {
553 preproc_throw_error(pp, "Cannot open #include file - this is fatal");
554 exit(1);
555 }
556
557 /* save the current include file state, etc. */
558 fs = lw_alloc(sizeof(struct preproc_info));
559 *fs = *pp;
560 fs -> n = pp -> filestack;
561 pp -> filestack = fs;
562 pp -> fn = fn;
563 pp -> fp = fp;
564 pp -> ra = CPP_NOUNG;
565 pp -> ppeolseen = 1;
566 pp -> eolstate = 0;
567 pp -> lineno = 0;
568 pp -> column = 0;
569 pp -> qseen = 0;
570 pp -> ungetbufl = 0;
571 pp -> ungetbufs = 0;
572 pp -> ungetbuf = NULL;
573 pp -> unget = 0;
574 pp -> eolseen = 0;
575 pp -> nlseen = 0;
576 pp -> skip_level = 0;
577 pp -> found_level = 0;
578 pp -> else_level = 0;
579 pp -> else_skip_level = 0;
580
581 // now get on with processing
451 } 582 }
452 583
453 static void dir_line(struct preproc_info *pp) 584 static void dir_line(struct preproc_info *pp)
454 { 585 {
586 struct token *ct;
587 long lineno;
588 char *estr;
589
590 lineno = -1;
591
592 ct = preproc_next_processed_token_nws(pp);
593 if (ct -> ttype == TOK_NUMBER)
594 {
595 lineno = strtoul(ct -> strval, &estr, 10);
596 if (*estr)
597 {
598 preproc_throw_error(pp, "Bad #line");
599 skip_eol(pp);
600 return;
601 }
602 }
603 else
604 {
605 preproc_throw_error(pp, "Bad #line");
606 skip_eol(pp);
607 return;
608 }
609 ct = preproc_next_processed_token_nws(pp);
610 if (ct -> ttype == TOK_EOL)
611 {
612 pp -> lineno = lineno;
613 return;
614 }
615 if (ct -> ttype != TOK_STRING)
616 {
617 preproc_throw_error(pp, "Bad #line");
618 skip_eol(pp);
619 return;
620 }
621 estr = lw_strdup(ct -> strval);
622 ct = preproc_next_processed_token_nws(pp);
623 if (ct -> ttype != TOK_EOL)
624 {
625 preproc_throw_error(pp, "Bad #line");
626 skip_eol(pp);
627 lw_free(estr);
628 return;
629 }
630 pp -> fn = estr;
631 pp -> lineno = lineno;
455 } 632 }
456 633
457 static void dir_pragma(struct preproc_info *pp) 634 static void dir_pragma(struct preproc_info *pp)
458 { 635 {
459 if (pp -> skip_level) 636 if (pp -> skip_level)