/* * TCC auto test program */ /* Unfortunately, gcc version < 3 does not handle that! */ //#define ALL_ISOC99 /* only gcc 3 handles _Bool correctly */ //#define BOOL_ISOC99 #define C99_MACROS /* test various include syntaxes */ #define TCCLIB_INC #define TCCLIB_INC1 #define TCCLIB_INC3 "tcclib" #include TCCLIB_INC #include TCCLIB_INC1.TCCLIB_INC2 #include TCCLIB_INC1.h> #include TCCLIB_INC3 ".h" #include #include "tcclib.h" void string_test(); void expr_test(); void macro_test(); void scope_test(); void forward_test(); void funcptr_test(); void loop_test(); void switch_test(); void goto_test(); void enum_test(); void typedef_test(); void struct_test(); void array_test(); void expr_ptr_test(); void bool_test(); void expr2_test(); void constant_expr_test(); void expr_cmp_test(); void char_short_test(); void init_test(void); void compound_literal_test(void); int kr_test(); void struct_assign_test(void); void cast_test(void); void bitfield_test(void); void c99_bool_test(void); void float_test(void); void longlong_test(void); void stdarg_test(void); void whitespace_test(void); void relocation_test(void); int fib(int n); void num(int n); void forward_ref(void); int isid(int c); #define A 2 #define N 1234 + A #define pf printf #define M1(a, b) (a) + (b) #define str(s) # s #define glue(a, b) a ## b #define xglue(a, b) glue(a, b) #define HIGHLOW "hello" #define LOW LOW ", world" #define min(a, b) ((a) < (b) ? (a) : (b)) #ifdef C99_MACROS #define dprintf(level,...) printf(__VA_ARGS__) #endif /* gcc vararg macros */ #define dprintf1(level, fmt, args...) printf(fmt, ## args) #define MACRO_NOARGS() #define AAA 3 #undef AAA #define AAA 4 #if 1 #define B3 1 #elif 1 #define B3 2 #elif 0 #define B3 3 #else #define B3 4 #endif void macro_test() { printf("macro:\n"); pf("N=%d\n", N); printf("aaa=%d\n", AAA); printf("min=%d\n", min(1, min(2, -1))); printf("s1=%s\n", glue(HIGH, LOW)); printf("s2=%s\n", xglue(HIGH, LOW)); printf("s3=%s\n", str("c")); printf("s4=%s\n", str(a1)); printf("B3=%d\n", B3); #ifdef A printf("A defined\n"); #endif #ifdef B printf("B defined\n"); #endif #ifdef A printf("A defined\n"); #else printf("A not defined\n"); #endif #ifdef B printf("B defined\n"); #else printf("B not defined\n"); #endif #ifdef A printf("A defined\n"); #ifdef B printf("B1 defined\n"); #else printf("B1 not defined\n"); #endif #else printf("A not defined\n"); #ifdef B printf("B2 defined\n"); #else printf("B2 not defined\n"); #endif #endif #if 1+1 printf("test true1\n"); #endif #if 0 printf("test true2\n"); #endif #if 1-1 printf("test true3\n"); #endif #if defined(A) printf("test trueA\n"); #endif #if defined(B) printf("test trueB\n"); #endif #if 0 printf("test 0\n"); #elif 0 printf("test 1\n"); #elif 2 printf("test 2\n"); #else printf("test 3\n"); #endif MACRO_NOARGS(); #ifdef __LINE__ printf("__LINE__ defined\n"); #endif printf("__LINE__=%d __FILE__=%s\n", __LINE__, __FILE__); #line 200 printf("__LINE__=%d __FILE__=%s\n", __LINE__, __FILE__); #line 203 "test" printf("__LINE__=%d __FILE__=%s\n", __LINE__, __FILE__); #line 185 "tcctest.c" /* not strictly preprocessor, but we test it there */ #ifdef C99_MACROS printf("__func__ = %s\n", __func__); dprintf(1, "vaarg=%d\n", 1); #endif dprintf1(1, "vaarg1\n"); dprintf1(1, "vaarg1=%d\n", 2); dprintf1(1, "vaarg1=%d %d\n", 1, 2); /* gcc extension */ printf("func='%s'\n", __FUNCTION__); } int op(a,b) { return a / b; } int ret(a) { if (a == 2) return 1; if (a == 3) return 2; return 0; } void ps(char *s) { int c; while (1) { c = *s; if (c == 0) break; printf("%c", c); s++; } } void string_test() { int b; printf("string:\n"); printf("\141\1423\143\n");/* dezdez test */ printf("\x41\x42\x43\x3a\n"); printf("c=%c\n", 'r'); printf("wc=%C 0x%lx %C\n", L'a', L'\x1234', L'c'); printf("wstring=%S\n", L"abc"); printf("wstring=%S\n", L"abc" L"def" "ghi"); printf("'\\377'=%d '\\xff'=%d\n", '\377', '\xff'); printf("L'\\377'=%d L'\\xff'=%d\n", L'\377', L'\xff'); ps("test\n"); b = 32; while ((b = b + 1) < 96) { printf("%c", b); } printf("\n"); printf("fib=%d\n", fib(33)); b = 262144; while (b != 0x80000000) { num(b); b = b * 2; } } void loop_test() { int i; i = 0; while (i < 10) printf("%d", i++); printf("\n"); for(i = 0; i < 10;i++) printf("%d", i); printf("\n"); i = 0; do { printf("%d", i++); } while (i < 10); printf("\n"); /* break/continue tests */ i = 0; while (1) { if (i == 6) break; i++; if (i == 3) continue; printf("%d", i); } printf("\n"); /* break/continue tests */ i = 0; do { if (i == 6) break; i++; if (i == 3) continue; printf("%d", i); } while(1); printf("\n"); for(i = 0;i < 10;i++) { if (i == 3) continue; printf("%d", i); } printf("\n"); } void goto_test() { int i; printf("goto:\n"); i = 0; s_loop: if (i >= 10) goto s_end; printf("%d", i); i++; goto s_loop; s_end: printf("\n"); } enum { E0, E1 = 2, E2 = 4, E3, E4, }; enum test { E5 = 1000, }; void enum_test() { enum test b1; printf("enum:\n%d %d %d %d %d %d\n", E0, E1, E2, E3, E4, E5); b1 = 1; printf("b1=%d\n", b1); } typedef int *my_ptr; void typedef_test() { my_ptr a; int b; a = &b; *a = 1234; printf("typedef:\n"); printf("a=%d\n", *a); } void forward_test() { printf("forward:\n"); forward_ref(); forward_ref(); } void forward_ref(void) { printf("forward ok\n"); } typedef struct struct1 { int f1; int f2, f3; union union1 { int v1; int v2; } u; char str[3]; } struct1; struct struct2 { int a; char b; }; union union2 { int w1; int w2; }; struct struct1 st1, st2; int main(int argc, char **argv) { string_test(); expr_test(); macro_test(); scope_test(); forward_test(); funcptr_test(); loop_test(); switch_test(); goto_test(); enum_test(); typedef_test(); struct_test(); array_test(); expr_ptr_test(); bool_test(); expr2_test(); constant_expr_test(); expr_cmp_test(); char_short_test(); init_test(); compound_literal_test(); kr_test(); struct_assign_test(); cast_test(); bitfield_test(); c99_bool_test(); float_test(); longlong_test(); stdarg_test(); whitespace_test(); relocation_test(); return 0; } int tab[3]; int tab2[3][2]; int g; void f1(g) { printf("g1=%d\n", g); } void scope_test() { printf("scope:\n"); g = 2; f1(1); printf("g2=%d\n", g); { int g; g = 3; printf("g3=%d\n", g); { int g; g = 4; printf("g4=%d\n", g); } } printf("g5=%d\n", g); } void array_test(int a[4]) { int i, j; printf("array:\n"); printf("sizeof(a) = %d\n", sizeof(a)); printf("sizeof(int) = %d\n", sizeof(int)); printf("sizeof(unsigned int) = %d\n", sizeof(unsigned int)); printf("sizeof(short) = %d\n", sizeof(short)); printf("sizeof(unsigned short) = %d\n", sizeof(unsigned short)); printf("sizeof(char) = %d\n", sizeof(char)); printf("sizeof(unsigned char) = %d\n", sizeof(unsigned char)); printf("sizeof(\"a\") = %d\n", sizeof("a")); #ifdef C99_MACROS printf("sizeof(__func__) = %d\n", sizeof(__func__)); #endif printf("sizeof tab %d\n", sizeof(tab)); printf("sizeof tab2 %d\n", sizeof tab2); tab[0] = 1; tab[1] = 2; tab[2] = 3; printf("%d %d %d\n", tab[0], tab[1], tab[2]); for(i=0;i<3;i++) for(j=0;j<2;j++) tab2[i][j] = 10 * i + j; for(i=0;i<3*2;i++) { printf(" %3d", ((int *)tab2)[i]); } printf("\n"); } void expr_test() { int a, b; a = 0; printf("%d\n", a += 1); printf("%d\n", a -= 2); printf("%d\n", a *= 31232132); printf("%d\n", a /= 4); printf("%d\n", a %= 20); printf("%d\n", a &= 6); printf("%d\n", a ^= 7); printf("%d\n", a |= 8); printf("%d\n", a >>= 3); printf("%d\n", a <<= 4); a = 22321; b = -22321; printf("%d\n", a + 1); printf("%d\n", a - 2); printf("%d\n", a * 312); printf("%d\n", a / 4); printf("%d\n", b / 4); printf("%d\n", (unsigned)b / 4); printf("%d\n", a % 20); printf("%d\n", b % 20); printf("%d\n", (unsigned)b % 20); printf("%d\n", a & 6); printf("%d\n", a ^ 7); printf("%d\n", a | 8); printf("%d\n", a >> 3); printf("%d\n", b >> 3); printf("%d\n", (unsigned)b >> 3); printf("%d\n", a << 4); printf("%d\n", ~a); printf("%d\n", -a); printf("%d\n", +a); printf("%d\n", 12 + 1); printf("%d\n", 12 - 2); printf("%d\n", 12 * 312); printf("%d\n", 12 / 4); printf("%d\n", 12 % 20); printf("%d\n", 12 & 6); printf("%d\n", 12 ^ 7); printf("%d\n", 12 | 8); printf("%d\n", 12 >> 2); printf("%d\n", 12 << 4); printf("%d\n", ~12); printf("%d\n", -12); printf("%d\n", +12); printf("%d %d %d %d\n", isid('a'), isid('g'), isid('T'), isid('(')); } int isid(int c) { return (c >= 'a' & c <= 'z') | (c >= 'A' & c <= 'Z') | c == '_'; } /**********************/ int vstack[10], *vstack_ptr; void vpush(int vt, int vc) { *vstack_ptr++ = vt; *vstack_ptr++ = vc; } void vpop(int *ft, int *fc) { *fc = *--vstack_ptr; *ft = *--vstack_ptr; } void expr2_test() { int a, b; printf("expr2:\n"); vstack_ptr = vstack; vpush(1432432, 2); vstack_ptr[-2] &= ~0xffffff80; vpop(&a, &b); printf("res= %d %d\n", a, b); } void constant_expr_test() { int a; printf("constant_expr:\n"); a = 3; printf("%d\n", a * 16); printf("%d\n", a * 1); printf("%d\n", a + 0); } int tab4[10]; void expr_ptr_test() { int *p, *q; printf("expr_ptr:\n"); p = tab4; q = tab4 + 10; printf("diff=%d\n", q - p); p++; printf("inc=%d\n", p - tab4); p--; printf("dec=%d\n", p - tab4); ++p; printf("inc=%d\n", p - tab4); --p; printf("dec=%d\n", p - tab4); printf("add=%d\n", p + 3 - tab4); printf("add=%d\n", 3 + p - tab4); } void expr_cmp_test() { int a, b; printf("constant_expr:\n"); a = -1; b = 1; printf("%d\n", a == a); printf("%d\n", a != a); printf("%d\n", a < b); printf("%d\n", a <= b); printf("%d\n", a <= a); printf("%d\n", b >= a); printf("%d\n", a >= a); printf("%d\n", b > a); printf("%d\n", (unsigned)a < b); printf("%d\n", (unsigned)a <= b); printf("%d\n", (unsigned)a <= a); printf("%d\n", (unsigned)b >= a); printf("%d\n", (unsigned)a >= a); printf("%d\n", (unsigned)b > a); } void struct_test() { struct1 *s; union union2 u; printf("struct:\n"); printf("sizes: %d %d %d %d\n", sizeof(struct struct1), sizeof(struct struct2), sizeof(union union1), sizeof(union union2)); st1.f1 = 1; st1.f2 = 2; st1.f3 = 3; printf("st1: %d %d %d\n", st1.f1, st1.f2, st1.f3); st1.u.v1 = 1; st1.u.v2 = 2; printf("union1: %d\n", st1.u.v1); u.w1 = 1; u.w2 = 2; printf("union2: %d\n", u.w1); s = &st2; s->f1 = 3; s->f2 = 2; s->f3 = 1; printf("st2: %d %d %d\n", s->f1, s->f2, s->f3); printf("str_addr=%x\n", (int)st1.str - (int)&st1.f1); } /* XXX: depend on endianness */ void char_short_test() { int var1, var2; printf("char_short:\n"); var1 = 0x01020304; var2 = 0xfffefdfc; printf("s8=%d %d\n", *(char *)&var1, *(char *)&var2); printf("u8=%d %d\n", *(unsigned char *)&var1, *(unsigned char *)&var2); printf("s16=%d %d\n", *(short *)&var1, *(short *)&var2); printf("u16=%d %d\n", *(unsigned short *)&var1, *(unsigned short *)&var2); printf("s32=%d %d\n", *(int *)&var1, *(int *)&var2); printf("u32=%d %d\n", *(unsigned int *)&var1, *(unsigned int *)&var2); *(char *)&var1 = 0x08; printf("var1=%x\n", var1); *(short *)&var1 = 0x0809; printf("var1=%x\n", var1); *(int *)&var1 = 0x08090a0b; printf("var1=%x\n", var1); } /******************/ typedef struct Sym { int v; int t; int c; struct Sym *next; struct Sym *prev; } Sym; void bool_test() { int *s, a, b, t, f; a = 0; s = (void*)0; printf("!s=%d\n", !s); if (!s || !s[0]) a = 1; printf("a=%d\n", a); printf("a=%d %d %d\n", 0 || 0, 0 || 1, 1 || 1); printf("a=%d %d %d\n", 0 && 0, 0 && 1, 1 && 1); printf("a=%d %d\n", 1 ? 1 : 0, 0 ? 1 : 0); #if 1 && 1 printf("a1\n"); #endif #if 1 || 0 printf("a2\n"); #endif #if 1 ? 0 : 1 printf("a3\n"); #endif #if 0 ? 0 : 1 printf("a4\n"); #endif a = 4; printf("b=%d\n", a + (0 ? 1 : a / 2)); /* test register spilling */ a = 10; b = 10; a = (a + b) * ((a < b) ? ((b - a) * (a - b)): a + b); printf("a=%d\n", a); /* test complex || or && expressions */ t = 1; f = 0; a = 32; printf("exp=%d\n", f == (32 <= a && a <= 3)); printf("r=%d\n", (t || f) + (t && f)); /* test ? : cast */ { int aspect_on; int aspect_native = 65536; double bfu_aspect = 1.0; int aspect; for(aspect_on = 0; aspect_on < 2; aspect_on++) { aspect=aspect_on?(aspect_native*bfu_aspect+0.5):65535UL; printf("aspect=%d\n", aspect); } } } int cinit1 = 0; int *cinit2 = (int []){3, 2, 1}; void compound_literal_test(void) { int *p, i; char *q, *q3; printf("compound_test:\n"); p = (int []){1, 2, 3}; for(i=0;i<3;i++) printf(" %d", p[i]); printf("\n"); for(i=0;i<3;i++) printf("%d", cinit2[i]); printf("\n"); q = "tralala1"; printf("q1=%s\n", q); q = (char *){ "tralala2" }; printf("q2=%s\n", q); q3 = (char *){ q }; printf("q3=%s\n", q3); q = (char []){ "tralala3" }; printf("q4=%s\n", q); #ifdef ALL_ISOC99 p = (int []){1, 2, cinit1 + 3}; for(i=0;i<3;i++) printf(" %d", p[i]); printf("\n"); for(i=0;i<3;i++) { p = (int []){1, 2, 4 + i}; printf("%d %d %d\n", p[0], p[1], p[2]); } #endif } /* K & R protos */ kr_func1(a, b) { return a + b; } int kr_func2(a, b) { return a + b; } kr_test() { printf("kr_test:\n"); printf("func1=%d\n", kr_func1(3, 4)); printf("func2=%d\n", kr_func2(3, 4)); return 0; } void num(int n) { char *tab, *p; tab = (char*)malloc(20); p = tab; while (1) { *p = 48 + (n % 10); p++; n = n / 10; if (n == 0) break; } while (p != tab) { p--; printf("%c", *p); } printf("\n"); } /* structure assignment tests */ struct structa1 { int f1; char f2; }; struct structa1 ssta1; void struct_assign_test1(struct structa1 s1, int t) { printf("%d %d %d\n", s1.f1, s1.f2, t); } struct structa1 struct_assign_test2(struct structa1 s1, int t) { s1.f1 += t; s1.f2 -= t; return s1; } void struct_assign_test(void) { struct structa1 lsta1, lsta2; #if 0 printf("struct_assign_test:\n"); lsta1.f1 = 1; lsta1.f2 = 2; printf("%d %d\n", lsta1.f1, lsta1.f2); lsta2 = lsta1; printf("%d %d\n", lsta2.f1, lsta2.f2); #else lsta2.f1 = 1; lsta2.f2 = 2; #endif struct_assign_test1(lsta2, 3); printf("before call: %d %d\n", lsta2.f1, lsta2.f2); lsta2 = struct_assign_test2(lsta2, 4); printf("after call: %d %d\n", lsta2.f1, lsta2.f2); } /* casts to short/char */ void cast1(char a, short b, unsigned char c, unsigned short d) { printf("%d %d %d %d\n", a, b, c, d); } char bcast; short scast; void cast_test() { int a; char c; char tab[10]; printf("cast_test:\n"); a = 0xfffff; cast1(a, a, a, a); a = 0xffffe; printf("%d %d %d %d\n", (char)(a + 1), (short)(a + 1), (unsigned char)(a + 1), (unsigned short)(a + 1)); printf("%d %d %d %d\n", (char)0xfffff, (short)0xfffff, (unsigned char)0xfffff, (unsigned short)0xfffff); a = (bcast = 128) + 1; printf("%d\n", a); a = (scast = 65536) + 1; printf("%d\n", a); printf("sizeof(c) = %d, sizeof((int)c) = %d\n", sizeof(c), sizeof((int)c)); /* test implicit int casting for array accesses */ c = 0; tab[1] = 2; tab[c] = 1; printf("%d %d\n", tab[0], tab[1]); /* test implicit casting on some operators */ printf("sizeof(+(char)'a') = %d\n", sizeof(+(char)'a')); printf("sizeof(-(char)'a') = %d\n", sizeof(-(char)'a')); printf("sizeof(~(char)'a') = %d\n", sizeof(-(char)'a')); } /* initializers tests */ struct structinit1 { int f1; char f2; short f3; int farray[3]; }; int sinit1 = 2; int sinit2 = { 3 }; int sinit3[3] = { 1, 2, {{3}}, }; int sinit4[3][2] = { {1, 2}, {3, 4}, {5, 6} }; int sinit5[3][2] = { 1, 2, 3, 4, 5, 6 }; int sinit6[] = { 1, 2, 3 }; int sinit7[] = { [2] = 3, [0] = 1, 2 }; char sinit8[] = "hello" "trala"; struct structinit1 sinit9 = { 1, 2, 3 }; struct structinit1 sinit10 = { .f2 = 2, 3, .f1 = 1 }; struct structinit1 sinit11 = { .f2 = 2, 3, .f1 = 1, #ifdef ALL_ISOC99 .farray[0] = 10, .farray[1] = 11, .farray[2] = 12, #endif }; char *sinit12 = "hello world"; char *sinit13[] = { "test1", "test2", "test3", }; char sinit14[10] = { "abc" }; int sinit15[3] = { sizeof(sinit15), 1, 2 }; void init_test(void) { int linit1 = 2; int linit2 = { 3 }; int linit4[3][2] = { {1, 2}, {3, 4}, {5, 6} }; int linit6[] = { 1, 2, 3 }; int i, j; char linit8[] = "hello" "trala"; int linit12[10] = { 1, 2 }; int linit13[10] = { 1, 2, [7] = 3, [3] = 4, }; char linit14[10] = "abc"; int linit15[10] = { linit1, linit1 + 1, [6] = linit1 + 2, }; struct linit16 { int a1, a2, a3, a4; } linit16 = { 1, .a3 = 2 }; int linit17 = sizeof(linit17); printf("init_test:\n"); printf("sinit1=%d\n", sinit1); printf("sinit2=%d\n", sinit2); printf("sinit3=%d %d %d %d\n", sizeof(sinit3), sinit3[0], sinit3[1], sinit3[2] ); printf("sinit6=%d\n", sizeof(sinit6)); printf("sinit7=%d %d %d %d\n", sizeof(sinit7), sinit7[0], sinit7[1], sinit7[2] ); printf("sinit8=%s\n", sinit8); printf("sinit9=%d %d %d\n", sinit9.f1, sinit9.f2, sinit9.f3 ); printf("sinit10=%d %d %d\n", sinit10.f1, sinit10.f2, sinit10.f3 ); printf("sinit11=%d %d %d %d %d %d\n", sinit11.f1, sinit11.f2, sinit11.f3, sinit11.farray[0], sinit11.farray[1], sinit11.farray[2] ); for(i=0;i<3;i++) for(j=0;j<2;j++) printf("[%d][%d] = %d %d %d\n", i, j, sinit4[i][j], sinit5[i][j], linit4[i][j]); printf("linit1=%d\n", linit1); printf("linit2=%d\n", linit2); printf("linit6=%d\n", sizeof(linit6)); printf("linit8=%d %s\n", sizeof(linit8), linit8); printf("sinit12=%s\n", sinit12); printf("sinit13=%d %s %s %s\n", sizeof(sinit13), sinit13[0], sinit13[1], sinit13[2]); printf("sinit14=%s\n", sinit14); for(i=0;i<10;i++) printf(" %d", linit12[i]); printf("\n"); for(i=0;i<10;i++) printf(" %d", linit13[i]); printf("\n"); for(i=0;i<10;i++) printf(" %d", linit14[i]); printf("\n"); for(i=0;i<10;i++) printf(" %d", linit15[i]); printf("\n"); printf("%d %d %d %d\n", linit16.a1, linit16.a2, linit16.a3, linit16.a4); /* test that initialisation is done after variable declare */ printf("linit17=%d\n", linit17); printf("sinit15=%d\n", sinit15[0]); } void switch_test() { int i; for(i=0;i<15;i++) { switch(i) { case 0: case 1: printf("a"); break; default: printf("%d", i); break; case 8 ... 12: printf("c"); break; case 3: printf("b"); break; } } printf("\n"); } /* ISOC99 _Bool type */ void c99_bool_test(void) { #ifdef BOOL_ISOC99 int a; _Bool b; printf("bool_test:\n"); printf("sizeof(_Bool) = %d\n", sizeof(_Bool)); a = 3; printf("cast: %d %d %d\n", (_Bool)10, (_Bool)0, (_Bool)a); b = 3; printf("b = %d\n", b); b++; printf("b = %d\n", b); #endif } void bitfield_test(void) { int a; struct sbf1 { int f1 : 3; int : 2; int f2 : 1; int : 0; int f3 : 5; int f4 : 7; unsigned int f5 : 7; } st1; printf("bitfield_test:"); printf("sizeof(st1) = %d\n", sizeof(st1)); st1.f1 = 3; st1.f2 = 1; st1.f3 = 15; a = 120; st1.f4 = a; st1.f5 = a; st1.f5++; printf("%d %d %d %d %d\n", st1.f1, st1.f2, st1.f3, st1.f4, st1.f5); } #define FTEST(prefix, type, fmt)\ void prefix ## cmp(type a, type b)\ {\ printf("%d %d %d %d %d %d\n",\ a == b,\ a != b,\ a < b,\ a > b,\ a >= b,\ a <= b);\ printf(fmt " " fmt " " fmt " " fmt " " fmt " " fmt " " fmt "\n",\ a,\ b,\ a + b,\ a - b,\ a * b,\ a / b,\ -a);\ printf(fmt "\n", ++a);\ printf(fmt "\n", a++);\ printf(fmt "\n", a);\ }\ void prefix ## fcast(type a)\ {\ float fa;\ double da;\ long double la;\ int ia;\ unsigned int ua;\ type b;\ fa = a;\ da = a;\ la = a;\ printf("ftof: %f %f %Lf\n", fa, da, la);\ ia = (int)a;\ ua = (unsigned int)a;\ printf("ftoi: %d %u\n", ia, ua);\ ia = -1234;\ ua = 0x81234500;\ b = ia;\ printf("itof: " fmt "\n", b);\ b = ua;\ printf("utof: " fmt "\n", b);\ }\ \ void prefix ## test(void)\ {\ printf("testing '%s'\n", #type);\ prefix ## cmp(1, 2.5);\ prefix ## cmp(2, 1.5);\ prefix ## cmp(1, 1);\ prefix ## fcast(234.6);\ prefix ## fcast(-2334.6);\ } FTEST(f, float, "%f") FTEST(d, double, "%f") FTEST(ld, long double, "%Lf") double ftab1[3] = { 1.2, 3.4, -5.6 }; void float_test(void) { float fa, fb; double da, db; int a; unsigned int b; printf("float_test:\n"); printf("sizeof(float) = %d\n", sizeof(float)); printf("sizeof(double) = %d\n", sizeof(double)); printf("sizeof(long double) = %d\n", sizeof(long double)); ftest(); dtest(); ldtest(); printf("%f %f %f\n", ftab1[0], ftab1[1], ftab1[2]); printf("%f %f %f\n", 2.12, .5, 2.3e10); // printf("%f %f %f\n", 0x1234p12, 0x1e23.23p10, 0x12dp-10); da = 123; printf("da=%f\n", da); fa = 123; printf("fa=%f\n", fa); a = 4000000000; da = a; printf("da = %f\n", da); b = 4000000000; db = b; printf("db = %f\n", db); } int fib(int n) { if (n <= 2) return 1; else return fib(n-1) + fib(n-2); } void funcptr_test() { void (*func)(int); int a; struct { int dummy; void (*func)(int); } st1; printf("funcptr:\n"); func = # (*func)(12345); func = num; a = 1; a = 1; func(12345); /* more complicated pointer computation */ st1.func = num; st1.func(12346); printf("sizeof1 = %d\n", sizeof(funcptr_test)); printf("sizeof2 = %d\n", sizeof funcptr_test); printf("sizeof3 = %d\n", sizeof(&funcptr_test)); printf("sizeof4 = %d\n", sizeof &funcptr_test); } void lloptest(long long a, long long b) { unsigned long long ua, ub; ua = a; ub = b; /* arith */ printf("arith: %Ld %Ld %Ld %Ld %Ld\n", a + b, a - b, a * b, a / b, a % b); /* binary */ printf("bin: %Ld %Ld %Ld\n", a & b, a | b, a ^ b); /* tests */ printf("test: %d %d %d %d %d %d\n", a == b, a != b, a < b, a > b, a >= b, a <= b); printf("utest: %d %d %d %d %d %d\n", ua == ub, ua != ub, ua < ub, ua > ub, ua >= ub, ua <= ub); /* arith2 */ a++; b++; printf("arith2: %Ld %Ld\n", a, b); printf("arith2: %Ld %Ld\n", a++, b++); printf("arith2: %Ld %Ld\n", --a, --b); printf("arith2: %Ld %Ld\n", a, b); } void llshift(long long a, int b) { printf("shift: %Ld %Ld %Ld\n", (unsigned long long)a >> b, a >> b, a << b); printf("shiftc: %Ld %Ld %Ld\n", (unsigned long long)a >> 3, a >> 3, a << 3); printf("shiftc: %Ld %Ld %Ld\n", (unsigned long long)a >> 35, a >> 35, a << 35); } void llfloat(void) { float fa; double da; long double lda; long long la, lb, lc; unsigned long long ula, ulb, ulc; la = 0x12345678; ula = 0x72345678; la = (la << 20) | 0x12345; ula = ula << 33; printf("la=%Ld ula=%Lu\n", la, ula); fa = la; da = la; lda = la; printf("lltof: %f %f %Lf\n", fa, da, lda); la = fa; lb = da; lc = lda; printf("ftoll: %Ld %Ld %Ld\n", la, lb, lc); fa = ula; da = ula; lda = ula; printf("ulltof: %f %f %Lf\n", fa, da, lda); ula = fa; ulb = da; ulc = lda; printf("ftoull: %Lu %Lu %Lu\n", ula, ulb, ulc); } long long llfunc1(int a) { return a; } /* currently not supported, except for typing */ void longlong_test(void) { long long a, b, c; int ia; unsigned int ua; printf("longlong_test:\n"); printf("sizeof(long long) = %d\n", sizeof(long long)); ia = -1; ua = -2; a = ia; b = ua; printf("%Ld %Ld\n", a, b); printf("%Ld %Ld %Ld %Lx\n", (long long)1, (long long)-2, 1LL, 0x1234567812345679); a = llfunc1(-3); printf("%Ld\n", a); lloptest(1000, 23); lloptest(0xff, 0x1234); b = 0x72345678 << 10; lloptest(-3, b); llshift(0x123, 5); llshift(-23, 5); b = 0x72345678 << 10; llshift(b, 47); llfloat(); #if 1 b = 0x12345678; a = -1; c = a + b; printf("%Lx\n", c); #endif } void vprintf1(const char *fmt, ...) { va_list ap; const char *p; int c, i; double d; long long ll; va_start(ap, fmt); p = fmt; for(;;) { c = *p; if (c == '\0') break; p++; if (c == '%') { c = *p; switch(c) { case '\0': goto the_end; case 'd': i = va_arg(ap, int); printf("%d", i); break; case 'f': d = va_arg(ap, double); printf("%f", d); break; case 'l': ll = va_arg(ap, long long); printf("%Ld", ll); break; } p++; } else { putchar(c); } } the_end: va_end(ap); } void stdarg_test(void) { vprintf1("%d %d %d\n", 1, 2, 3); vprintf1("%f %d %f\n", 1.0, 2, 3.0); vprintf1("%l %l %d %f\n", 1234567891234LL, 987654321986LL, 3, 1234.0); } void whitespace_test(void) { char *str; #if 1 pri\ ntf("whitspace:\n"); #endif pf("N=%d\n", 2); pri\ ntf("aaa=%d\n", 3); pri\ \ ntf("min=%d\n", 4); printf("len1=%d\n", strlen(" ")); str = " "; printf("len1=%d str[0]=%d\n", strlen(str), str[0]); printf("len1=%d\n", strlen(" a ")); } int reltab[3] = { 1, 2, 3 }; int *rel1 = &reltab[1]; int *rel2 = &reltab[2]; void relocation_test(void) { printf("*rel1=%d\n", *rel1); printf("*rel2=%d\n", *rel2); }