#pragma comment(option,"-..."), bitfields test, etc...

tccpp.c:
* #pragma comment(option,"-some-option")
  to set commandline option from C code.  May work only
  for some options.
libtcc.c:
* option "-d1..9": sets a 'g_debug' global variable.
  (for development)
tests2/Makefile:
* new make targets: tests2.37 / tests2.37+
  run single test from tests2,  optionally update .expect
* new variable GEN-ALWAYS to always generate certain .expects
* bitfields test
tccgen.c:
* bitfields: fix a bug and improve slightly more
* _Generic: ignore "type match twice"
master
grischka 2017-07-14 19:26:01 +02:00
parent 04418c7add
commit 69a137ff88
10 changed files with 476 additions and 55 deletions

View File

@ -345,9 +345,12 @@ tar: tcc-doc.html
config.mak: config.mak:
$(if $(wildcard $@),,@echo "Please run ./configure." && exit 1) $(if $(wildcard $@),,@echo "Please run ./configure." && exit 1)
# in tests subdir # run all tests
test: test:
$(MAKE) -C tests $(MAKE) -C tests
# run test(s) from tests2 subdir (see make help)
tests2.%:
$(MAKE) -C tests/tests2 $@
clean: clean:
rm -f $(PROGS) $(PROGS_CROSS) tcc_p$(EXESUF) tcc.pod rm -f $(PROGS) $(PROGS_CROSS) tcc_p$(EXESUF) tcc.pod
@ -389,8 +392,14 @@ help:
@echo " INC-i386 = {B}/lib/include:{B}/i386-linux/usr/include" @echo " INC-i386 = {B}/lib/include:{B}/i386-linux/usr/include"
@echo " DEF-i386 += -D__linux__" @echo " DEF-i386 += -D__linux__"
@echo "" @echo ""
@echo "make test"
@echo " run all tests"
@echo ""
@echo "make tests2.all / make tests2.37 / make tests2.37+"
@echo " run all/single test(s) from tests2, optionally update .expect"
@echo ""
@echo "Other supported make targets:" @echo "Other supported make targets:"
@echo " install install-strip test tags ETAGS tar clean distclean help" @echo " install install-strip tags ETAGS tar clean distclean help"
@echo "" @echo ""
# -------------------------------------------------------------------------- # --------------------------------------------------------------------------

View File

@ -1801,6 +1801,8 @@ reparse:
s->dflag = 3; s->dflag = 3;
else if (*optarg == 'M') else if (*optarg == 'M')
s->dflag = 7; s->dflag = 7;
else if (isnum(*optarg))
g_debug = atoi(optarg);
else else
goto unsupported_option; goto unsupported_option;
break; break;

1
tcc.h
View File

@ -1289,6 +1289,7 @@ ST_DATA int func_var; /* true if current function is variadic */
ST_DATA int func_vc; ST_DATA int func_vc;
ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */ ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */
ST_DATA const char *funcname; ST_DATA const char *funcname;
ST_DATA int g_debug;
ST_FUNC void tcc_debug_start(TCCState *s1); ST_FUNC void tcc_debug_start(TCCState *s1);
ST_FUNC void tcc_debug_end(TCCState *s1); ST_FUNC void tcc_debug_end(TCCState *s1);

View File

