added correct ## handling : added TOK_PPNUM token
This commit is contained in:
parent
973eb60e01
commit
c0180c4e5f
1 changed files with 163 additions and 89 deletions
250
tcc.c
250
tcc.c
|
@ -463,6 +463,7 @@ struct TCCState {
|
||||||
#define TOK_ARROW 0xcb
|
#define TOK_ARROW 0xcb
|
||||||
#define TOK_DOTS 0xcc /* three dots */
|
#define TOK_DOTS 0xcc /* three dots */
|
||||||
#define TOK_SHR 0xcd /* unsigned shift right */
|
#define TOK_SHR 0xcd /* unsigned shift right */
|
||||||
|
#define TOK_PPNUM 0xce /* preprocessor number */
|
||||||
|
|
||||||
#define TOK_SHL 0x01 /* shift left */
|
#define TOK_SHL 0x01 /* shift left */
|
||||||
#define TOK_SAR 0x02 /* signed shift right */
|
#define TOK_SAR 0x02 /* signed shift right */
|
||||||
|
@ -1029,10 +1030,10 @@ static inline int isoct(int c)
|
||||||
|
|
||||||
static inline int toup(int c)
|
static inline int toup(int c)
|
||||||
{
|
{
|
||||||
if (ch >= 'a' && ch <= 'z')
|
if (c >= 'a' && c <= 'z')
|
||||||
return ch - 'a' + 'A';
|
return c - 'a' + 'A';
|
||||||
else
|
else
|
||||||
return ch;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void strcat_vprintf(char *buf, int buf_size, const char *fmt, va_list ap)
|
static void strcat_vprintf(char *buf, int buf_size, const char *fmt, va_list ap)
|
||||||
|
@ -1081,7 +1082,8 @@ void error1(TCCState *s1, int is_warning, const char *fmt, va_list ap)
|
||||||
} else {
|
} else {
|
||||||
s1->error_func(s1->error_opaque, buf);
|
s1->error_func(s1->error_opaque, buf);
|
||||||
}
|
}
|
||||||
s1->nb_errors++;
|
if (!is_warning)
|
||||||
|
s1->nb_errors++;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef LIBTCC
|
#ifdef LIBTCC
|
||||||
|
@ -1314,6 +1316,12 @@ char *get_tok_str(int v, CValue *cv)
|
||||||
cstr_ccat(&cstr_buf, '\'');
|
cstr_ccat(&cstr_buf, '\'');
|
||||||
cstr_ccat(&cstr_buf, '\0');
|
cstr_ccat(&cstr_buf, '\0');
|
||||||
break;
|
break;
|
||||||
|
case TOK_PPNUM:
|
||||||
|
cstr = cv->cstr;
|
||||||
|
len = cstr->size - 1;
|
||||||
|
for(i=0;i<len;i++)
|
||||||
|
add_char(&cstr_buf, ((unsigned char *)cstr->data)[i]);
|
||||||
|
break;
|
||||||
case TOK_STR:
|
case TOK_STR:
|
||||||
case TOK_LSTR:
|
case TOK_LSTR:
|
||||||
cstr = cv->cstr;
|
cstr = cv->cstr;
|
||||||
|
@ -1724,6 +1732,7 @@ static inline int tok_ext_size(int t)
|
||||||
case TOK_LSTR:
|
case TOK_LSTR:
|
||||||
case TOK_CFLOAT:
|
case TOK_CFLOAT:
|
||||||
case TOK_LINENUM:
|
case TOK_LINENUM:
|
||||||
|
case TOK_PPNUM:
|
||||||
return 1;
|
return 1;
|
||||||
case TOK_CDOUBLE:
|
case TOK_CDOUBLE:
|
||||||
case TOK_CLLONG:
|
case TOK_CLLONG:
|
||||||
|
@ -1756,7 +1765,7 @@ static void tok_str_free(int *str)
|
||||||
t = *p++;
|
t = *p++;
|
||||||
if (t == 0)
|
if (t == 0)
|
||||||
break;
|
break;
|
||||||
if (t == TOK_STR || t == TOK_LSTR) {
|
if (t == TOK_STR || t == TOK_LSTR || t == TOK_PPNUM) {
|
||||||
/* XXX: use a macro to be portable on 64 bit ? */
|
/* XXX: use a macro to be portable on 64 bit ? */
|
||||||
cstr = (CString *)(*p++);
|
cstr = (CString *)(*p++);
|
||||||
cstr_free(cstr);
|
cstr_free(cstr);
|
||||||
|
@ -1791,7 +1800,7 @@ static void tok_str_add2(TokenString *s, int t, CValue *cv)
|
||||||
CValue cv1;
|
CValue cv1;
|
||||||
|
|
||||||
tok_str_add(s, t);
|
tok_str_add(s, t);
|
||||||
if (t == TOK_STR || t == TOK_LSTR) {
|
if (t == TOK_STR || t == TOK_LSTR || t == TOK_PPNUM) {
|
||||||
/* special case: need to duplicate string */
|
/* special case: need to duplicate string */
|
||||||
cstr1 = cv->cstr;
|
cstr1 = cv->cstr;
|
||||||
cstr = tcc_malloc(sizeof(CString));
|
cstr = tcc_malloc(sizeof(CString));
|
||||||
|
@ -2325,42 +2334,32 @@ void bn_zero(unsigned int *bn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void parse_number(void)
|
/* parse number in null terminated string 'p' and return it in the
|
||||||
|
current token */
|
||||||
|
void parse_number(const char *p)
|
||||||
{
|
{
|
||||||
int b, t, shift, frac_bits, s, exp_val;
|
int b, t, shift, frac_bits, s, exp_val, ch;
|
||||||
char *q;
|
char *q;
|
||||||
unsigned int bn[BN_SIZE];
|
unsigned int bn[BN_SIZE];
|
||||||
double d;
|
double d;
|
||||||
|
|
||||||
/* number */
|
/* number */
|
||||||
q = token_buf;
|
q = token_buf;
|
||||||
|
ch = *p++;
|
||||||
t = ch;
|
t = ch;
|
||||||
cinp();
|
ch = *p++;
|
||||||
*q++ = t;
|
*q++ = t;
|
||||||
b = 10;
|
b = 10;
|
||||||
if (t == '.') {
|
if (t == '.') {
|
||||||
/* special dot handling */
|
goto float_frac_parse;
|
||||||
if (ch >= '0' && ch <= '9') {
|
|
||||||
goto float_frac_parse;
|
|
||||||
} else if (ch == '.') {
|
|
||||||
cinp();
|
|
||||||
if (ch != '.')
|
|
||||||
expect("'.'");
|
|
||||||
cinp();
|
|
||||||
tok = TOK_DOTS;
|
|
||||||
} else {
|
|
||||||
/* dots */
|
|
||||||
tok = t;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
} else if (t == '0') {
|
} else if (t == '0') {
|
||||||
if (ch == 'x' || ch == 'X') {
|
if (ch == 'x' || ch == 'X') {
|
||||||
q--;
|
q--;
|
||||||
cinp();
|
ch = *p++;
|
||||||
b = 16;
|
b = 16;
|
||||||
} else if (tcc_ext && (ch == 'b' || ch == 'B')) {
|
} else if (tcc_ext && (ch == 'b' || ch == 'B')) {
|
||||||
q--;
|
q--;
|
||||||
cinp();
|
ch = *p++;
|
||||||
b = 2;
|
b = 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2382,7 +2381,7 @@ void parse_number(void)
|
||||||
error("number too long");
|
error("number too long");
|
||||||
}
|
}
|
||||||
*q++ = ch;
|
*q++ = ch;
|
||||||
cinp();
|
ch = *p++;
|
||||||
}
|
}
|
||||||
if (ch == '.' ||
|
if (ch == '.' ||
|
||||||
((ch == 'e' || ch == 'E') && b == 10) ||
|
((ch == 'e' || ch == 'E') && b == 10) ||
|
||||||
|
@ -2415,7 +2414,7 @@ void parse_number(void)
|
||||||
}
|
}
|
||||||
frac_bits = 0;
|
frac_bits = 0;
|
||||||
if (ch == '.') {
|
if (ch == '.') {
|
||||||
cinp();
|
ch = *p++;
|
||||||
while (1) {
|
while (1) {
|
||||||
t = ch;
|
t = ch;
|
||||||
if (t >= 'a' && t <= 'f') {
|
if (t >= 'a' && t <= 'f') {
|
||||||
|
@ -2431,25 +2430,25 @@ void parse_number(void)
|
||||||
error("invalid digit");
|
error("invalid digit");
|
||||||
bn_lshift(bn, shift, t);
|
bn_lshift(bn, shift, t);
|
||||||
frac_bits += shift;
|
frac_bits += shift;
|
||||||
cinp();
|
ch = *p++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ch != 'p' && ch != 'P')
|
if (ch != 'p' && ch != 'P')
|
||||||
error("exponent expected");
|
error("exponent expected");
|
||||||
cinp();
|
ch = *p++;
|
||||||
s = 1;
|
s = 1;
|
||||||
exp_val = 0;
|
exp_val = 0;
|
||||||
if (ch == '+') {
|
if (ch == '+') {
|
||||||
cinp();
|
ch = *p++;
|
||||||
} else if (ch == '-') {
|
} else if (ch == '-') {
|
||||||
s = -1;
|
s = -1;
|
||||||
cinp();
|
ch = *p++;
|
||||||
}
|
}
|
||||||
if (ch < '0' || ch > '9')
|
if (ch < '0' || ch > '9')
|
||||||
error("exponent digits expected");
|
error("exponent digits expected");
|
||||||
while (ch >= '0' && ch <= '9') {
|
while (ch >= '0' && ch <= '9') {
|
||||||
exp_val = exp_val * 10 + ch - '0';
|
exp_val = exp_val * 10 + ch - '0';
|
||||||
cinp();
|
ch = *p++;
|
||||||
}
|
}
|
||||||
exp_val = exp_val * s;
|
exp_val = exp_val * s;
|
||||||
|
|
||||||
|
@ -2459,12 +2458,12 @@ void parse_number(void)
|
||||||
d = ldexp(d, exp_val - frac_bits);
|
d = ldexp(d, exp_val - frac_bits);
|
||||||
t = toup(ch);
|
t = toup(ch);
|
||||||
if (t == 'F') {
|
if (t == 'F') {
|
||||||
cinp();
|
ch = *p++;
|
||||||
tok = TOK_CFLOAT;
|
tok = TOK_CFLOAT;
|
||||||
/* float : should handle overflow */
|
/* float : should handle overflow */
|
||||||
tokc.f = (float)d;
|
tokc.f = (float)d;
|
||||||
} else if (t == 'L') {
|
} else if (t == 'L') {
|
||||||
cinp();
|
ch = *p++;
|
||||||
tok = TOK_CLDOUBLE;
|
tok = TOK_CLDOUBLE;
|
||||||
/* XXX: not large enough */
|
/* XXX: not large enough */
|
||||||
tokc.ld = (long double)d;
|
tokc.ld = (long double)d;
|
||||||
|
@ -2478,25 +2477,25 @@ void parse_number(void)
|
||||||
if (q >= token_buf + STRING_MAX_SIZE)
|
if (q >= token_buf + STRING_MAX_SIZE)
|
||||||
goto num_too_long;
|
goto num_too_long;
|
||||||
*q++ = ch;
|
*q++ = ch;
|
||||||
cinp();
|
ch = *p++;
|
||||||
float_frac_parse:
|
float_frac_parse:
|
||||||
while (ch >= '0' && ch <= '9') {
|
while (ch >= '0' && ch <= '9') {
|
||||||
if (q >= token_buf + STRING_MAX_SIZE)
|
if (q >= token_buf + STRING_MAX_SIZE)
|
||||||
goto num_too_long;
|
goto num_too_long;
|
||||||
*q++ = ch;
|
*q++ = ch;
|
||||||
cinp();
|
ch = *p++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ch == 'e' || ch == 'E') {
|
if (ch == 'e' || ch == 'E') {
|
||||||
if (q >= token_buf + STRING_MAX_SIZE)
|
if (q >= token_buf + STRING_MAX_SIZE)
|
||||||
goto num_too_long;
|
goto num_too_long;
|
||||||
*q++ = ch;
|
*q++ = ch;
|
||||||
cinp();
|
ch = *p++;
|
||||||
if (ch == '-' || ch == '+') {
|
if (ch == '-' || ch == '+') {
|
||||||
if (q >= token_buf + STRING_MAX_SIZE)
|
if (q >= token_buf + STRING_MAX_SIZE)
|
||||||
goto num_too_long;
|
goto num_too_long;
|
||||||
*q++ = ch;
|
*q++ = ch;
|
||||||
cinp();
|
ch = *p++;
|
||||||
}
|
}
|
||||||
if (ch < '0' || ch > '9')
|
if (ch < '0' || ch > '9')
|
||||||
error("exponent digits expected");
|
error("exponent digits expected");
|
||||||
|
@ -2504,18 +2503,18 @@ void parse_number(void)
|
||||||
if (q >= token_buf + STRING_MAX_SIZE)
|
if (q >= token_buf + STRING_MAX_SIZE)
|
||||||
goto num_too_long;
|
goto num_too_long;
|
||||||
*q++ = ch;
|
*q++ = ch;
|
||||||
cinp();
|
ch = *p++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*q = '\0';
|
*q = '\0';
|
||||||
t = toup(ch);
|
t = toup(ch);
|
||||||
errno = 0;
|
errno = 0;
|
||||||
if (t == 'F') {
|
if (t == 'F') {
|
||||||
cinp();
|
ch = *p++;
|
||||||
tok = TOK_CFLOAT;
|
tok = TOK_CFLOAT;
|
||||||
tokc.f = strtof(token_buf, NULL);
|
tokc.f = strtof(token_buf, NULL);
|
||||||
} else if (t == 'L') {
|
} else if (t == 'L') {
|
||||||
cinp();
|
ch = *p++;
|
||||||
tok = TOK_CLDOUBLE;
|
tok = TOK_CLDOUBLE;
|
||||||
tokc.ld = strtold(token_buf, NULL);
|
tokc.ld = strtold(token_buf, NULL);
|
||||||
} else {
|
} else {
|
||||||
|
@ -2525,7 +2524,7 @@ void parse_number(void)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
unsigned long long n, n1;
|
unsigned long long n, n1;
|
||||||
int lcount;
|
int lcount, ucount;
|
||||||
|
|
||||||
/* integer number */
|
/* integer number */
|
||||||
*q = '\0';
|
*q = '\0';
|
||||||
|
@ -2552,6 +2551,7 @@ void parse_number(void)
|
||||||
n1 = n;
|
n1 = n;
|
||||||
n = n * b + t;
|
n = n * b + t;
|
||||||
/* detect overflow */
|
/* detect overflow */
|
||||||
|
/* XXX: this test is not reliable */
|
||||||
if (n < n1)
|
if (n < n1)
|
||||||
error("integer constant overflow");
|
error("integer constant overflow");
|
||||||
}
|
}
|
||||||
|
@ -2568,11 +2568,12 @@ void parse_number(void)
|
||||||
tok = TOK_CINT;
|
tok = TOK_CINT;
|
||||||
}
|
}
|
||||||
lcount = 0;
|
lcount = 0;
|
||||||
|
ucount = 0;
|
||||||
for(;;) {
|
for(;;) {
|
||||||
t = toup(ch);
|
t = toup(ch);
|
||||||
if (t == 'L') {
|
if (t == 'L') {
|
||||||
if (lcount >= 2)
|
if (lcount >= 2)
|
||||||
error("three 'l' in integer constant");
|
error("three 'l's in integer constant");
|
||||||
lcount++;
|
lcount++;
|
||||||
if (lcount == 2) {
|
if (lcount == 2) {
|
||||||
if (tok == TOK_CINT)
|
if (tok == TOK_CINT)
|
||||||
|
@ -2580,13 +2581,16 @@ void parse_number(void)
|
||||||
else if (tok == TOK_CUINT)
|
else if (tok == TOK_CUINT)
|
||||||
tok = TOK_CULLONG;
|
tok = TOK_CULLONG;
|
||||||
}
|
}
|
||||||
cinp();
|
ch = *p++;
|
||||||
} else if (t == 'U') {
|
} else if (t == 'U') {
|
||||||
|
if (ucount >= 1)
|
||||||
|
error("two 'u's in integer constant");
|
||||||
|
ucount++;
|
||||||
if (tok == TOK_CINT)
|
if (tok == TOK_CINT)
|
||||||
tok = TOK_CUINT;
|
tok = TOK_CUINT;
|
||||||
else if (tok == TOK_CLLONG)
|
else if (tok == TOK_CLLONG)
|
||||||
tok = TOK_CULLONG;
|
tok = TOK_CULLONG;
|
||||||
cinp();
|
ch = *p++;
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2598,7 +2602,6 @@ void parse_number(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* return next token without macro substitution */
|
/* return next token without macro substitution */
|
||||||
static inline void next_nomacro1(void)
|
static inline void next_nomacro1(void)
|
||||||
{
|
{
|
||||||
|
@ -2649,8 +2652,42 @@ static inline void next_nomacro1(void)
|
||||||
*q = '\0';
|
*q = '\0';
|
||||||
ts = tok_alloc(token_buf, q - token_buf);
|
ts = tok_alloc(token_buf, q - token_buf);
|
||||||
tok = ts->tok;
|
tok = ts->tok;
|
||||||
} else if (isnum(ch) || ch == '.') {
|
} else if (isnum(ch)) {
|
||||||
parse_number();
|
int t;
|
||||||
|
cstr_reset(&tokcstr);
|
||||||
|
/* after the first digit, accept digits, alpha, '.' or sign if
|
||||||
|
prefixed by 'eEpP' */
|
||||||
|
parse_num:
|
||||||
|
for(;;) {
|
||||||
|
t = ch;
|
||||||
|
cstr_ccat(&tokcstr, ch);
|
||||||
|
cinp();
|
||||||
|
if (!(isnum(ch) || isid(ch) || ch == '.' ||
|
||||||
|
((ch == '+' || ch == '-') &&
|
||||||
|
(t == 'e' || t == 'E' || t == 'p' || t == 'P'))))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* We add a trailing '\0' to ease parsing */
|
||||||
|
cstr_ccat(&tokcstr, '\0');
|
||||||
|
tokc.cstr = &tokcstr;
|
||||||
|
tok = TOK_PPNUM;
|
||||||
|
} else if (ch == '.') {
|
||||||
|
/* special dot handling because it can also start a number */
|
||||||
|
cinp();
|
||||||
|
if (isnum(ch)) {
|
||||||
|
cstr_reset(&tokcstr);
|
||||||
|
cstr_ccat(&tokcstr, '.');
|
||||||
|
goto parse_num;
|
||||||
|
}
|
||||||
|
if (ch == '.') {
|
||||||
|
cinp();
|
||||||
|
if (ch != '.')
|
||||||
|
expect("'.'");
|
||||||
|
cinp();
|
||||||
|
tok = TOK_DOTS;
|
||||||
|
} else {
|
||||||
|
tok = '.';
|
||||||
|
}
|
||||||
} else if (ch == '\'') {
|
} else if (ch == '\'') {
|
||||||
tok = TOK_CCHAR;
|
tok = TOK_CCHAR;
|
||||||
char_const:
|
char_const:
|
||||||
|
@ -2824,13 +2861,6 @@ int *macro_arg_subst(Sym **nested_list, int *macro_str, Sym *args)
|
||||||
return str.str;
|
return str.str;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* not inline to save space */
|
|
||||||
static int is_tok_num(int t)
|
|
||||||
{
|
|
||||||
return (t == TOK_CINT || t == TOK_CUINT ||
|
|
||||||
t == TOK_CLLONG || t == TOK_CULLONG);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* handle the '##' operator */
|
/* handle the '##' operator */
|
||||||
static int *macro_twosharps(void)
|
static int *macro_twosharps(void)
|
||||||
{
|
{
|
||||||
|
@ -2840,7 +2870,9 @@ static int *macro_twosharps(void)
|
||||||
const char *p1, *p2;
|
const char *p1, *p2;
|
||||||
CValue cval;
|
CValue cval;
|
||||||
TokenString macro_str1;
|
TokenString macro_str1;
|
||||||
|
CString cstr;
|
||||||
|
|
||||||
|
cstr_new(&cstr);
|
||||||
tok_str_new(¯o_str1);
|
tok_str_new(¯o_str1);
|
||||||
tok = 0;
|
tok = 0;
|
||||||
while (1) {
|
while (1) {
|
||||||
|
@ -2853,49 +2885,86 @@ static int *macro_twosharps(void)
|
||||||
t = *macro_ptr;
|
t = *macro_ptr;
|
||||||
if (t) {
|
if (t) {
|
||||||
t = tok_get(¯o_ptr, &cval);
|
t = tok_get(¯o_ptr, &cval);
|
||||||
/* XXX: not exact, but cannot do more without
|
|
||||||
modifying the whole preprocessing architecture ! */
|
/* We concatenate the two tokens if we have an
|
||||||
/* XXX: handle arbitrary size */
|
identifier or a preprocessing number */
|
||||||
|
cstr_reset(&cstr);
|
||||||
p1 = get_tok_str(tok, &tokc);
|
p1 = get_tok_str(tok, &tokc);
|
||||||
pstrcpy(token_buf, sizeof(token_buf), p1);
|
cstr_cat(&cstr, p1);
|
||||||
p2 = get_tok_str(t, &cval);
|
p2 = get_tok_str(t, &cval);
|
||||||
if (tok >= TOK_IDENT &&
|
cstr_cat(&cstr, p2);
|
||||||
(t >= TOK_IDENT || is_tok_num(t))) {
|
cstr_ccat(&cstr, '\0');
|
||||||
pstrcat(token_buf, sizeof(token_buf), p2);
|
|
||||||
ts = tok_alloc(token_buf, strlen(token_buf));
|
if ((tok >= TOK_IDENT || tok == TOK_PPNUM) &&
|
||||||
tok = ts->tok; /* modify current token */
|
(t >= TOK_IDENT || t == TOK_PPNUM)) {
|
||||||
} else if (is_tok_num(tok) && is_tok_num(t)) {
|
if (tok == TOK_PPNUM) {
|
||||||
unsigned long long n;
|
/* if number, then create a number token */
|
||||||
do_num:
|
/* NOTE: no need to allocate because
|
||||||
pstrcat(token_buf, sizeof(token_buf), p2);
|
tok_str_add2() does it */
|
||||||
n = strtoull(token_buf, NULL, 10);
|
tokc.cstr = &cstr;
|
||||||
if ((n & 0xffffffff00000000LL) != 0) {
|
|
||||||
if ((n >> 63) != 0)
|
|
||||||
tok = TOK_CULLONG;
|
|
||||||
else
|
|
||||||
tok = TOK_CLLONG;
|
|
||||||
} else if (n > 0x7fffffff) {
|
|
||||||
tok = TOK_CUINT;
|
|
||||||
} else {
|
} else {
|
||||||
tok = TOK_CINT;
|
/* if identifier, we must do a test to
|
||||||
|
validate we have a correct identifier */
|
||||||
|
if (t == TOK_PPNUM) {
|
||||||
|
const char *p;
|
||||||
|
int c;
|
||||||
|
|
||||||
|
p = p2;
|
||||||
|
for(;;) {
|
||||||
|
c = *p;
|
||||||
|
if (c == '\0')
|
||||||
|
break;
|
||||||
|
p++;
|
||||||
|
if (!isnum(c) && !isid(c))
|
||||||
|
goto error_pasting;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ts = tok_alloc(cstr.data, strlen(cstr.data));
|
||||||
|
tok = ts->tok; /* modify current token */
|
||||||
}
|
}
|
||||||
if (tok == TOK_CINT || tok == TOK_CUINT)
|
|
||||||
tokc.ui = n;
|
|
||||||
else
|
|
||||||
tokc.ull = n;
|
|
||||||
} else if (is_tok_num(tok) && t >= TOK_IDENT) {
|
|
||||||
/* incorrect, but suffisant for '1LL' case */
|
|
||||||
goto do_num;
|
|
||||||
} else {
|
} else {
|
||||||
warning("pasting \"%s\" and \"%s\" does not give a valid preprocessing token", token_buf, p2);
|
const char *str = cstr.data;
|
||||||
/* cannot merge tokens: skip '##' */
|
const unsigned char *q;
|
||||||
macro_ptr = macro_ptr1;
|
|
||||||
break;
|
/* we look for a valid token */
|
||||||
|
/* XXX: do more extensive checks */
|
||||||
|
if (!strcmp(str, ">>=")) {
|
||||||
|
tok = TOK_A_SAR;
|
||||||
|
} else if (!strcmp(str, "<<=")) {
|
||||||
|
tok = TOK_A_SHL;
|
||||||
|
} else if (strlen(str) == 2) {
|
||||||
|
/* search in two bytes table */
|
||||||
|
q = tok_two_chars;
|
||||||
|
for(;;) {
|
||||||
|
if (!*q)
|
||||||
|
goto error_pasting;
|
||||||
|
if (q[0] == str[0] && q[1] == str[1])
|
||||||
|
break;
|
||||||
|
q += 3;
|
||||||
|
}
|
||||||
|
tok = q[2];
|
||||||
|
} else {
|
||||||
|
error_pasting:
|
||||||
|
/* NOTE: because get_tok_str use a static buffer,
|
||||||
|
we must save it */
|
||||||
|
cstr_reset(&cstr);
|
||||||
|
p1 = get_tok_str(tok, &tokc);
|
||||||
|
cstr_cat(&cstr, p1);
|
||||||
|
cstr_ccat(&cstr, '\0');
|
||||||
|
p2 = get_tok_str(t, &cval);
|
||||||
|
warning("pasting \"%s\" and \"%s\" does not give a valid preprocessing token", cstr.data, p2);
|
||||||
|
/* cannot merge tokens: just add them separately */
|
||||||
|
tok_str_add2(¯o_str1, tok, &tokc);
|
||||||
|
/* XXX: free associated memory ? */
|
||||||
|
tok = t;
|
||||||
|
tokc = cval;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tok_str_add2(¯o_str1, tok, &tokc);
|
tok_str_add2(¯o_str1, tok, &tokc);
|
||||||
}
|
}
|
||||||
|
cstr_free(&cstr);
|
||||||
tok_str_add(¯o_str1, 0);
|
tok_str_add(¯o_str1, 0);
|
||||||
return macro_str1.str;
|
return macro_str1.str;
|
||||||
}
|
}
|
||||||
|
@ -3100,6 +3169,11 @@ void next(void)
|
||||||
goto redo;
|
goto redo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* convert preprocessor tokens into C tokens */
|
||||||
|
if (tok == TOK_PPNUM) {
|
||||||
|
parse_number((char *)tokc.cstr->data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#if defined(DEBUG)
|
#if defined(DEBUG)
|
||||||
printf("token = %s\n", get_tok_str(tok, &tokc));
|
printf("token = %s\n", get_tok_str(tok, &tokc));
|
||||||
|
|
Loading…
Reference in a new issue