The include directive needs to be parsed as pp-tokens, not as token (i.e. no conversion to TOK_STR or TOK_NUM). Also fix parsing computed includes using quoted strings.
Unified · Split
| @@ -1737,34 +1737,27 @@ ST_FUNC void preprocess(int is_bof) · 1736 unmodified lines | |||
| 1737 | inp(); | 1737 | inp(); |
| 1738 | #endif | 1738 | #endif |
| 1739 | } else { | 1739 | } else { |
| 1740 | /* computed #include : either we have only strings or | 1740 | int len; |
| 1741 | we have anything enclosed in '<>' */ | 1741 | /* computed #include : concatenate everything up to linefeed, |
| 1742 | the result must be one of the two accepted forms. | ||
| 1743 | Don't convert pp-tokens to tokens here. */ | ||
| 1744 | parse_flags = (PARSE_FLAG_PREPROCESS | ||
| 1745 | | PARSE_FLAG_LINEFEED | ||
| 1746 | | (parse_flags & PARSE_FLAG_ASM_FILE)); | ||
| 1742 | next(); | 1747 | next(); |
| 1743 | buf[0] = '\0'; | 1748 | buf[0] = '\0'; |
| 1744 | if (tok == TOK_STR) { | 1749 | while (tok != TOK_LINEFEED) { |
| 1745 | while (tok != TOK_LINEFEED) { | 1750 | pstrcat(buf, sizeof(buf), get_tok_str(tok, &tokc)); |
| 1746 | if (tok != TOK_STR) { | 1751 | next(); |
| 1747 | include_syntax: | 1752 | } |
| 1748 | tcc_error("'#include' expects \"FILENAME\" or <FILENAME>"); | 1753 | len = strlen(buf); |
| 1749 | } | 1754 | /* check syntax and remove '<>|""' */ |
| 1750 | pstrcat(buf, sizeof(buf), (char *)tokc.str.data); | 1755 | if ((len < 2 || ((buf[0] != '"' || buf[len-1] != '"') && |
| 1751 | next(); | 1756 | (buf[0] != '<' || buf[len-1] != '>')))) |
| 1752 | } | 1757 | tcc_error("'#include' expects \"FILENAME\" or <FILENAME>"); |
| 1753 | c = '\"'; | 1758 | c = buf[len-1]; |
| 1754 | } else { | 1759 | memmove(buf, buf + 1, len - 2); |
| 1755 | int len; | 1760 | buf[len - 2] = '\0'; |
| 1756 | while (tok != TOK_LINEFEED) { | ||
| 1757 | pstrcat(buf, sizeof(buf), get_tok_str(tok, &tokc)); | ||
| 1758 | next(); | ||
| 1759 | } | ||
| 1760 | len = strlen(buf); | ||
| 1761 | /* check syntax and remove '<>' */ | ||
| 1762 | if (len < 2 || buf[0] != '<' || buf[len - 1] != '>') | ||
| 1763 | goto include_syntax; | ||
| 1764 | memmove(buf, buf + 1, len - 2); | ||
| 1765 | buf[len - 2] = '\0'; | ||
| 1766 | c = '>'; | ||
| 1767 | } | ||
| 1768 | } | 1761 | } |
| 1769 | 1762 | ||
| 1770 | if (s1->include_stack_ptr >= s1->include_stack + INCLUDE_STACK_SIZE) | 1763 | if (s1->include_stack_ptr >= s1->include_stack + INCLUDE_STACK_SIZE) |
| @@ -0,0 +1,13 @@ | |||
| 1 | /* This file is to test compute #include directives. It's named so | ||
| 2 | that it starts with a pre-processing number which isn't a valid | ||
| 3 | number (42test.h). Including this must work. */ | ||
| 4 | #ifndef INC42_FIRST | ||
| 5 | int have_included_42test_h; | ||
| 6 | #define INC42_FIRST | ||
| 7 | #elif !defined INC42_SECOND | ||
| 8 | #define INC42_SECOND | ||
| 9 | int have_included_42test_h_second; | ||
| 10 | #else | ||
| 11 | #define INC42_THIRD | ||
| 12 | int have_included_42test_h_third; | ||
| 13 | #endif | ||
| @@ -44,7 +44,7 @@ · 43 unmodified lines | |||
| 44 | #define TCCLIB_INC <tcclib.h> | 44 | #define TCCLIB_INC <tcclib.h> |
| 45 | #define TCCLIB_INC1 <tcclib | 45 | #define TCCLIB_INC1 <tcclib |
| 46 | #define TCCLIB_INC2 h> | 46 | #define TCCLIB_INC2 h> |
| 47 | #define TCCLIB_INC3 "tcclib" | 47 | #define TCCLIB_INC3 "tcclib.h" |
| 48 | 48 | ||
| 49 | #include TCCLIB_INC | 49 | #include TCCLIB_INC |
| 50 | 50 | ||
| @@ -52,8 +52,7 @@ · 1 unmodified line | |||
| 52 | 52 | ||
| 53 | #include TCCLIB_INC1.h> | 53 | #include TCCLIB_INC1.h> |
| 54 | 54 | ||
| 55 | /* gcc 3.2 does not accept that (bug ?) */ | 55 | #include TCCLIB_INC3 |
| 56 | //#include TCCLIB_INC3 ".h" | ||
| 57 | 56 | ||
| 58 | #include <tcclib.h> | 57 | #include <tcclib.h> |
| 59 | 58 | ||
| @@ -61,6 +60,17 @@ · 1 unmodified line | |||
| 61 | 60 | ||
| 62 | #include "tcctest.h" | 61 | #include "tcctest.h" |
| 63 | 62 | ||
| 63 | /* Test two more ways to include a file named like a pp-number */ | ||
| 64 | #define INC(name) <tests/name.h> | ||
| 65 | #define funnyname 42test.h | ||
| 66 | #define incdir tests/ | ||
| 67 | #define incname < incdir funnyname > | ||
| 68 | #define __stringify(x) #x | ||
| 69 | #define stringify(x) __stringify(x) | ||
| 70 | #include INC(42test) | ||
| 71 | #include incname | ||
| 72 | #include stringify(funnyname) | ||
| 73 | |||
| 64 | void intdiv_test(); | 74 | void intdiv_test(); |
| 65 | void string_test(); | 75 | void string_test(); |
| 66 | void expr_test(); | 76 | void expr_test(); |
| @@ -396,6 +406,11 @@ comment · 329 unmodified lines | |||
| 396 | printf("%s\n", __BASE_FILE__); | 406 | printf("%s\n", __BASE_FILE__); |
| 397 | printf("%s\n", get_file_from_header()); | 407 | printf("%s\n", get_file_from_header()); |
| 398 | printf("%s\n", __FILE__); | 408 | printf("%s\n", __FILE__); |
| 409 | |||
| 410 | /* Check that funnily named include was in fact included */ | ||
| 411 | have_included_42test_h = 1; | ||
| 412 | have_included_42test_h_second = 1; | ||
| 413 | have_included_42test_h_third = 1; | ||
| 399 | } | 414 | } |
| 400 | 415 | ||
| 401 | 416 | ||