@ -57,6 +57,7 @@ ST_DATA int func_var; /* true if current function is variadic (used by return in
ST_DATA int func_vc; ST_DATA int func_vc;
ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */ ST_DATA int last_line_num, last_ind, func_ind; /* debug last line number and pc */
ST_DATA const char *funcname; ST_DATA const char *funcname;
ST_DATA int g_debug;
ST_DATA CType char_pointer_type, func_old_type, int_type, size_type; ST_DATA CType char_pointer_type, func_old_type, int_type, size_type;
@ -1083,8 +1084,7 @@ static void load_packed_bf(CType *type, int bit_pos, int bit_size)
{ {
int n, o, bits; int n, o, bits;
save_reg_upstack(vtop->r, 1); save_reg_upstack(vtop->r, 1);
vpushi(0); // B X vpush64(type->t & VT_BTYPE, 0); // B X
vtop->type.t |= type->t;
bits = 0, o = bit_pos >> 3, bit_pos &= 7; bits = 0, o = bit_pos >> 3, bit_pos &= 7;
do { do {
vswap(); // X B vswap(); // X B
@ -1113,7 +1113,7 @@ static void load_packed_bf(CType *type, int bit_pos, int bit_size)
} }
/* single-byte store mode for packed or otherwise unaligned bitfields */ /* single-byte store mode for packed or otherwise unaligned bitfields */
void store_packed_bf(int bit_pos, int bit_size) static void store_packed_bf(int bit_pos, int bit_size)
{ {
int bits, n, o, m, c; int bits, n, o, m, c;
@ -1148,7 +1148,7 @@ void store_packed_bf(int bit_pos, int bit_size)
vpop(), vpop(); vpop(), vpop();
} }
int adjust_bf(SValue *sv, int bit_pos, int bit_size) static int adjust_bf(SValue *sv, int bit_pos, int bit_size)
{ {
int t; int t;
if (0 == sv->type.ref) if (0 == sv->type.ref)
@ -2781,7 +2781,7 @@ static void type_to_str(char *buf, int buf_size,
pstrcat(buf, buf_size, "inline "); pstrcat(buf, buf_size, "inline ");
buf_size -= strlen(buf); buf_size -= strlen(buf);
buf += strlen(buf); buf += strlen(buf);
if (IS_ENUM(type->t)) { if (IS_ENUM(t)) {
tstr = "enum "; tstr = "enum ";
goto tstruct; goto tstruct;
} }
@ -3405,9 +3405,12 @@ static void struct_layout(CType *type, AttributeDef *ad)
//#define BF_DEBUG //#define BF_DEBUG
for (f = type->ref->next; f; f = f->next) { for (f = type->ref->next; f; f = f->next) {
if (f->type.t & VT_BITFIELD) if (f->type.t & VT_BITFIELD) {
bit_size = BIT_SIZE(f->type.t); bit_size = BIT_SIZE(f->type.t);
else /* in pcc mode, long long bitfields have type int if they fit */
if (pcc && (f->type.t & VT_BTYPE) == VT_LLONG && bit_size <= 32)
f->type.t = (f->type.t & ~VT_BTYPE) | VT_INT;
} else
bit_size = -1; bit_size = -1;
size = type_size(&f->type, &align); size = type_size(&f->type, &align);
a = f->a.aligned ? 1 << (f->a.aligned - 1) : 0; a = f->a.aligned ? 1 << (f->a.aligned - 1) : 0;
@ -3476,16 +3479,10 @@ static void struct_layout(CType *type, AttributeDef *ad)
goto new_field; goto new_field;
} }
/* in pcc mode, long long bitfields have type int if they fit */ while (bit_pos >= align * 8)
if (size == 8 && bit_size <= 32) { c += align, bit_pos -= align * 8;
f->type.t = (f->type.t & ~VT_BTYPE) | VT_INT;
size = 4;
}
if (bit_pos >= size * 8) {
c += size;
bit_pos -= size * 8;
}
offset = c; offset = c;
/* In PCC layout named bit-fields influence the alignment /* In PCC layout named bit-fields influence the alignment
of the containing struct using the base types alignment, of the containing struct using the base types alignment,
except for packed fields (which here have correct align). */ except for packed fields (which here have correct align). */
@ -3576,14 +3573,20 @@ static void struct_layout(CType *type, AttributeDef *ad)
if (pcc) if (pcc)
c += (bit_pos + 7) >> 3; c += (bit_pos + 7) >> 3;
a = ad->a.aligned ? 1 << (ad->a.aligned - 1) : 0; /* store size and alignment */
a = bt = ad->a.aligned ? 1 << (ad->a.aligned - 1) : 1;
if (a < maxalign) if (a < maxalign)
a = maxalign; a = maxalign;
c = (c + a - 1) & -a;
/* store size and alignment */
type->ref->c = c;
type->ref->r = a; type->ref->r = a;
if (pragma_pack && pragma_pack < maxalign) {
/* can happen if individual align for some member was given. In
this case MSVC ignores maxalign when aligning the size */
a = pragma_pack;
if (a < bt)
a = bt;
}
c = (c + a - 1) & -a;
type->ref->c = c;
#ifdef BF_DEBUG #ifdef BF_DEBUG
printf("struct size %-2d align %-2d\n\n", c, a), fflush(stdout); printf("struct size %-2d align %-2d\n\n", c, a), fflush(stdout);
@ -3603,7 +3606,6 @@ static void struct_layout(CType *type, AttributeDef *ad)
continue; continue;
bit_pos = BIT_POS(f->type.t); bit_pos = BIT_POS(f->type.t);
size = type_size(&f->type, &align); size = type_size(&f->type, &align);
if (bit_pos + bit_size <= size * 8 && f->c + size <= c) if (bit_pos + bit_size <= size * 8 && f->c + size <= c)
continue; continue;
@ -3637,19 +3639,20 @@ static void struct_layout(CType *type, AttributeDef *ad)
| (bit_pos << VT_STRUCT_SHIFT); | (bit_pos << VT_STRUCT_SHIFT);
if (s != size) if (s != size)
f->auxtype = t.t; f->auxtype = t.t;
#ifdef BF_DEBUG
printf("FIX field %s offset %-2d size %-2d align %-2d "
"pos %-2d bits %-2d\n",
get_tok_str(f->v & ~SYM_FIELD, NULL),
cx, s, align, px, bit_size);
#endif
} else { } else {
/* fall back to load/store single-byte wise */ /* fall back to load/store single-byte wise */
f->auxtype = VT_STRUCT; f->auxtype = VT_STRUCT;
}
#ifdef BF_DEBUG #ifdef BF_DEBUG
printf("FIX field %s offset %-2d size %-2d align %-2d " printf("FIX field %s : load byte-wise\n",
"pos %-2d bits %-2d %s\n", get_tok_str(f->v & ~SYM_FIELD, NULL));
get_tok_str(f->v & ~SYM_FIELD, NULL),
cx, s, align, px, bit_size,
f->auxtype == VT_PTR ? " byte-wise" : ""
);
#endif #endif
}
} }
} }
@ -4915,9 +4918,9 @@ ST_FUNC void unary(void)
type_decl(&cur_type, &ad_tmp, &itmp, TYPE_ABSTRACT); type_decl(&cur_type, &ad_tmp, &itmp, TYPE_ABSTRACT);
if (compare_types(&controlling_type, &cur_type, 0)) { if (compare_types(&controlling_type, &cur_type, 0)) {
if (has_match) { if (has_match) {
tcc_error("type march twice"); // tcc_error("type march twice");
} }
if (has_default) if (str)
tok_str_free(str); tok_str_free(str);
has_match = 1; has_match = 1;
learn = 1; learn = 1;

22
tccpp.c
View File

@ -1658,24 +1658,28 @@ static void pragma_parse(TCCState *s1)
goto pragma_err; goto pragma_err;
} else if (tok == TOK_comment) { } else if (tok == TOK_comment) {
char *file; char *p; int t;
next(); next();
skip('('); skip('(');
if (tok != TOK_lib) t = tok;
goto pragma_warn;
next(); next();
skip(','); skip(',');
if (tok != TOK_STR) if (tok != TOK_STR)
goto pragma_err; goto pragma_err;
file = tcc_strdup((char *)tokc.str.data); p = tcc_strdup((char *)tokc.str.data);
dynarray_add(&s1->pragma_libs, &s1->nb_pragma_libs, file);
next(); next();
if (tok != ')') if (tok != ')')
goto pragma_err; goto pragma_err;
} else { if (t == TOK_lib) {
pragma_warn: dynarray_add(&s1->pragma_libs, &s1->nb_pragma_libs, p);
if (s1->warn_unsupported) } else {
tcc_warning("#pragma %s is ignored", get_tok_str(tok, &tokc)); if (t == TOK_option)
tcc_set_options(s1, p);
tcc_free(p);
}
} else if (s1->warn_unsupported) {
tcc_warning("#pragma %s is ignored", get_tok_str(tok, &tokc));
} }
return; return;

