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 | 1737 | inp(); |
| 1738 | 1738 | #endif |
| 1739 | 1739 | } else { |
| 1740 | − /* computed #include : either we have only strings or | |
| 1741 | − we have anything enclosed in '<>' */ | |
| 1740 | + int len; | |
| 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 | 1747 | next(); |
| 1743 | 1748 | buf[0] = '\0'; |
| 1744 | − if (tok == TOK_STR) { | |
| 1745 | − while (tok != TOK_LINEFEED) { | |
| 1746 | − if (tok != TOK_STR) { | |
| 1747 | − include_syntax: | |
| 1748 | − tcc_error("'#include' expects \"FILENAME\" or <FILENAME>"); | |
| 1749 | − } | |
| 1750 | − pstrcat(buf, sizeof(buf), (char *)tokc.str.data); | |
| 1751 | − next(); | |
| 1752 | − } | |
| 1753 | − c = '\"'; | |
| 1754 | − } else { | |
| 1755 | − int len; | |
| 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 | − } | |
| 1749 | + while (tok != TOK_LINEFEED) { | |
| 1750 | + pstrcat(buf, sizeof(buf), get_tok_str(tok, &tokc)); | |
| 1751 | + next(); | |
| 1752 | + } | |
| 1753 | + len = strlen(buf); | |
| 1754 | + /* check syntax and remove '<>|""' */ | |
| 1755 | + if ((len < 2 || ((buf[0] != '"' || buf[len-1] != '"') && | |
| 1756 | + (buf[0] != '<' || buf[len-1] != '>')))) | |
| 1757 | + tcc_error("'#include' expects \"FILENAME\" or <FILENAME>"); | |
| 1758 | + c = buf[len-1]; | |
| 1759 | + memmove(buf, buf + 1, len - 2); | |
| 1760 | + buf[len - 2] = '\0'; | |
| 1768 | 1761 | } |
| 1769 | 1762 | |
| 1770 | 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 | 44 | #define TCCLIB_INC <tcclib.h> |
| 45 | 45 | #define TCCLIB_INC1 <tcclib |
| 46 | 46 | #define TCCLIB_INC2 h> |
| 47 | −#define TCCLIB_INC3 "tcclib" | |
| 47 | +#define TCCLIB_INC3 "tcclib.h" | |
| 48 | 48 | |
| 49 | 49 | #include TCCLIB_INC |
| 50 | 50 | |
| @@ -52,8 +52,7 @@ · 1 unmodified line | ||
| 52 | 52 | |
| 53 | 53 | #include TCCLIB_INC1.h> |
| 54 | 54 | |
| 55 | −/* gcc 3.2 does not accept that (bug ?) */ | |
| 56 | −//#include TCCLIB_INC3 ".h" | |
| 55 | +#include TCCLIB_INC3 | |
| 57 | 56 | |
| 58 | 57 | #include <tcclib.h> |
| 59 | 58 | |
| @@ -61,6 +60,17 @@ · 1 unmodified line | ||
| 61 | 60 | |
| 62 | 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 | 74 | void intdiv_test(); |
| 65 | 75 | void string_test(); |
| 66 | 76 | void expr_test(); |
| @@ -396,6 +406,11 @@ comment · 329 unmodified lines | ||
| 396 | 406 | printf("%s\n", __BASE_FILE__); |
| 397 | 407 | printf("%s\n", get_file_from_header()); |
| 398 | 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 | |