tccpp : get rid of 'ch'
- also simplify parse(_line)_comment() and parse_pp_string() - fixes a continuation problem in strings (see tcctest.c) - no differences in performance could be observed 161 insertions(+), 246 deletions(-), less 85 lines
This commit is contained in:
parent
85c32ddd0b
commit
20a1ebf854
6 changed files with 161 additions and 246 deletions
3
tcc.h
3
tcc.h
|
@ -77,7 +77,6 @@ extern long double strtold (const char *__nptr, char **__endptr);
|
||||||
# define LIBTCCAPI __declspec(dllexport)
|
# define LIBTCCAPI __declspec(dllexport)
|
||||||
# define PUB_FUNC LIBTCCAPI
|
# define PUB_FUNC LIBTCCAPI
|
||||||
# endif
|
# endif
|
||||||
# define inp next_inp /* inp is an intrinsic on msvc/mingw */
|
|
||||||
# ifdef _MSC_VER
|
# ifdef _MSC_VER
|
||||||
# pragma warning (disable : 4244) // conversion from 'uint64_t' to 'int', possible loss of data
|
# pragma warning (disable : 4244) // conversion from 'uint64_t' to 'int', possible loss of data
|
||||||
# pragma warning (disable : 4267) // conversion from 'size_t' to 'int', possible loss of data
|
# pragma warning (disable : 4267) // conversion from 'size_t' to 'int', possible loss of data
|
||||||
|
@ -1303,7 +1302,7 @@ ST_FUNC char *tcc_load_text(int fd);
|
||||||
/* ------------ tccpp.c ------------ */
|
/* ------------ tccpp.c ------------ */
|
||||||
|
|
||||||
ST_DATA struct BufferedFile *file;
|
ST_DATA struct BufferedFile *file;
|
||||||
ST_DATA int ch, tok;
|
ST_DATA int tok;
|
||||||
ST_DATA CValue tokc;
|
ST_DATA CValue tokc;
|
||||||
ST_DATA const int *macro_ptr;
|
ST_DATA const int *macro_ptr;
|
||||||
ST_DATA int parse_flags;
|
ST_DATA int parse_flags;
|
||||||
|
|
2
tccgen.c
2
tccgen.c
|
@ -7636,7 +7636,7 @@ static void decl_initializer(init_params *p, CType *type, unsigned long c, int f
|
||||||
|
|
||||||
decl_design_flex(p, s, len);
|
decl_design_flex(p, s, len);
|
||||||
if (!(flags & DIF_SIZE_ONLY)) {
|
if (!(flags & DIF_SIZE_ONLY)) {
|
||||||
int nb = n;
|
int nb = n, ch;
|
||||||
if (len < nb)
|
if (len < nb)
|
||||||
nb = len;
|
nb = len;
|
||||||
if (len > nb)
|
if (len > nb)
|
||||||
|
|
389
tccpp.c
389
tccpp.c
|
@ -31,7 +31,7 @@ ST_DATA int tok_flags;
|
||||||
ST_DATA int parse_flags;
|
ST_DATA int parse_flags;
|
||||||
|
|
||||||
ST_DATA struct BufferedFile *file;
|
ST_DATA struct BufferedFile *file;
|
||||||
ST_DATA int ch, tok;
|
ST_DATA int tok;
|
||||||
ST_DATA CValue tokc;
|
ST_DATA CValue tokc;
|
||||||
ST_DATA const int *macro_ptr;
|
ST_DATA const int *macro_ptr;
|
||||||
ST_DATA CString tokcstr; /* current parsed string, if any */
|
ST_DATA CString tokcstr; /* current parsed string, if any */
|
||||||
|
@ -639,6 +639,17 @@ ST_FUNC const char *get_tok_str(int v, CValue *cv)
|
||||||
return cstr_buf.data;
|
return cstr_buf.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int check_space(int t, int *spc)
|
||||||
|
{
|
||||||
|
if (t < 256 && (isidnum_table[t - CH_EOF] & IS_SPC)) {
|
||||||
|
if (*spc)
|
||||||
|
return 1;
|
||||||
|
*spc = 1;
|
||||||
|
} else
|
||||||
|
*spc = 0;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* return the current character, handling end of block if necessary
|
/* return the current character, handling end of block if necessary
|
||||||
(but not stray) */
|
(but not stray) */
|
||||||
static int handle_eob(void)
|
static int handle_eob(void)
|
||||||
|
@ -674,132 +685,102 @@ static int handle_eob(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* read next char from current input file and handle end of input buffer */
|
/* read next char from current input file and handle end of input buffer */
|
||||||
static inline void inp(void)
|
static int next_c(void)
|
||||||
{
|
{
|
||||||
ch = *(++(file->buf_ptr));
|
int ch = *++file->buf_ptr;
|
||||||
/* end of buffer/file handling */
|
/* end of buffer/file handling */
|
||||||
if (ch == CH_EOB)
|
if (ch == CH_EOB && file->buf_ptr >= file->buf_end)
|
||||||
ch = handle_eob();
|
ch = handle_eob();
|
||||||
|
return ch;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* handle '\[\r]\n' */
|
/* input with '\[\r]\n' handling. */
|
||||||
static int handle_stray_noerror(void)
|
static int handle_stray_noerror(int err)
|
||||||
{
|
{
|
||||||
while (ch == '\\') {
|
int ch;
|
||||||
inp();
|
while ((ch = next_c()) == '\\') {
|
||||||
|
ch = next_c();
|
||||||
if (ch == '\n') {
|
if (ch == '\n') {
|
||||||
|
newl:
|
||||||
file->line_num++;
|
file->line_num++;
|
||||||
inp();
|
|
||||||
} else if (ch == '\r') {
|
|
||||||
inp();
|
|
||||||
if (ch != '\n')
|
|
||||||
goto fail;
|
|
||||||
file->line_num++;
|
|
||||||
inp();
|
|
||||||
} else {
|
} else {
|
||||||
fail:
|
if (ch == '\r') {
|
||||||
return 1;
|
ch = next_c();
|
||||||
|
if (ch == '\n')
|
||||||
|
goto newl;
|
||||||
|
*--file->buf_ptr = '\r';
|
||||||
|
}
|
||||||
|
if (err)
|
||||||
|
tcc_error("stray '\\' in program");
|
||||||
|
/* may take advantage of 'BufferedFile.unget[4}' */
|
||||||
|
return *--file->buf_ptr = '\\';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return ch;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_stray(void)
|
#define ninp() handle_stray_noerror(0)
|
||||||
|
|
||||||
|
/* handle '\\' in strings, comments and skipped regions */
|
||||||
|
static int handle_bs(uint8_t **p)
|
||||||
{
|
{
|
||||||
if (handle_stray_noerror())
|
int c;
|
||||||
tcc_error("stray '\\' in program");
|
file->buf_ptr = *p - 1;
|
||||||
|
c = ninp();
|
||||||
|
*p = file->buf_ptr;
|
||||||
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* skip the stray and handle the \\n case. Output an error if
|
/* skip the stray and handle the \\n case. Output an error if
|
||||||
incorrect char after the stray */
|
incorrect char after the stray */
|
||||||
static int handle_stray1(uint8_t *p)
|
static int handle_stray(uint8_t **p)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
|
file->buf_ptr = *p - 1;
|
||||||
file->buf_ptr = p;
|
c = handle_stray_noerror(!(parse_flags & PARSE_FLAG_ACCEPT_STRAYS));
|
||||||
if (p >= file->buf_end) {
|
*p = file->buf_ptr;
|
||||||
c = handle_eob();
|
|
||||||
if (c != '\\')
|
|
||||||
return c;
|
|
||||||
p = file->buf_ptr;
|
|
||||||
}
|
|
||||||
ch = *p;
|
|
||||||
if (handle_stray_noerror()) {
|
|
||||||
if (!(parse_flags & PARSE_FLAG_ACCEPT_STRAYS))
|
|
||||||
tcc_error("stray '\\' in program");
|
|
||||||
*--file->buf_ptr = '\\';
|
|
||||||
}
|
|
||||||
p = file->buf_ptr;
|
|
||||||
c = *p;
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* handle just the EOB case, but not stray */
|
|
||||||
#define PEEKC_EOB(c, p)\
|
|
||||||
{\
|
|
||||||
p++;\
|
|
||||||
c = *p;\
|
|
||||||
if (c == '\\') {\
|
|
||||||
file->buf_ptr = p;\
|
|
||||||
c = handle_eob();\
|
|
||||||
p = file->buf_ptr;\
|
|
||||||
}\
|
|
||||||
}
|
|
||||||
|
|
||||||
/* handle the complicated stray case */
|
/* handle the complicated stray case */
|
||||||
#define PEEKC(c, p)\
|
#define PEEKC(c, p)\
|
||||||
{\
|
{\
|
||||||
p++;\
|
c = *++p;\
|
||||||
c = *p;\
|
if (c == '\\')\
|
||||||
if (c == '\\') {\
|
c = handle_stray(&p); \
|
||||||
c = handle_stray1(p);\
|
|
||||||
p = file->buf_ptr;\
|
|
||||||
}\
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* input with '\[\r]\n' handling. Note that this function cannot
|
static int skip_spaces(void)
|
||||||
handle other characters after '\', so you cannot call it inside
|
|
||||||
strings or comments */
|
|
||||||
static void minp(void)
|
|
||||||
{
|
{
|
||||||
inp();
|
int ch;
|
||||||
if (ch == '\\')
|
--file->buf_ptr;
|
||||||
handle_stray();
|
do {
|
||||||
|
ch = ninp();
|
||||||
|
} while (isidnum_table[ch - CH_EOF] & IS_SPC);
|
||||||
|
return ch;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* single line C++ comments */
|
/* single line C++ comments */
|
||||||
static uint8_t *parse_line_comment(uint8_t *p)
|
static uint8_t *parse_line_comment(uint8_t *p)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
p++;
|
|
||||||
for(;;) {
|
for(;;) {
|
||||||
c = *p;
|
for (;;) {
|
||||||
|
c = *++p;
|
||||||
redo:
|
redo:
|
||||||
if (c == '\n' || c == CH_EOF) {
|
if (c == '\n' || c == '\\')
|
||||||
break;
|
break;
|
||||||
} else if (c == '\\') {
|
c = *++p;
|
||||||
file->buf_ptr = p;
|
if (c == '\n' || c == '\\')
|
||||||
c = handle_eob();
|
break;
|
||||||
p = file->buf_ptr;
|
|
||||||
if (c == '\\') {
|
|
||||||
PEEKC_EOB(c, p);
|
|
||||||
if (c == '\n') {
|
|
||||||
file->line_num++;
|
|
||||||
PEEKC_EOB(c, p);
|
|
||||||
} else if (c == '\r') {
|
|
||||||
PEEKC_EOB(c, p);
|
|
||||||
if (c == '\n') {
|
|
||||||
file->line_num++;
|
|
||||||
PEEKC_EOB(c, p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
goto redo;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
p++;
|
|
||||||
}
|
}
|
||||||
|
if (c == '\n')
|
||||||
|
break;
|
||||||
|
c = handle_bs(&p);
|
||||||
|
if (c == CH_EOF)
|
||||||
|
break;
|
||||||
|
if (c != '\\')
|
||||||
|
goto redo;
|
||||||
}
|
}
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
@ -808,144 +789,69 @@ static uint8_t *parse_line_comment(uint8_t *p)
|
||||||
static uint8_t *parse_comment(uint8_t *p)
|
static uint8_t *parse_comment(uint8_t *p)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
p++;
|
|
||||||
for(;;) {
|
for(;;) {
|
||||||
/* fast skip loop */
|
/* fast skip loop */
|
||||||
for(;;) {
|
for(;;) {
|
||||||
c = *p;
|
c = *++p;
|
||||||
|
redo:
|
||||||
if (c == '\n' || c == '*' || c == '\\')
|
if (c == '\n' || c == '*' || c == '\\')
|
||||||
break;
|
break;
|
||||||
p++;
|
c = *++p;
|
||||||
c = *p;
|
|
||||||
if (c == '\n' || c == '*' || c == '\\')
|
if (c == '\n' || c == '*' || c == '\\')
|
||||||
break;
|
break;
|
||||||
p++;
|
|
||||||
}
|
}
|
||||||
/* now we can handle all the cases */
|
/* now we can handle all the cases */
|
||||||
if (c == '\n') {
|
if (c == '\n') {
|
||||||
file->line_num++;
|
file->line_num++;
|
||||||
p++;
|
|
||||||
} else if (c == '*') {
|
} else if (c == '*') {
|
||||||
p++;
|
do {
|
||||||
for(;;) {
|
c = *++p;
|
||||||
c = *p;
|
} while (c == '*');
|
||||||
if (c == '*') {
|
if (c == '\\')
|
||||||
p++;
|
c = handle_bs(&p);
|
||||||
} else if (c == '/') {
|
if (c == '/')
|
||||||
goto end_of_comment;
|
break;
|
||||||
} else if (c == '\\') {
|
goto check_eof;
|
||||||
file->buf_ptr = p;
|
|
||||||
c = handle_eob();
|
|
||||||
p = file->buf_ptr;
|
|
||||||
if (c == CH_EOF)
|
|
||||||
tcc_error("unexpected end of file in comment");
|
|
||||||
if (c == '\\') {
|
|
||||||
/* skip '\[\r]\n', otherwise just skip the stray */
|
|
||||||
while (c == '\\') {
|
|
||||||
PEEKC_EOB(c, p);
|
|
||||||
if (c == '\n') {
|
|
||||||
file->line_num++;
|
|
||||||
PEEKC_EOB(c, p);
|
|
||||||
} else if (c == '\r') {
|
|
||||||
PEEKC_EOB(c, p);
|
|
||||||
if (c == '\n') {
|
|
||||||
file->line_num++;
|
|
||||||
PEEKC_EOB(c, p);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
goto after_star;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
after_star: ;
|
|
||||||
} else {
|
} else {
|
||||||
/* stray, eob or eof */
|
c = handle_bs(&p);
|
||||||
file->buf_ptr = p;
|
check_eof:
|
||||||
c = handle_eob();
|
if (c == CH_EOF)
|
||||||
p = file->buf_ptr;
|
|
||||||
if (c == CH_EOF) {
|
|
||||||
tcc_error("unexpected end of file in comment");
|
tcc_error("unexpected end of file in comment");
|
||||||
} else if (c == '\\') {
|
if (c != '\\')
|
||||||
p++;
|
goto redo;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
end_of_comment:
|
return p + 1;
|
||||||
p++;
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
ST_FUNC int set_idnum(int c, int val)
|
|
||||||
{
|
|
||||||
int prev = isidnum_table[c - CH_EOF];
|
|
||||||
isidnum_table[c - CH_EOF] = val;
|
|
||||||
return prev;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define cinp minp
|
|
||||||
|
|
||||||
static inline void skip_spaces(void)
|
|
||||||
{
|
|
||||||
ch = file->buf_ptr[0];
|
|
||||||
while (isidnum_table[ch - CH_EOF] & IS_SPC)
|
|
||||||
cinp();
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int check_space(int t, int *spc)
|
|
||||||
{
|
|
||||||
if (t < 256 && (isidnum_table[t - CH_EOF] & IS_SPC)) {
|
|
||||||
if (*spc)
|
|
||||||
return 1;
|
|
||||||
*spc = 1;
|
|
||||||
} else
|
|
||||||
*spc = 0;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* parse a string without interpreting escapes */
|
/* parse a string without interpreting escapes */
|
||||||
static uint8_t *parse_pp_string(uint8_t *p,
|
static uint8_t *parse_pp_string(uint8_t *p, int sep, CString *str)
|
||||||
int sep, CString *str)
|
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
p++;
|
|
||||||
for(;;) {
|
for(;;) {
|
||||||
c = *p;
|
c = *++p;
|
||||||
|
redo:
|
||||||
if (c == sep) {
|
if (c == sep) {
|
||||||
break;
|
break;
|
||||||
} else if (c == '\\') {
|
} else if (c == '\\') {
|
||||||
file->buf_ptr = p;
|
c = handle_bs(&p);
|
||||||
c = handle_eob();
|
|
||||||
p = file->buf_ptr;
|
|
||||||
if (c == CH_EOF) {
|
if (c == CH_EOF) {
|
||||||
unterminated_string:
|
unterminated_string:
|
||||||
/* XXX: indicate line number of start of string */
|
/* XXX: indicate line number of start of string */
|
||||||
tcc_error("missing terminating %c character", sep);
|
tcc_error("missing terminating %c character", sep);
|
||||||
} else if (c == '\\') {
|
} else if (c == '\\') {
|
||||||
/* escape : just skip \[\r]\n */
|
if (str)
|
||||||
PEEKC_EOB(c, p);
|
cstr_ccat(str, c);
|
||||||
if (c == '\n') {
|
c = *++p;
|
||||||
file->line_num++;
|
/* add char after '\\' unconditionally */
|
||||||
p++;
|
if (c == '\\') {
|
||||||
} else if (c == '\r') {
|
c = handle_bs(&p);
|
||||||
PEEKC_EOB(c, p);
|
if (c == CH_EOF)
|
||||||
if (c != '\n')
|
goto unterminated_string;
|
||||||
expect("'\n' after '\r'");
|
|
||||||
file->line_num++;
|
|
||||||
p++;
|
|
||||||
} else if (c == CH_EOF) {
|
|
||||||
goto unterminated_string;
|
|
||||||
} else {
|
|
||||||
if (str) {
|
|
||||||
cstr_ccat(str, '\\');
|
|
||||||
cstr_ccat(str, c);
|
|
||||||
}
|
|
||||||
p++;
|
|
||||||
}
|
}
|
||||||
|
goto add_char;
|
||||||
|
} else {
|
||||||
|
goto redo;
|
||||||
}
|
}
|
||||||
} else if (c == '\n') {
|
} else if (c == '\n') {
|
||||||
add_lf:
|
add_lf:
|
||||||
|
@ -955,22 +861,24 @@ static uint8_t *parse_pp_string(uint8_t *p,
|
||||||
} else if (str) { /* not skipping */
|
} else if (str) { /* not skipping */
|
||||||
goto unterminated_string;
|
goto unterminated_string;
|
||||||
} else {
|
} else {
|
||||||
tcc_warning("missing terminating %c character", sep);
|
//tcc_warning("missing terminating %c character", sep);
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
} else if (c == '\r') {
|
} else if (c == '\r') {
|
||||||
PEEKC_EOB(c, p);
|
c = *++p;
|
||||||
if (c != '\n') {
|
if (c == '\\')
|
||||||
if (str)
|
c = handle_bs(&p);
|
||||||
cstr_ccat(str, '\r');
|
if (c == '\n')
|
||||||
} else {
|
|
||||||
goto add_lf;
|
goto add_lf;
|
||||||
}
|
if (c == CH_EOF)
|
||||||
|
goto unterminated_string;
|
||||||
|
if (str)
|
||||||
|
cstr_ccat(str, '\r');
|
||||||
|
goto redo;
|
||||||
} else {
|
} else {
|
||||||
add_char:
|
add_char:
|
||||||
if (str)
|
if (str)
|
||||||
cstr_ccat(str, c);
|
cstr_ccat(str, c);
|
||||||
p++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
p++;
|
p++;
|
||||||
|
@ -1005,15 +913,11 @@ redo_start:
|
||||||
p++;
|
p++;
|
||||||
goto redo_start;
|
goto redo_start;
|
||||||
case '\\':
|
case '\\':
|
||||||
file->buf_ptr = p;
|
c = handle_bs(&p);
|
||||||
c = handle_eob();
|
if (c == CH_EOF)
|
||||||
if (c == CH_EOF) {
|
|
||||||
expect("#endif");
|
expect("#endif");
|
||||||
} else if (c == '\\') {
|
if (c == '\\')
|
||||||
ch = file->buf_ptr[0];
|
++p;
|
||||||
handle_stray_noerror();
|
|
||||||
}
|
|
||||||
p = file->buf_ptr;
|
|
||||||
goto redo_no_start;
|
goto redo_no_start;
|
||||||
/* skip strings */
|
/* skip strings */
|
||||||
case '\"':
|
case '\"':
|
||||||
|
@ -1027,13 +931,11 @@ redo_start:
|
||||||
case '/':
|
case '/':
|
||||||
if (in_warn_or_error)
|
if (in_warn_or_error)
|
||||||
goto _default;
|
goto _default;
|
||||||
file->buf_ptr = p;
|
++p;
|
||||||
ch = *p;
|
c = handle_bs(&p);
|
||||||
minp();
|
if (c == '*') {
|
||||||
p = file->buf_ptr;
|
|
||||||
if (ch == '*') {
|
|
||||||
p = parse_comment(p);
|
p = parse_comment(p);
|
||||||
} else if (ch == '/') {
|
} else if (c == '/') {
|
||||||
p = parse_line_comment(p);
|
p = parse_line_comment(p);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1507,7 +1409,7 @@ static int parse_include(TCCState *s1, int do_next, int test)
|
||||||
CachedInclude *e;
|
CachedInclude *e;
|
||||||
|
|
||||||
cstr_new(&cs);
|
cstr_new(&cs);
|
||||||
skip_spaces(), c = ch;
|
c = skip_spaces();
|
||||||
if (c == '<' || c == '\"') {
|
if (c == '<' || c == '\"') {
|
||||||
file->buf_ptr = parse_pp_string(file->buf_ptr, c == '<' ? '>' : c, &cs);
|
file->buf_ptr = parse_pp_string(file->buf_ptr, c == '<' ? '>' : c, &cs);
|
||||||
next_nomacro();
|
next_nomacro();
|
||||||
|
@ -2072,20 +1974,15 @@ ST_FUNC void preprocess(int is_bof)
|
||||||
break;
|
break;
|
||||||
case TOK_ERROR:
|
case TOK_ERROR:
|
||||||
case TOK_WARNING:
|
case TOK_WARNING:
|
||||||
c = tok;
|
|
||||||
skip_spaces();
|
|
||||||
q = buf;
|
q = buf;
|
||||||
while (ch != '\n' && ch != CH_EOF) {
|
c = skip_spaces();
|
||||||
|
while (c != '\n' && c != CH_EOF) {
|
||||||
if ((q - buf) < sizeof(buf) - 1)
|
if ((q - buf) < sizeof(buf) - 1)
|
||||||
*q++ = ch;
|
*q++ = c;
|
||||||
if (ch == '\\') {
|
c = ninp();
|
||||||
if (handle_stray_noerror() == 0)
|
|
||||||
--q;
|
|
||||||
} else
|
|
||||||
inp();
|
|
||||||
}
|
}
|
||||||
*q = '\0';
|
*q = '\0';
|
||||||
if (c == TOK_ERROR)
|
if (tok == TOK_ERROR)
|
||||||
tcc_error("#error %s", buf);
|
tcc_error("#error %s", buf);
|
||||||
else
|
else
|
||||||
tcc_warning("#warning %s", buf);
|
tcc_warning("#warning %s", buf);
|
||||||
|
@ -2697,13 +2594,10 @@ static inline void next_nomacro1(void)
|
||||||
goto redo_no_start;
|
goto redo_no_start;
|
||||||
case '\\':
|
case '\\':
|
||||||
/* first look if it is in fact an end of buffer */
|
/* first look if it is in fact an end of buffer */
|
||||||
c = handle_stray1(p);
|
c = handle_stray(&p);
|
||||||
p = file->buf_ptr;
|
|
||||||
if (c == '\\')
|
if (c == '\\')
|
||||||
goto parse_simple;
|
goto parse_simple;
|
||||||
if (c != CH_EOF)
|
if (c == CH_EOF) {
|
||||||
goto redo_no_start;
|
|
||||||
{
|
|
||||||
TCCState *s1 = tcc_state;
|
TCCState *s1 = tcc_state;
|
||||||
if ((parse_flags & PARSE_FLAG_LINEFEED)
|
if ((parse_flags & PARSE_FLAG_LINEFEED)
|
||||||
&& !(tok_flags & TOK_FLAG_EOF)) {
|
&& !(tok_flags & TOK_FLAG_EOF)) {
|
||||||
|
@ -2742,6 +2636,8 @@ static inline void next_nomacro1(void)
|
||||||
tok_flags = TOK_FLAG_BOF|TOK_FLAG_BOL;
|
tok_flags = TOK_FLAG_BOF|TOK_FLAG_BOL;
|
||||||
goto redo_no_start;
|
goto redo_no_start;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
goto redo_no_start;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -3326,30 +3222,30 @@ static int next_argstream(Sym **nested_list, TokenString *ws_str)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ch = handle_eob();
|
uint8_t *p = file->buf_ptr;
|
||||||
|
int ch = handle_bs(&p);
|
||||||
if (ws_str) {
|
if (ws_str) {
|
||||||
while (is_space(ch) || ch == '\n' || ch == '/') {
|
while (is_space(ch) || ch == '\n' || ch == '/') {
|
||||||
if (ch == '/') {
|
if (ch == '/') {
|
||||||
int c;
|
int c;
|
||||||
uint8_t *p = file->buf_ptr;
|
|
||||||
PEEKC(c, p);
|
PEEKC(c, p);
|
||||||
if (c == '*') {
|
if (c == '*') {
|
||||||
p = parse_comment(p);
|
p = parse_comment(p) - 1;
|
||||||
file->buf_ptr = p - 1;
|
|
||||||
} else if (c == '/') {
|
} else if (c == '/') {
|
||||||
p = parse_line_comment(p);
|
p = parse_line_comment(p) - 1;
|
||||||
file->buf_ptr = p - 1;
|
} else {
|
||||||
} else
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
ch = ' ';
|
ch = ' ';
|
||||||
}
|
}
|
||||||
if (ch == '\n')
|
if (ch == '\n')
|
||||||
file->line_num++;
|
file->line_num++;
|
||||||
if (!(ch == '\f' || ch == '\v' || ch == '\r'))
|
if (!(ch == '\f' || ch == '\v' || ch == '\r'))
|
||||||
tok_str_add(ws_str, ch);
|
tok_str_add(ws_str, ch);
|
||||||
cinp();
|
PEEKC(ch, p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
file->buf_ptr = p;
|
||||||
t = ch;
|
t = ch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3838,6 +3734,13 @@ ST_FUNC void preprocess_end(TCCState *s1)
|
||||||
tccpp_delete(s1);
|
tccpp_delete(s1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ST_FUNC int set_idnum(int c, int val)
|
||||||
|
{
|
||||||
|
int prev = isidnum_table[c - CH_EOF];
|
||||||
|
isidnum_table[c - CH_EOF] = val;
|
||||||
|
return prev;
|
||||||
|
}
|
||||||
|
|
||||||
ST_FUNC void tccpp_new(TCCState *s)
|
ST_FUNC void tccpp_new(TCCState *s)
|
||||||
{
|
{
|
||||||
int i, c;
|
int i, c;
|
||||||
|
|
|
@ -4315,6 +4315,12 @@ ntf("min=%d\n", 4);
|
||||||
#line 2222 "test"
|
#line 2222 "test"
|
||||||
printf("__LINE__=%d __FILE__=%s\n", __LINE__, __FILE__);
|
printf("__LINE__=%d __FILE__=%s\n", __LINE__, __FILE__);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
printf("\\
|
||||||
|
"12\\
|
||||||
|
063\\
|
||||||
|
n 456\"\n");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define RUN(test) puts("---- " #test " ----"), test(), puts("")
|
#define RUN(test) puts("---- " #test " ----"), test(), puts("")
|
||||||
|
|
|
@ -448,4 +448,8 @@ int main() {
|
||||||
char *str = "\Uffffffff";
|
char *str = "\Uffffffff";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#elif defined test_error_string
|
||||||
|
#error \123\\
|
||||||
|
456
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -219,3 +219,6 @@ arg[1] = "Y"
|
||||||
|
|
||||||
[test_illegal_unicode]
|
[test_illegal_unicode]
|
||||||
60_errors_and_warnings.c:448: error: 0xffffffff is not a valid universal character
|
60_errors_and_warnings.c:448: error: 0xffffffff is not a valid universal character
|
||||||
|
|
||||||
|
[test_error_string]
|
||||||
|
60_errors_and_warnings.c:453: error: #error \123\456
|
||||||
|
|
Loading…
Add table
Reference in a new issue