View File

@ -167,6 +167,7 @@
DEF(TOK_push_macro, "push_macro") DEF(TOK_push_macro, "push_macro")
DEF(TOK_pop_macro, "pop_macro") DEF(TOK_pop_macro, "pop_macro")
DEF(TOK_once, "once") DEF(TOK_once, "once")
DEF(TOK_option, "option")
/* builtin functions or variables */ /* builtin functions or variables */
#ifndef TCC_ARM_EABI #ifndef TCC_ARM_EABI

View File

@ -0,0 +1,215 @@
/* ----------------------------------------------------------------------- */
#if TEST == 1
{
struct M P A __s
{
unsigned x : 12;
unsigned char y : 7;
unsigned z : 28;
unsigned a: 4;
unsigned b: 5;
};
TEST_STRUCT(0x333,0x44,0x555555,6,7);
}
/* ----------------------------------------------------------------------- */
#elif TEST == 2
{
struct M P __s
{
int x: 12;
char y: 6;
long long z:63;
A char a:4;
long long b:2;
};
TEST_STRUCT(3,30,0x123456789abcdef0LL,5,2);
}
/* ----------------------------------------------------------------------- */
#elif TEST == 3
{
struct M P __s
{
unsigned x:5, y:5, :0, z:5; char a:5; A short b:5;
};
TEST_STRUCT(21,23,25,6,14);
}
/* ----------------------------------------------------------------------- */
#elif TEST == 4
{
struct M P __s {
int x : 3;
int : 2;
int y : 1;
int : 0;
int z : 5;
int a : 7;
unsigned int b : 7;
};
TEST_STRUCT(3,1,15,120,120);
}
/* ----------------------------------------------------------------------- */
#elif TEST == 5
{
struct M P __s {
long long x : 45;
long long : 2;
long long y : 35;
unsigned long long z : 38;
char a; short b;
};
TEST_STRUCT(0x123456789ULL, 120<<25, 120, 0x44, 0x77);
}
/* ----------------------------------------------------------------------- */
#elif TEST == 6
{
struct M P __s {
int a;
char b;
int x : 12, y : 4, : 0, : 4, z : 3;
char d;
};
TEST_STRUCT(1,2,3,4,-3);
}
/* ----------------------------------------------------------------------- */
#elif defined PACK
#if PACK
# pragma pack(push,1)
# define P //_P
#else
# define P
#endif
#define TEST 1
#include SELF
#define TEST 2
#include SELF
#define TEST 3
#include SELF
#define TEST 4
#include SELF
#define TEST 5
#include SELF
#define TEST 6
#include SELF
printf("\n\n");
#if PACK
# pragma pack(pop)
#endif
#undef P
#undef PACK
/* ----------------------------------------------------------------------- */
#elif defined ALIGN
#if ALIGN
# define A _A(16)
#else
# define A
#endif
#define PACK 0
#include SELF
#define PACK 1
#include SELF
#undef A
#undef ALIGN
/* ----------------------------------------------------------------------- */
#elif defined MS_BF
#if MS_BF
# ifdef __TINYC__
# pragma comment(option, "-mms-bitfields")
# elif defined __GNUC__
# define M __attribute__((ms_struct))
# endif
#else
# ifdef __TINYC__
# pragma comment(option, "-mno-ms-bitfields")
# elif defined __GNUC__
# define M __attribute__((gcc_struct))
# endif
#endif
#ifndef M
# define M
#endif
#define ALIGN 0
#include SELF
#define ALIGN 1
#include SELF
#undef M
#undef MS_BF
/* ----------------------------------------------------------------------- */
#else
#include <stdio.h>
#include <string.h>
/* some gcc headers #define __attribute__ to empty if it's not gcc */
#undef __attribute__
void dump(void *p, int s)
{
int i;
for (i = s; --i >= 0;)
printf("%02X", ((unsigned char*)p)[i]);
printf("\n");
}
#define pv(m) \
printf(sizeof (s->m + 0) == 8 ? " %016llx" : " %02x", s->m)
#define TEST_STRUCT(v1,v2,v3,v4,v5) { \
struct __s _s, *s = & _s; \
printf("---- TEST %d%s%s%s ----\n", \
TEST, MS_BF?" - MS-BITFIELDS":"", \
PACK?" - PACKED":"", \
ALIGN?" - WITH ALIGN":""); \
memset(s, 0, sizeof *s); \
s->x = -1, s->y = -1, s->z = -1, s->a = -1, s->b = -1; \
printf("bits in use : "), dump(s, sizeof *s); \
s->x = v1, s->y = v2, s->z = v3, s->a += v4, ++s->a, s->b = v5; \
printf("bits as set : "), dump(s, sizeof *s); \
printf("values :"), pv(x), pv(y), pv(z), pv(a), pv(b), printf("\n"); \
printf("align/size : %d %d\n\n", alignof(struct __s),sizeof(struct __s)); \
}
#ifdef _MSC_VER
# define _A(n) __declspec(align(n))
# define _P
# define alignof(x) __alignof(x)
#else
# define _A(n) __attribute__((aligned(n)))
# define _P __attribute__((packed))
# define alignof(x) __alignof__(x)
#endif
#ifndef MS_BITFIELDS
# define MS_BITFIELDS 0
#endif
#define SELF "95_bitfields.c"
int main()
{
#define MS_BF MS_BITFIELDS
#include SELF
return 0;
}
/* ----------------------------------------------------------------------- */
#endif
#undef TEST

