I just discovered __attribute__((constructor))!
This commit is contained in:
parent
71bee24e51
commit
52846ceeac
@ -4,20 +4,18 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
typedef int (*tt_test)(void);
|
|
||||||
|
|
||||||
char *tt_filename;
|
char *tt_filename;
|
||||||
char *tt_current_test;
|
char *tt_current_test;
|
||||||
int tt_fd[2];
|
int tt_fd[2];
|
||||||
int tt_color = 1;
|
int tt_color = 1;
|
||||||
|
|
||||||
extern tt_test tt_tests[];
|
|
||||||
extern char *tt_test_names[];
|
|
||||||
|
|
||||||
#ifndef TT_BUFFER_SIZE
|
#ifndef TT_BUFFER_SIZE
|
||||||
#define TT_BUFFER_SIZE 512
|
#define TT_BUFFER_SIZE 512
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define TT_CLR_RED ((tt_color)?"\x1b[31m":"")
|
#define TT_CLR_RED ((tt_color)?"\x1b[31m":"")
|
||||||
#define TT_CLR_GRN ((tt_color)?"\x1b[32m":"")
|
#define TT_CLR_GRN ((tt_color)?"\x1b[32m":"")
|
||||||
#define TT_CLR_BLU ((tt_color)?"\x1b[34m":"")
|
#define TT_CLR_BLU ((tt_color)?"\x1b[34m":"")
|
||||||
@ -25,6 +23,7 @@ extern char *tt_test_names[];
|
|||||||
|
|
||||||
#define TT_FAIL(error, ...) dprintf(tt_fd[1], "\"%s\" Line %d: %s >> " error "\n", tt_filename, __LINE__, tt_current_test, __VA_ARGS__);
|
#define TT_FAIL(error, ...) dprintf(tt_fd[1], "\"%s\" Line %d: %s >> " error "\n", tt_filename, __LINE__, tt_current_test, __VA_ARGS__);
|
||||||
|
|
||||||
|
|
||||||
#define ASSERT_EQUAL(type, pf, lhs, rhs) do { \
|
#define ASSERT_EQUAL(type, pf, lhs, rhs) do { \
|
||||||
type tt_lhs = (type)(lhs); \
|
type tt_lhs = (type)(lhs); \
|
||||||
type tt_rhs = (type)(rhs); \
|
type tt_rhs = (type)(rhs); \
|
||||||
@ -70,11 +69,36 @@ extern char *tt_test_names[];
|
|||||||
#define ASSERT_NEQ_CHR(lhs, rhs) ASSERT_NOT_EQUAL(char, "c", lhs, rhs)
|
#define ASSERT_NEQ_CHR(lhs, rhs) ASSERT_NOT_EQUAL(char, "c", lhs, rhs)
|
||||||
#define ASSERT_EQ_STR(lhs, rhs, n) ASSERT_STRN(lhs, rhs, n)
|
#define ASSERT_EQ_STR(lhs, rhs, n) ASSERT_STRN(lhs, rhs, n)
|
||||||
|
|
||||||
#define TEST(name) int ttt_##name()
|
typedef int (*tt_test)(void);
|
||||||
|
|
||||||
|
struct tt_test
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
int (*test)(void);
|
||||||
|
};
|
||||||
|
struct tt_test *tt_tests;
|
||||||
|
|
||||||
|
int tt_test_count = 0;
|
||||||
|
|
||||||
|
#define TEST(name) \
|
||||||
|
int ttt_##name(); \
|
||||||
|
__attribute__((constructor)) void tttr_##name() { \
|
||||||
|
tt_register(#name, ttt_##name); \
|
||||||
|
} \
|
||||||
|
int ttt_##name()
|
||||||
|
|
||||||
#define BEFORE() void tt_before()
|
#define BEFORE() void tt_before()
|
||||||
#define AFTER() void tt_after()
|
#define AFTER() void tt_after()
|
||||||
|
|
||||||
|
void tt_register(char *name, int (*fn)(void))
|
||||||
|
{
|
||||||
|
tt_tests = realloc(tt_tests, (tt_test_count+1)*sizeof(struct tt_test));
|
||||||
|
tt_tests[tt_test_count].name = name;
|
||||||
|
tt_tests[tt_test_count].test = fn;
|
||||||
|
tt_test_count++;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void __attribute__((weak)) tt_before(void);
|
void __attribute__((weak)) tt_before(void);
|
||||||
void __attribute__((weak)) tt_after(void);
|
void __attribute__((weak)) tt_after(void);
|
||||||
|
|
||||||
@ -89,17 +113,18 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
int failures = 0;
|
int failures = 0;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while(tt_tests[i])
|
while(i < tt_test_count)
|
||||||
{
|
{
|
||||||
|
struct tt_test *test = &tt_tests[i];
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
pipe(tt_fd);
|
pipe(tt_fd);
|
||||||
int pid;
|
int pid;
|
||||||
|
tt_current_test = test->name;
|
||||||
if(!(pid = fork()))
|
if(!(pid = fork()))
|
||||||
{
|
{
|
||||||
close(tt_fd[0]);
|
close(tt_fd[0]);
|
||||||
tt_current_test = tt_test_names[i];
|
|
||||||
if(tt_before) tt_before();
|
if(tt_before) tt_before();
|
||||||
int result = tt_tests[i]();
|
int result = test->test();
|
||||||
if(tt_after) tt_after();
|
if(tt_after) tt_after();
|
||||||
exit(result);
|
exit(result);
|
||||||
}
|
}
|
||||||
@ -116,7 +141,7 @@ int main(int argc, char **argv)
|
|||||||
if(!WIFEXITED(status))
|
if(!WIFEXITED(status))
|
||||||
{
|
{
|
||||||
failed = 1;
|
failed = 1;
|
||||||
sprintf(buffer, "\"%s\" >> TEST %d CRASHED\n", tt_filename, i+1);
|
sprintf(buffer, "\"%s\" >> TEST %s CRASHED\n", tt_filename, tt_current_test);
|
||||||
}
|
}
|
||||||
if(failed)
|
if(failed)
|
||||||
{
|
{
|
||||||
|
14
ttest
14
ttest
@ -9,19 +9,9 @@ main()
|
|||||||
local files=`find $dir -name "*.tt"`
|
local files=`find $dir -name "*.tt"`
|
||||||
for suite in $files; do
|
for suite in $files; do
|
||||||
|
|
||||||
cp $suite $suite.c
|
|
||||||
local tests=`sed -n -e 's/^\s*TEST(\([^,]*\)).*$/ttt_\1/p' $suite`
|
|
||||||
|
|
||||||
echo "tt_test tt_tests[] = {" >> $suite.c
|
|
||||||
for t in $tests; do echo "$t," >> $suite.c; done
|
|
||||||
echo "0};" >> $suite.c
|
|
||||||
|
|
||||||
echo "char *tt_test_names[] = {" >> $suite.c
|
|
||||||
for t in $tests; do echo "\"$t\"," >> $suite.c; done
|
|
||||||
echo "\"\"};" >> $suite.c
|
|
||||||
|
|
||||||
test_exec=`mktemp /tmp/tmp.XXXXXX`
|
test_exec=`mktemp /tmp/tmp.XXXXXX`
|
||||||
compiler_output=`cc $suite.c -o $test_exec -ggdb -I $dir/include -I toolchain -DTTEST 2>&1`
|
compiler_output=`cc -x c $suite -o $test_exec -ggdb -I $dir/include -I toolchain -DTTEST 2>&1`
|
||||||
compiler_status=$?
|
compiler_status=$?
|
||||||
|
|
||||||
echo -e "\x1b[35m$suite\x1b[0m"
|
echo -e "\x1b[35m$suite\x1b[0m"
|
||||||
@ -32,7 +22,7 @@ main()
|
|||||||
echo -e "\x1b[31mCOMPILATION OF SUITE FAILED\x1b[0m"
|
echo -e "\x1b[31mCOMPILATION OF SUITE FAILED\x1b[0m"
|
||||||
echo "$compiler_output" | sed -e 's/\.tt\.c:/\.tt:/'
|
echo "$compiler_output" | sed -e 's/\.tt\.c:/\.tt:/'
|
||||||
fi
|
fi
|
||||||
rm -f $suite.c $test_exec
|
rm -f $test_exec
|
||||||
done
|
done
|
||||||
done
|
done
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user