tccpp: fix issues, add tests
* fix some macro expansion issues
* add some pp tests in tests/pp
* improved tcc -E output for better diff'ability
* remove -dD feature (quirky code, exotic feature,
didn't work well)
Based partially on ideas / researches from PipCet
Some issues remain with VA_ARGS macros (if used in a
rather tricky way).
Also, to keep it simple, the pp doesn't automtically
add any extra spaces to separate tokens which otherwise
would form wrong tokens if re-read from tcc -E output
(such as '+' '=') GCC does that, other compilers don't.
* cleanups
- #line 01 "file" / # 01 "file" processing
- #pragma comment(lib,"foo")
- tcc -E: forward some pragmas to output (pack, comment(lib))
- fix macro parameter list parsing mess from
a3fc543459
a715d7143d
(some coffee might help, next time ;)
- introduce TOK_PPSTR - to have character constants as
written in the file (similar to TOK_PPNUM)
- allow '\' appear in macros
- new functions begin/end_macro to:
- fix switching macro levels during expansion
- allow unget_tok to unget more than one tok
- slight speedup by using bitflags in isidnum_table
Also:
- x86_64.c : fix decl after statements
- i386-gen,c : fix a vstack leak with VLA on windows
- configure/Makefile : build on windows (MSYS) was broken
- tcc_warning: fflush stderr to keep output order (win32)
This commit is contained in:
6
tests/pp/01.c
Normal file
6
tests/pp/01.c
Normal file
@ -0,0 +1,6 @@
|
||||
#define hash_hash # ## #
|
||||
#define mkstr(a) # a
|
||||
#define in_between(a) mkstr(a)
|
||||
#define join(c, d) in_between(c hash_hash d)
|
||||
char p[] = join(x, y);
|
||||
// char p[] = "x ## y";
|
||||
1
tests/pp/01.expect
Normal file
1
tests/pp/01.expect
Normal file
@ -0,0 +1 @@
|
||||
char p[] = "x ## y";
|
||||
28
tests/pp/02.c
Normal file
28
tests/pp/02.c
Normal file
@ -0,0 +1,28 @@
|
||||
#define x 3
|
||||
#define f(a) f(x * (a))
|
||||
#undef x
|
||||
#define x 2
|
||||
#define g f
|
||||
#define z z[0]
|
||||
#define h g(~
|
||||
#define m(a) a(w)
|
||||
#define w 0,1
|
||||
#define t(a) a
|
||||
#define p() int
|
||||
#define q(x) x
|
||||
#define r(x,y) x ## y
|
||||
#define str(x) # x
|
||||
f(y+1) + f(f(z)) % t(t(g)(0) + t)(1);
|
||||
g(x+(3,4)-w) | h 5) & m
|
||||
(f)^m(m);
|
||||
char c[2][6] = { str(hello), str() };
|
||||
/*
|
||||
* f(2 * (y+1)) + f(2 * (f(2 * (z[0])))) % f(2 * (0)) + t(1);
|
||||
* f(2 * (2+(3,4)-0,1)) | f(2 * (~ 5)) & f(2 * (0,1))^m(0,1);
|
||||
* char c[2][6] = { "hello", "" };
|
||||
*/
|
||||
#define L21 f(y+1) + f(f(z)) % t(t(g)(0) + t)(1);
|
||||
#define L22 g(x+(3,4)-w) | h 5) & m\
|
||||
(f)^m(m);
|
||||
L21
|
||||
L22
|
||||
5
tests/pp/02.expect
Normal file
5
tests/pp/02.expect
Normal file
@ -0,0 +1,5 @@
|
||||
f(2 * (y+1)) + f(2 * (f(2 * (z[0])))) % f(2 * (0)) + t(1);
|
||||
f(2 * (2+(3,4)-0,1)) | f(2 * (~ 5)) & f(2 * (0,1))^m(0,1);
|
||||
char c[2][6] = { "hello", "" };
|
||||
f(2 * (y+1)) + f(2 * (f(2 * (z[0])))) % f(2 * (0)) + t(1);
|
||||
f(2 * (2+(3,4)-0,1)) | f(2 * (~ 5)) & f(2 * (0,1))^m(0,1);
|
||||
15
tests/pp/03.c
Normal file
15
tests/pp/03.c
Normal file
@ -0,0 +1,15 @@
|
||||
#define str(s) # s
|
||||
#define xstr(s) str(s)
|
||||
#define debug(s, t) printf("x" # s "= %d, x" # t "= %s", \
|
||||
x ## s, x ## t)
|
||||
#define INCFILE(n) vers ## n
|
||||
#define glue(a, b) a ## b
|
||||
#define xglue(a, b) glue(a, b)
|
||||
#define HIGHLOW "hello"
|
||||
#define LOW LOW ", world"
|
||||
debug(1, 2);
|
||||
fputs(str(strncmp("abc\0d", "abc", '\4') // this goes away
|
||||
== 0) str(: @\n), s);
|
||||
\#include xstr(INCFILE(2).h)
|
||||
glue(HIGH, LOW);
|
||||
xglue(HIGH, LOW)
|
||||
5
tests/pp/03.expect
Normal file
5
tests/pp/03.expect
Normal file
@ -0,0 +1,5 @@
|
||||
printf("x" "1" "= %d, x" "2" "= %s", x1, x2);
|
||||
fputs("strncmp(\"abc\\0d\", \"abc\", '\\4') == 0" ": @\n", s);
|
||||
\#include "vers2.h"
|
||||
"hello";
|
||||
"hello" ", world"
|
||||
4
tests/pp/04.c
Normal file
4
tests/pp/04.c
Normal file
@ -0,0 +1,4 @@
|
||||
#define foobar 1
|
||||
#define C(x,y) x##y
|
||||
#define D(x) (C(x,bar))
|
||||
D(foo)
|
||||
1
tests/pp/04.expect
Normal file
1
tests/pp/04.expect
Normal file
@ -0,0 +1 @@
|
||||
(1)
|
||||
7
tests/pp/05.c
Normal file
7
tests/pp/05.c
Normal file
@ -0,0 +1,7 @@
|
||||
#define t(x,y,z) x ## y ## z
|
||||
#define xxx(s) int s[] = { t(1,2,3), t(,4,5), t(6,,7), t(8,9,), \
|
||||
t(10,,), t(,11,), t(,,12), t(,,) };
|
||||
|
||||
int j[] = { t(1,2,3), t(,4,5), t(6,,7), t(8,9,),
|
||||
t(10,,), t(,11,), t(,,12), t(,,) };
|
||||
xxx(j)
|
||||
3
tests/pp/05.expect
Normal file
3
tests/pp/05.expect
Normal file
@ -0,0 +1,3 @@
|
||||
int j[] = { 123, 45, 67, 89,
|
||||
10, 11, 12, };
|
||||
int j[] = { 123, 45, 67, 89, 10, 11, 12, };
|
||||
5
tests/pp/06.c
Normal file
5
tests/pp/06.c
Normal file
@ -0,0 +1,5 @@
|
||||
#define X(a,b, \
|
||||
c,d) \
|
||||
foo
|
||||
|
||||
X(1,2,3,4)
|
||||
1
tests/pp/06.expect
Normal file
1
tests/pp/06.expect
Normal file
@ -0,0 +1 @@
|
||||
foo
|
||||
4
tests/pp/07.c
Normal file
4
tests/pp/07.c
Normal file
@ -0,0 +1,4 @@
|
||||
#define a() YES
|
||||
#define b() a
|
||||
b()
|
||||
b()()
|
||||
2
tests/pp/07.expect
Normal file
2
tests/pp/07.expect
Normal file
@ -0,0 +1,2 @@
|
||||
a
|
||||
YES
|
||||
4
tests/pp/08.c
Normal file
4
tests/pp/08.c
Normal file
@ -0,0 +1,4 @@
|
||||
// test macro expansion in arguments
|
||||
#define s_pos s_s.s_pos
|
||||
#define foo(x) (x)
|
||||
foo(hej.s_pos)
|
||||
1
tests/pp/08.expect
Normal file
1
tests/pp/08.expect
Normal file
@ -0,0 +1 @@
|
||||
(hej.s_s.s_pos)
|
||||
4
tests/pp/09.c
Normal file
4
tests/pp/09.c
Normal file
@ -0,0 +1,4 @@
|
||||
#define C(a,b,c) a##b##c
|
||||
#define N(x,y) C(x,_,y)
|
||||
#define A_O aaaaoooo
|
||||
N(A,O)
|
||||
1
tests/pp/09.expect
Normal file
1
tests/pp/09.expect
Normal file
@ -0,0 +1 @@
|
||||
aaaaoooo
|
||||
10
tests/pp/10.c
Normal file
10
tests/pp/10.c
Normal file
@ -0,0 +1,10 @@
|
||||
#define f(x) x
|
||||
#define g(x) f(x) f(x
|
||||
#define i(x) g(x)) g(x
|
||||
#define h(x) i(x))) i(x
|
||||
#define k(x) i(x))) i(x))))
|
||||
f(x)
|
||||
g(x))
|
||||
i(x)))
|
||||
h(x))))
|
||||
k(x))))
|
||||
5
tests/pp/10.expect
Normal file
5
tests/pp/10.expect
Normal file
@ -0,0 +1,5 @@
|
||||
x
|
||||
x x
|
||||
x x x x
|
||||
x x x x x x x x
|
||||
x x x x x x x x))))
|
||||
31
tests/pp/11.c
Normal file
31
tests/pp/11.c
Normal file
@ -0,0 +1,31 @@
|
||||
#define D1(s, ...) s
|
||||
#define D2(s, ...) s D1(__VA_ARGS__)
|
||||
#define D3(s, ...) s D2(__VA_ARGS__)
|
||||
#define D4(s, ...) s D3(__VA_ARGS__)
|
||||
|
||||
D1(a)
|
||||
D2(a, b)
|
||||
D3(a, b, c)
|
||||
D4(a, b, c, d)
|
||||
|
||||
x D4(a, b, c, d) y
|
||||
x D4(a, b, c) y
|
||||
x D4(a, b) y
|
||||
x D4(a) y
|
||||
x D4() y
|
||||
|
||||
#define GNU_COMMA(X,Y...) X,## Y
|
||||
|
||||
x GNU_COMMA(A,B,C) y
|
||||
x GNU_COMMA(A,B) y
|
||||
x GNU_COMMA(A) y
|
||||
x GNU_COMMA() y
|
||||
|
||||
#define __sun_attr___noreturn__ __attribute__((__noreturn__))
|
||||
#define ___sun_attr_inner(__a) __sun_attr_##__a
|
||||
#define __sun_attr__(__a) ___sun_attr_inner __a
|
||||
#define __NORETURN __sun_attr__((__noreturn__))
|
||||
__NORETURN
|
||||
#define X(...)
|
||||
#define Y(...) 1 __VA_ARGS__ 2
|
||||
Y(X X() ())
|
||||
15
tests/pp/11.expect
Normal file
15
tests/pp/11.expect
Normal file
@ -0,0 +1,15 @@
|
||||
a
|
||||
a b
|
||||
a b c
|
||||
a b c d
|
||||
x a b c d y
|
||||
x a b c y
|
||||
x a b y
|
||||
x a y
|
||||
x y
|
||||
x A,B,C y
|
||||
x A,B y
|
||||
x A y
|
||||
x y
|
||||
__attribute__((__noreturn__))
|
||||
1 2
|
||||
35
tests/pp/Makefile
Normal file
35
tests/pp/Makefile
Normal file
@ -0,0 +1,35 @@
|
||||
#
|
||||
# credits: 01..13.c from the pcc cpp-tests suite
|
||||
#
|
||||
|
||||
TCC = ../../tcc
|
||||
TESTS = $(patsubst %.c,%.test,$(wildcard *.c))
|
||||
|
||||
all test : $(TESTS)
|
||||
|
||||
%.test: %.c %.expect
|
||||
@echo PPTest $* ...
|
||||
@$(TCC) -E -P $< >$*.output 2>&1 ; \
|
||||
diff -Nu -b -B -I "^#" $(EXTRA_DIFF_OPTS) $*.expect $*.output \
|
||||
&& rm -f $*.output
|
||||
|
||||
# automatically generate .expect files with gcc:
|
||||
%.expect :
|
||||
gcc -E -P $*.c >$*.expect 2>&1
|
||||
|
||||
# tell make not to delete
|
||||
.PRECIOUS: %.expect
|
||||
|
||||
clean:
|
||||
rm -vf *.output
|
||||
|
||||
# 02.test : EXTRA_DIFF_OPTS = -w
|
||||
# 03.test : EXTRA_DIFF_OPTS = -w
|
||||
# 04.test : EXTRA_DIFF_OPTS = -w
|
||||
# 10.test : EXTRA_DIFF_OPTS = -w
|
||||
|
||||
# diff options:
|
||||
# -b ighore space changes
|
||||
# -w ighore all whitespace
|
||||
# -B ignore blank lines
|
||||
# -I <RE> ignore lines matching RE
|
||||
Reference in New Issue
Block a user