View File

@ -0,0 +1,2 @@
#define MS_BITFIELDS 1
#include "95_bitfields.c"

View File

@ -0,0 +1,152 @@
---- TEST 1 - MS-BITFIELDS ----
bits in use : 0000001FFFFFFFFF0000007F00000FFF
bits as set : 00000007605555550000004400000333
values : 333 44 555555 06 07
align/size : 4 16
---- TEST 2 - MS-BITFIELDS ----
bits in use : 0000000000000003000000000000000F7FFFFFFFFFFFFFFF0000003F00000FFF
bits as set : 00000000000000020000000000000005123456789ABCDEF00000001E00000003
values : 03 1e 123456789abcdef0 05 fffffffffffffffe
align/size : 8 32
---- TEST 3 - MS-BITFIELDS ----
bits in use : 001F001F0000001F000003FF
bits as set : 000E000600000019000002F5
values : 15 17 19 06 0e
align/size : 4 12
---- TEST 4 - MS-BITFIELDS ----
bits in use : 0007FFFF00000027
bits as set : 00078F0F00000023
values : 03 ffffffff 0f fffffff8 78
align/size : 4 8
---- TEST 5 - MS-BITFIELDS ----
bits in use : 00000000FFFF00FF0000003FFFFFFFFF00000007FFFFFFFF00001FFFFFFFFFFF
bits as set : 0000000000770044000000000000007800000007F00000000000000123456789
values : 0000000123456789 fffffffff0000000 0000000000000078 44 77
align/size : 8 32
---- TEST 6 - MS-BITFIELDS ----
bits in use : 00000000000000700000FFFF000000FFFFFFFFFF
bits as set : 000000000000003000002001000000FD00000004
values : 01 02 03 04 fffffffd
align/size : 4 20
---- TEST 1 - MS-BITFIELDS - PACKED ----
bits in use : 0000001FFFFFFFFF7F00000FFF
bits as set : 00000007605555554400000333
values : 333 44 555555 06 07
align/size : 1 13
---- TEST 2 - MS-BITFIELDS - PACKED ----
bits in use : 00000000000000030F7FFFFFFFFFFFFFFF3F00000FFF
bits as set : 000000000000000205123456789ABCDEF01E00000003
values : 03 1e 123456789abcdef0 05 fffffffffffffffe
align/size : 1 22
---- TEST 3 - MS-BITFIELDS - PACKED ----
bits in use : 001F1F0000001F000003FF
bits as set : 000E0600000019000002F5
values : 15 17 19 06 0e
align/size : 1 11
---- TEST 4 - MS-BITFIELDS - PACKED ----
bits in use : 0007FFFF00000027
bits as set : 00078F0F00000023
values : 03 ffffffff 0f fffffff8 78
align/size : 1 8
---- TEST 5 - MS-BITFIELDS - PACKED ----
bits in use : FFFFFF0000003FFFFFFFFF00000007FFFFFFFF00001FFFFFFFFFFF
bits as set : 007744000000000000007800000007F00000000000000123456789
values : 0000000123456789 fffffffff0000000 0000000000000078 44 77
align/size : 1 27
---- TEST 6 - MS-BITFIELDS - PACKED ----
bits in use : 00000000700000FFFFFFFFFFFFFF
bits as set : 000000003000002001FD00000004
values : 01 02 03 04 fffffffd
align/size : 1 14
---- TEST 1 - MS-BITFIELDS - WITH ALIGN ----
bits in use : 0000001FFFFFFFFF0000007F00000FFF
bits as set : 00000007605555550000004400000333
values : 333 44 555555 06 07
align/size : 16 16
---- TEST 2 - MS-BITFIELDS - WITH ALIGN ----
bits in use : 0000000000000003000000000000000F7FFFFFFFFFFFFFFF0000003F00000FFF
bits as set : 00000000000000020000000000000005123456789ABCDEF00000001E00000003
values : 03 1e 123456789abcdef0 05 fffffffffffffffe
align/size : 16 32
---- TEST 3 - MS-BITFIELDS - WITH ALIGN ----
bits in use : 0000000000000000000000000000001F000000000000001F0000001F000003FF
bits as set : 0000000000000000000000000000000E000000000000000600000019000002F5
values : 15 17 19 06 0e
align/size : 16 32
---- TEST 4 - MS-BITFIELDS - WITH ALIGN ----
bits in use : 0007FFFF00000027
bits as set : 00078F0F00000023
values : 03 ffffffff 0f fffffff8 78
align/size : 4 8
---- TEST 5 - MS-BITFIELDS - WITH ALIGN ----
bits in use : 00000000FFFF00FF0000003FFFFFFFFF00000007FFFFFFFF00001FFFFFFFFFFF
bits as set : 0000000000770044000000000000007800000007F00000000000000123456789
values : 0000000123456789 fffffffff0000000 0000000000000078 44 77
align/size : 8 32
---- TEST 6 - MS-BITFIELDS - WITH ALIGN ----
bits in use : 00000000000000700000FFFF000000FFFFFFFFFF
bits as set : 000000000000003000002001000000FD00000004
values : 01 02 03 04 fffffffd
align/size : 4 20
---- TEST 1 - MS-BITFIELDS - PACKED - WITH ALIGN ----
bits in use : 0000000000001FFFFFFFFF7F00000FFF
bits as set : 00000000000007605555554400000333
values : 333 44 555555 06 07
align/size : 16 16
---- TEST 2 - MS-BITFIELDS - PACKED - WITH ALIGN ----
bits in use : 00000000000000030F0000007FFFFFFFFFFFFFFF3F00000FFF
bits as set : 000000000000000205000000123456789ABCDEF01E00000003
values : 03 1e 123456789abcdef0 05 fffffffffffffffe
align/size : 16 25
---- TEST 3 - MS-BITFIELDS - PACKED - WITH ALIGN ----
bits in use : 001F000000000000001F0000001F000003FF
bits as set : 000E000000000000000600000019000002F5
values : 15 17 19 06 0e
align/size : 16 18
---- TEST 4 - MS-BITFIELDS - PACKED - WITH ALIGN ----
bits in use : 0007FFFF00000027
bits as set : 00078F0F00000023
values : 03 ffffffff 0f fffffff8 78
align/size : 1 8
---- TEST 5 - MS-BITFIELDS - PACKED - WITH ALIGN ----
bits in use : FFFFFF0000003FFFFFFFFF00000007FFFFFFFF00001FFFFFFFFFFF
bits as set : 007744000000000000007800000007F00000000000000123456789
values : 0000000123456789 fffffffff0000000 0000000000000078 44 77
align/size : 1 27
---- TEST 6 - MS-BITFIELDS - PACKED - WITH ALIGN ----
bits in use : 00000000700000FFFFFFFFFFFFFF
bits as set : 000000003000002001FD00000004
values : 01 02 03 04 fffffffd
align/size : 1 14

