Mercurial > hg > index.cgi
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) |