From d0d25ec7df636deaf650d31ae3b50e60659f54dd Mon Sep 17 00:00:00 2001 From: Michael Matz Date: Mon, 8 Aug 2016 22:26:11 +0200 Subject: [PATCH] tccpp: Allow computed include like 42.h 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. --- tccpp.c | 45 +++++++++++++++++++-------------------------- tests/42test.h | 13 +++++++++++++ tests/tcctest.c | 21 ++++++++++++++++++--- 3 files changed, 50 insertions(+), 29 deletions(-) create mode 100644 tests/42test.h diff --git a/tccpp.c b/tccpp.c index 1838a3a..5aaea1a 100644 --- a/tccpp.c +++ b/tccpp.c @@ -1737,34 +1737,27 @@ ST_FUNC void preprocess(int is_bof) inp(); #endif } else { - /* computed #include : either we have only strings or - we have anything enclosed in '<>' */ + int len; + /* computed #include : concatenate everything up to linefeed, + the result must be one of the two accepted forms. + Don't convert pp-tokens to tokens here. */ + parse_flags = (PARSE_FLAG_PREPROCESS + | PARSE_FLAG_LINEFEED + | (parse_flags & PARSE_FLAG_ASM_FILE)); next(); buf[0] = '\0'; - if (tok == TOK_STR) { - while (tok != TOK_LINEFEED) { - if (tok != TOK_STR) { - include_syntax: - tcc_error("'#include' expects \"FILENAME\" or "); - } - pstrcat(buf, sizeof(buf), (char *)tokc.str.data); - next(); - } - c = '\"'; - } else { - int len; - while (tok != TOK_LINEFEED) { - pstrcat(buf, sizeof(buf), get_tok_str(tok, &tokc)); - next(); - } - len = strlen(buf); - /* check syntax and remove '<>' */ - if (len < 2 || buf[0] != '<' || buf[len - 1] != '>') - goto include_syntax; - memmove(buf, buf + 1, len - 2); - buf[len - 2] = '\0'; - c = '>'; - } + while (tok != TOK_LINEFEED) { + pstrcat(buf, sizeof(buf), get_tok_str(tok, &tokc)); + next(); + } + len = strlen(buf); + /* check syntax and remove '<>|""' */ + if ((len < 2 || ((buf[0] != '"' || buf[len-1] != '"') && + (buf[0] != '<' || buf[len-1] != '>')))) + tcc_error("'#include' expects \"FILENAME\" or "); + c = buf[len-1]; + memmove(buf, buf + 1, len - 2); + buf[len - 2] = '\0'; } if (s1->include_stack_ptr >= s1->include_stack + INCLUDE_STACK_SIZE) diff --git a/tests/42test.h b/tests/42test.h new file mode 100644 index 0000000..5db7d1c --- /dev/null +++ b/tests/42test.h @@ -0,0 +1,13 @@ +/* This file is to test compute #include directives. It's named so + that it starts with a pre-processing number which isn't a valid + number (42test.h). Including this must work. */ +#ifndef INC42_FIRST +int have_included_42test_h; +#define INC42_FIRST +#elif !defined INC42_SECOND +#define INC42_SECOND +int have_included_42test_h_second; +#else +#define INC42_THIRD +int have_included_42test_h_third; +#endif diff --git a/tests/tcctest.c b/tests/tcctest.c index 52dbfaf..2abbacd 100644 --- a/tests/tcctest.c +++ b/tests/tcctest.c @@ -44,7 +44,7 @@ #define TCCLIB_INC #define TCCLIB_INC1 -#define TCCLIB_INC3 "tcclib" +#define TCCLIB_INC3 "tcclib.h" #include TCCLIB_INC @@ -52,8 +52,7 @@ #include TCCLIB_INC1.h> -/* gcc 3.2 does not accept that (bug ?) */ -//#include TCCLIB_INC3 ".h" +#include TCCLIB_INC3 #include @@ -61,6 +60,17 @@ #include "tcctest.h" +/* Test two more ways to include a file named like a pp-number */ +#define INC(name) +#define funnyname 42test.h +#define incdir tests/ +#define incname < incdir funnyname > +#define __stringify(x) #x +#define stringify(x) __stringify(x) +#include INC(42test) +#include incname +#include stringify(funnyname) + void intdiv_test(); void string_test(); void expr_test(); @@ -396,6 +406,11 @@ comment printf("%s\n", __BASE_FILE__); printf("%s\n", get_file_from_header()); printf("%s\n", __FILE__); + + /* Check that funnily named include was in fact included */ + have_included_42test_h = 1; + have_included_42test_h_second = 1; + have_included_42test_h_third = 1; }