aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libtcc.c1
-rw-r--r--tccpp.c39
-rw-r--r--tcctok.h1
-rw-r--r--tests/pp/pp-counter.c27
-rw-r--r--tests/pp/pp-counter.expect15
5 files changed, 72 insertions, 11 deletions
diff --git a/libtcc.c b/libtcc.c
index 0e5f55b..ba50ddf 100644
--- a/libtcc.c
+++ b/libtcc.c
@@ -762,6 +762,7 @@ LIBTCCAPI TCCState *tcc_new(void)
define_push(TOK___FILE__, MACRO_OBJ, NULL, NULL);
define_push(TOK___DATE__, MACRO_OBJ, NULL, NULL);
define_push(TOK___TIME__, MACRO_OBJ, NULL, NULL);
+ define_push(TOK___COUNTER__, MACRO_OBJ, NULL, NULL);
{
/* define __TINYC__ 92X */
char buffer[32]; int a,b,c;
diff --git a/tccpp.c b/tccpp.c
index ced5cc6..dca900c 100644
--- a/tccpp.c
+++ b/tccpp.c
@@ -2980,18 +2980,29 @@ static int *macro_arg_subst(Sym **nested_list, const int *macro_str, Sym *args)
str.len--;
goto add_var;
}
- } else {
- for(;;) {
- int t1;
- TOK_GET(&t1, &st, &cval);
- if (t1 <= 0)
- break;
- tok_str_add2(&str, t1, &cval);
- }
}
} else {
add_var:
- macro_subst(&str, nested_list, st);
+ if (!s->next) {
+ /* Expand arguments tokens and store them. In most
+ cases we could also re-expand each argument if
+ used multiple times, but not if the argument
+ contains the __COUNTER__ macro. */
+ TokenString str2;
+ sym_push2(&s->next, s->v, s->type.t, 0);
+ tok_str_new(&str2);
+ macro_subst(&str2, nested_list, st);
+ tok_str_add(&str2, 0);
+ s->next->d = str2.str;
+ }
+ st = s->next->d;
+ }
+ for(;;) {
+ int t2;
+ TOK_GET(&t2, &st, &cval);
+ if (t2 <= 0)
+ break;
+ tok_str_add2(&str, t2, &cval);
}
if (str.len == l0) /* expanded to empty string */
tok_str_add(&str, TOK_PLCHLDR);
@@ -3180,11 +3191,13 @@ static int macro_subst_tok(
CValue cval;
CString cstr;
char buf[32];
+ static int counter;
/* if symbol is a macro, prepare substitution */
/* special macros */
- if (tok == TOK___LINE__) {
- snprintf(buf, sizeof(buf), "%d", file->line_num);
+ if (tok == TOK___LINE__ || tok == TOK___COUNTER__) {
+ t = tok == TOK___LINE__ ? file->line_num : counter++;
+ snprintf(buf, sizeof(buf), "%d", t);
cstrval = buf;
t1 = TOK_PPNUM;
goto add_cstr1;
@@ -3316,6 +3329,10 @@ static int macro_subst_tok(
while (sa) {
sa1 = sa->prev;
tok_str_free_str(sa->d);
+ if (sa->next) {
+ tok_str_free_str(sa->next->d);
+ sym_free(sa->next);
+ }
sym_free(sa);
sa = sa1;
}
diff --git a/tcctok.h b/tcctok.h
index 56e1ae3..6d4ad30 100644
--- a/tcctok.h
+++ b/tcctok.h
@@ -87,6 +87,7 @@
DEF(TOK___TIME__, "__TIME__")
DEF(TOK___FUNCTION__, "__FUNCTION__")
DEF(TOK___VA_ARGS__, "__VA_ARGS__")
+ DEF(TOK___COUNTER__, "__COUNTER__")
/* special identifiers */
DEF(TOK___FUNC__, "__func__")
diff --git a/tests/pp/pp-counter.c b/tests/pp/pp-counter.c
new file mode 100644
index 0000000..3978e1a
--- /dev/null
+++ b/tests/pp/pp-counter.c
@@ -0,0 +1,27 @@
+X1 __COUNTER__
+X2 __COUNTER__
+#if __COUNTER__
+X3 __COUNTER__
+#endif
+#define pass(x) x
+#define a x __COUNTER__ y
+#define a2 pass(__COUNTER__)
+#define f(c) c __COUNTER__
+#define apply(d) d d __COUNTER__ x2 f(d) y2 __COUNTER__
+#define _paste(a,b) a ## b
+#define paste(a,b) _paste(a,b)
+#define _paste3(a,b,c) a ## b ## c
+#define doublepaste(a,b) _paste3(a,b,b)
+#define str(x) #x
+X4 a
+X5 f(a)
+X6 f(b)
+X7 f(__COUNTER__)
+X8 apply(a)
+X9 apply(f(a))
+X10 apply(__COUNTER__)
+X11 apply(a2)
+X12 str(__COUNTER__)
+X13 paste(x,__COUNTER__)
+X14 _paste(x,__COUNTER__)
+X15 doublepaste(x,__COUNTER__)
diff --git a/tests/pp/pp-counter.expect b/tests/pp/pp-counter.expect
new file mode 100644
index 0000000..02fc535
--- /dev/null
+++ b/tests/pp/pp-counter.expect
@@ -0,0 +1,15 @@
+X1 0
+X2 1
+X3 3
+X4 x 4 y
+X5 x 5 y 6
+X6 b 7
+X7 8 9
+X8 x 10 y x 10 y 11 x2 x 10 y 12 y2 13
+X9 x 14 y 15 x 14 y 15 16 x2 x 14 y 15 17 y2 18
+X10 19 19 20 x2 19 21 y2 22
+X11 23 23 24 x2 23 25 y2 26
+X12 "__COUNTER__"
+X13 x27
+X14 x__COUNTER__
+X15 x2828