View File

@ -18,6 +18,9 @@ NORUN =
FLAGS = FLAGS =
76_dollars_in_identifiers.test : FLAGS += -fdollars-in-identifiers 76_dollars_in_identifiers.test : FLAGS += -fdollars-in-identifiers
# Always generate certain .expects (don't put these in the GIT),
GEN-ALWAYS = 95_bitfields.expect
# Filter source directory in warnings/errors (out-of-tree builds) # Filter source directory in warnings/errors (out-of-tree builds)
FILTER = 2>&1 | sed 's,$(SRC)/,,g' FILTER = 2>&1 | sed 's,$(SRC)/,,g'
# Filter some always-warning # Filter some always-warning
@ -40,26 +43,55 @@ endif
ifeq (,$(filter i386 x86_64,$(ARCH))) ifeq (,$(filter i386 x86_64,$(ARCH)))
SKIP += 85_asm-outside-function.test SKIP += 85_asm-outside-function.test
endif endif
ifeq (-$(findstring gcc,$(CC)-)-,--)
SKIP += $(patsubst %.expect,%.test,$(GEN-ALWAYS))
endif
ifeq (-$(CONFIG_WIN32)-$(CONFIG_i386)$(CONFIG_arm)-,--yes-)
SKIP += 95_bitfields_ms.test # type_align is differnt on 32bit-non-windows
endif
all test: $(filter-out $(SKIP),$(TESTS)) all test tests2.all: $(filter-out $(SKIP),$(TESTS)) ;
%.test: %.c %.expect %.test: %.c %.expect
@echo Test: $*... @echo Test: $*...
# test -run @$(if $(NORUN),\
@if test -z "$(NORUN)"; then \ ($(TCC) $(FLAGS) $< -o a.exe && ./a.exe $(ARGS)),\
$(TCC) $(FLAGS) -run $< $(ARGS) $(FILTER) >$*.output 2>&1 || true; \ $(TCC) $(FLAGS) -run $< $(ARGS)\
else \ ) $(FILTER) >$*.output 2>&1 || true
$(TCC) $(FLAGS) $< -o ./$*.exe $(FILTER) >$*.output 2>&1; \ @diff -Nbu $(filter %.expect,$^) $*.output \
./$*.exe $(ARGS) >>$*.output 2>&1 || true; \ && rm -f $*.output $(filter $*.expect,$(GEN-ALWAYS))
fi
@diff -Nbu $(SRC)/$*.expect $*.output && rm -f $*.output $*.exe F1 = $(or $(filter $1_%,$(TESTS)),$1_???.test)
F2 = $1 UPDATE="$(patsubst %.test,%.expect,$1)"
# run single test and update .expect file, e.g. "make tests2.37+"
tests2.%+:
@$(MAKE) $(call F2,$(call F1,$*)) --no-print-directory
# run single test, e.g. "make tests2.37"
tests2.%:
@$(MAKE) $(call F1,$*) --no-print-directory
# automatically generate .expect files with gcc: # automatically generate .expect files with gcc:
%.expect : # %.c %.expect :
(gcc -w $*.c -o a.exe && ./a.exe $(ARGS)) $(FILTER) >$*.expect 2>&1; rm -f a.exe @echo Generating: $@
@$(CC) -w -std=gnu99 $(FLAGS) $(SRC)/$*.c -o a.exe
@./a.exe $(ARGS) $(FILTER) >$@ 2>&1
@rm -f a.exe
# using the ms compiler for the really ms-compatible bitfields
MS-CC = cl
95_bitfields_ms.expect :
@echo Generating: $@
@$(MS-CC) $(basename $@).c
@./$(basename $@).exe >$@ 2>&1
@rm -f *.exe *.obj *.pdb
# tell make not to delete # tell make not to delete
.PRECIOUS: %.expect .PRECIOUS: %.expect
$(sort $(GEN-ALWAYS) $(UPDATE)) : force
force:
clean: clean:
rm -f fred.txt *.output a.exe rm -f fred.txt *.output a.exe $(GEN-ALWAYS)