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.
master
Michael Matz 2016-08-08 22:26:11 +02:00
parent 0381387640
commit d0d25ec7df
3 changed files with 50 additions and 29 deletions

45
tccpp.c
View File

@ -1737,34 +1737,27 @@ ST_FUNC void preprocess(int is_bof)
inp(); inp();
#endif #endif
} else { } else {
/* computed #include : either we have only strings or int len;
we have anything enclosed in '<>' */ /* 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(); next();
buf[0] = '\0'; buf[0] = '\0';
if (tok == TOK_STR) { while (tok != TOK_LINEFEED) {
while (tok != TOK_LINEFEED) { pstrcat(buf, sizeof(buf), get_tok_str(tok, &tokc));
if (tok != TOK_STR) { next();
include_syntax: }
tcc_error("'#include' expects \"FILENAME\" or <FILENAME>"); len = strlen(buf);
} /* check syntax and remove '<>|""' */
pstrcat(buf, sizeof(buf), (char *)tokc.str.data); if ((len < 2 || ((buf[0] != '"' || buf[len-1] != '"') &&
next(); (buf[0] != '<' || buf[len-1] != '>'))))
} tcc_error("'#include' expects \"FILENAME\" or <FILENAME>");
c = '\"'; c = buf[len-1];
} else { memmove(buf, buf + 1, len - 2);
int len; buf[len - 2] = '\0';
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 = '>';
}
} }
if (s1->include_stack_ptr >= s1->include_stack + INCLUDE_STACK_SIZE) if (s1->include_stack_ptr >= s1->include_stack + INCLUDE_STACK_SIZE)

13
tests/42test.h 100644
View File

@ -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

View File

@ -44,7 +44,7 @@
#define TCCLIB_INC <tcclib.h> #define TCCLIB_INC <tcclib.h>
#define TCCLIB_INC1 <tcclib #define TCCLIB_INC1 <tcclib
#define TCCLIB_INC2 h> #define TCCLIB_INC2 h>
#define TCCLIB_INC3 "tcclib" #define TCCLIB_INC3 "tcclib.h"
#include TCCLIB_INC #include TCCLIB_INC
@ -52,8 +52,7 @@
#include TCCLIB_INC1.h> #include TCCLIB_INC1.h>
/* gcc 3.2 does not accept that (bug ?) */ #include TCCLIB_INC3
//#include TCCLIB_INC3 ".h"
#include <tcclib.h> #include <tcclib.h>
@ -61,6 +60,17 @@
#include "tcctest.h" #include "tcctest.h"
/* Test two more ways to include a file named like a pp-number */
#define INC(name) <tests/name.h>
#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 intdiv_test();
void string_test(); void string_test();
void expr_test(); void expr_test();
@ -396,6 +406,11 @@ comment
printf("%s\n", __BASE_FILE__); printf("%s\n", __BASE_FILE__);
printf("%s\n", get_file_from_header()); printf("%s\n", get_file_from_header());
printf("%s\n", __FILE__); 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;
} }