| @@ -0,0 +1,2188 @@ |
| | 1 | /* |
| | 2 | * TCC auto test program |
| | 3 | */ |
| | 4 | #include "config.h" |
| | 5 | |
| | 6 | #if GCC_MAJOR >= 3 |
| | 7 | |
| | 8 | /* Unfortunately, gcc version < 3 does not handle that! */ |
| | 9 | #define ALL_ISOC99 |
| | 10 | |
| | 11 | /* only gcc 3 handles _Bool correctly */ |
| | 12 | #define BOOL_ISOC99 |
| | 13 | |
| | 14 | /* gcc 2.95.3 does not handle correctly CR in strings or after strays */ |
| | 15 | #define CORRECT_CR_HANDLING |
| | 16 | |
| | 17 | #endif |
| | 18 | |
| | 19 | /* deprecated and no longer supported in gcc 3.3 */ |
| | 20 | //#define ACCEPT_CR_IN_STRINGS |
| | 21 | |
| | 22 | /* __VA_ARGS__ and __func__ support */ |
| | 23 | #define C99_MACROS |
| | 24 | |
| | 25 | /* test various include syntaxes */ |
| | 26 | |
| | 27 | #define TCCLIB_INC <tcclib.h> |
| | 28 | #define TCCLIB_INC1 <tcclib |
| | 29 | #define TCCLIB_INC2 h> |
| | 30 | #define TCCLIB_INC3 "tcclib" |
| | 31 | |
| | 32 | #include TCCLIB_INC |
| | 33 | |
| | 34 | #include TCCLIB_INC1.TCCLIB_INC2 |
| | 35 | |
| | 36 | #include TCCLIB_INC1.h> |
| | 37 | |
| | 38 | /* gcc 3.2 does not accept that (bug ?) */ |
| | 39 | //#include TCCLIB_INC3 ".h" |
| | 40 | |
| | 41 | #include <tcclib.h> |
| | 42 | |
| | 43 | #include "tcclib.h" |
| | 44 | |
| | 45 | void string_test(); |
| | 46 | void expr_test(); |
| | 47 | void macro_test(); |
| | 48 | void scope_test(); |
| | 49 | void forward_test(); |
| | 50 | void funcptr_test(); |
| | 51 | void loop_test(); |
| | 52 | void switch_test(); |
| | 53 | void goto_test(); |
| | 54 | void enum_test(); |
| | 55 | void typedef_test(); |
| | 56 | void struct_test(); |
| | 57 | void array_test(); |
| | 58 | void expr_ptr_test(); |
| | 59 | void bool_test(); |
| | 60 | void expr2_test(); |
| | 61 | void constant_expr_test(); |
| | 62 | void expr_cmp_test(); |
| | 63 | void char_short_test(); |
| | 64 | void init_test(void); |
| | 65 | void compound_literal_test(void); |
| | 66 | int kr_test(); |
| | 67 | void struct_assign_test(void); |
| | 68 | void cast_test(void); |
| | 69 | void bitfield_test(void); |
| | 70 | void c99_bool_test(void); |
| | 71 | void float_test(void); |
| | 72 | void longlong_test(void); |
| | 73 | void manyarg_test(void); |
| | 74 | void stdarg_test(void); |
| | 75 | void whitespace_test(void); |
| | 76 | void relocation_test(void); |
| | 77 | void old_style_function(void); |
| | 78 | void sizeof_test(void); |
| | 79 | void typeof_test(void); |
| | 80 | void local_label_test(void); |
| | 81 | void statement_expr_test(void); |
| | 82 | void asm_test(void); |
| | 83 | void builtin_test(void); |
| | 84 | |
| | 85 | int fib(int n); |
| | 86 | void num(int n); |
| | 87 | void forward_ref(void); |
| | 88 | int isid(int c); |
| | 89 | |
| | 90 | #define A 2 |
| | 91 | #define N 1234 + A |
| | 92 | #define pf printf |
| | 93 | #define M1(a, b) (a) + (b) |
| | 94 | |
| | 95 | #define str\ |
| | 96 | (s) # s |
| | 97 | #define glue(a, b) a ## b |
| | 98 | #define xglue(a, b) glue(a, b) |
| | 99 | #define HIGHLOW "hello" |
| | 100 | #define LOW LOW ", world" |
| | 101 | |
| | 102 | #define min(a, b) ((a) < (b) ? (a) : (b)) |
| | 103 | |
| | 104 | #ifdef C99_MACROS |
| | 105 | #define dprintf(level,...) printf(__VA_ARGS__) |
| | 106 | #endif |
| | 107 | |
| | 108 | /* gcc vararg macros */ |
| | 109 | #define dprintf1(level, fmt, args...) printf(fmt, ## args) |
| | 110 | |
| | 111 | #define MACRO_NOARGS() |
| | 112 | |
| | 113 | #define AAA 3 |
| | 114 | #undef AAA |
| | 115 | #define AAA 4 |
| | 116 | |
| | 117 | #if 1 |
| | 118 | #define B3 1 |
| | 119 | #elif 1 |
| | 120 | #define B3 2 |
| | 121 | #elif 0 |
| | 122 | #define B3 3 |
| | 123 | #else |
| | 124 | #define B3 4 |
| | 125 | #endif |
| | 126 | |
| | 127 | #define __INT64_C(c) c ## LL |
| | 128 | #define INT64_MIN (-__INT64_C(9223372036854775807)-1) |
| | 129 | |
| | 130 | int qq(int x) |
| | 131 | { |
| | 132 | return x + 40; |
| | 133 | } |
| | 134 | #define qq(x) x |
| | 135 | |
| | 136 | #define spin_lock(lock) do { } while (0) |
| | 137 | #define wq_spin_lock spin_lock |
| | 138 | #define TEST2() wq_spin_lock(a) |
| | 139 | |
| | 140 | void macro_test(void) |
| | 141 | { |
| | 142 | printf("macro:\n"); |
| | 143 | pf("N=%d\n", N); |
| | 144 | printf("aaa=%d\n", AAA); |
| | 145 | |
| | 146 | printf("min=%d\n", min(1, min(2, -1))); |
| | 147 | |
| | 148 | printf("s1=%s\n", glue(HIGH, LOW)); |
| | 149 | printf("s2=%s\n", xglue(HIGH, LOW)); |
| | 150 | printf("s3=%s\n", str("c")); |
| | 151 | printf("s4=%s\n", str(a1)); |
| | 152 | printf("B3=%d\n", B3); |
| | 153 | |
| | 154 | #ifdef A |
| | 155 | printf("A defined\n"); |
| | 156 | #endif |
| | 157 | #ifdef B |
| | 158 | printf("B defined\n"); |
| | 159 | #endif |
| | 160 | #ifdef A |
| | 161 | printf("A defined\n"); |
| | 162 | #else |
| | 163 | printf("A not defined\n"); |
| | 164 | #endif |
| | 165 | #ifdef B |
| | 166 | printf("B defined\n"); |
| | 167 | #else |
| | 168 | printf("B not defined\n"); |
| | 169 | #endif |
| | 170 | |
| | 171 | #ifdef A |
| | 172 | printf("A defined\n"); |
| | 173 | #ifdef B |
| | 174 | printf("B1 defined\n"); |
| | 175 | #else |
| | 176 | printf("B1 not defined\n"); |
| | 177 | #endif |
| | 178 | #else |
| | 179 | printf("A not defined\n"); |
| | 180 | #ifdef B |
| | 181 | printf("B2 defined\n"); |
| | 182 | #else |
| | 183 | printf("B2 not defined\n"); |
| | 184 | #endif |
| | 185 | #endif |
| | 186 | |
| | 187 | #if 1+1 |
| | 188 | printf("test true1\n"); |
| | 189 | #endif |
| | 190 | #if 0 |
| | 191 | printf("test true2\n"); |
| | 192 | #endif |
| | 193 | #if 1-1 |
| | 194 | printf("test true3\n"); |
| | 195 | #endif |
| | 196 | #if defined(A) |
| | 197 | printf("test trueA\n"); |
| | 198 | #endif |
| | 199 | #if defined(B) |
| | 200 | printf("test trueB\n"); |
| | 201 | #endif |
| | 202 | |
| | 203 | #if 0 |
| | 204 | printf("test 0\n"); |
| | 205 | #elif 0 |
| | 206 | printf("test 1\n"); |
| | 207 | #elif 2 |
| | 208 | printf("test 2\n"); |
| | 209 | #else |
| | 210 | printf("test 3\n"); |
| | 211 | #endif |
| | 212 | |
| | 213 | MACRO_NOARGS(); |
| | 214 | |
| | 215 | #ifdef __LINE__ |
| | 216 | printf("__LINE__ defined\n"); |
| | 217 | #endif |
| | 218 | |
| | 219 | printf("__LINE__=%d __FILE__=%s\n", |
| | 220 | __LINE__, __FILE__); |
| | 221 | #line 200 |
| | 222 | printf("__LINE__=%d __FILE__=%s\n", |
| | 223 | __LINE__, __FILE__); |
| | 224 | #line 203 "test" |
| | 225 | printf("__LINE__=%d __FILE__=%s\n", |
| | 226 | __LINE__, __FILE__); |
| | 227 | #line 227 "tcctest.c" |
| | 228 | |
| | 229 | /* not strictly preprocessor, but we test it there */ |
| | 230 | #ifdef C99_MACROS |
| | 231 | printf("__func__ = %s\n", __func__); |
| | 232 | dprintf(1, "vaarg=%d\n", 1); |
| | 233 | #endif |
| | 234 | dprintf1(1, "vaarg1\n"); |
| | 235 | dprintf1(1, "vaarg1=%d\n", 2); |
| | 236 | dprintf1(1, "vaarg1=%d %d\n", 1, 2); |
| | 237 | |
| | 238 | /* gcc extension */ |
| | 239 | printf("func='%s'\n", __FUNCTION__); |
| | 240 | |
| | 241 | /* complicated macros in glibc */ |
| | 242 | printf("INT64_MIN=%Ld\n", INT64_MIN); |
| | 243 | { |
| | 244 | int a; |
| | 245 | a = 1; |
| | 246 | glue(a+, +); |
| | 247 | printf("a=%d\n", a); |
| | 248 | glue(a <, <= 2); |
| | 249 | printf("a=%d\n", a); |
| | 250 | } |
| | 251 | |
| | 252 | /* macro function with argument outside the macro string */ |
| | 253 | #define MF_s MF_hello |
| | 254 | #define MF_hello(msg) printf("%s\n",msg) |
| | 255 | |
| | 256 | #define MF_t printf("tralala\n"); MF_hello |
| | 257 | |
| | 258 | MF_s("hi"); |
| | 259 | MF_t("hi"); |
| | 260 | |
| | 261 | /* test macro substituion inside args (should not eat stream) */ |
| | 262 | printf("qq=%d\n", qq(qq)(2)); |
| | 263 | |
| | 264 | /* test zero argument case. NOTE: gcc 2.95.x does not accept a |
| | 265 | null argument without a space. gcc 3.2 fixes that. */ |
| | 266 | |
| | 267 | #define qq1(x) 1 |
| | 268 | printf("qq1=%d\n", qq1( )); |
| | 269 | |
| | 270 | /* comment with stray handling *\ |
| | 271 | / |
| | 272 | /* this is a valid *\/ comment */ |
| | 273 | /* this is a valid comment *\*/ |
| | 274 | // this is a valid\ |
| | 275 | comment |
| | 276 | |
| | 277 | /* test function macro substitution when the function name is |
| | 278 | substituted */ |
| | 279 | TEST2(); |
| | 280 | } |
| | 281 | |
| | 282 | int op(a,b) |
| | 283 | { |
| | 284 | return a / b; |
| | 285 | } |
| | 286 | |
| | 287 | int ret(a) |
| | 288 | { |
| | 289 | if (a == 2) |
| | 290 | return 1; |
| | 291 | if (a == 3) |
| | 292 | return 2; |
| | 293 | return 0; |
| | 294 | } |
| | 295 | |
| | 296 | void ps(const char *s) |
| | 297 | { |
| | 298 | int c; |
| | 299 | while (1) { |
| | 300 | c = *s; |
| | 301 | if (c == 0) |
| | 302 | break; |
| | 303 | printf("%c", c); |
| | 304 | s++; |
| | 305 | } |
| | 306 | } |
| | 307 | |
| | 308 | const char foo1_string[] = "\ |
| | 309 | bar\n\ |
| | 310 | test\14\ |
| | 311 | 1"; |
| | 312 | |
| | 313 | void string_test() |
| | 314 | { |
| | 315 | unsigned int b; |
| | 316 | printf("string:\n"); |
| | 317 | printf("\141\1423\143\n");/* dezdez test */ |
| | 318 | printf("\x41\x42\x43\x3a\n"); |
| | 319 | printf("c=%c\n", 'r'); |
| | 320 | printf("wc=%C 0x%lx %C\n", L'a', L'\x1234', L'c'); |
| | 321 | printf("foo1_string='%s'\n", foo1_string); |
| | 322 | #if 0 |
| | 323 | printf("wstring=%S\n", L"abc"); |
| | 324 | printf("wstring=%S\n", L"abc" L"def" "ghi"); |
| | 325 | printf("'\\377'=%d '\\xff'=%d\n", '\377', '\xff'); |
| | 326 | printf("L'\\377'=%d L'\\xff'=%d\n", L'\377', L'\xff'); |
| | 327 | #endif |
| | 328 | ps("test\n"); |
| | 329 | b = 32; |
| | 330 | while ((b = b + 1) < 96) { |
| | 331 | printf("%c", b); |
| | 332 | } |
| | 333 | printf("\n"); |
| | 334 | printf("fib=%d\n", fib(33)); |
| | 335 | b = 262144; |
| | 336 | while (b != 0x80000000) { |
| | 337 | num(b); |
| | 338 | b = b * 2; |
| | 339 | } |
| | 340 | } |
| | 341 | |
| | 342 | void loop_test() |
| | 343 | { |
| | 344 | int i; |
| | 345 | i = 0; |
| | 346 | while (i < 10) |
| | 347 | printf("%d", i++); |
| | 348 | printf("\n"); |
| | 349 | for(i = 0; i < 10;i++) |
| | 350 | printf("%d", i); |
| | 351 | printf("\n"); |
| | 352 | i = 0; |
| | 353 | do { |
| | 354 | printf("%d", i++); |
| | 355 | } while (i < 10); |
| | 356 | printf("\n"); |
| | 357 | |
| | 358 | /* break/continue tests */ |
| | 359 | i = 0; |
| | 360 | while (1) { |
| | 361 | if (i == 6) |
| | 362 | break; |
| | 363 | i++; |
| | 364 | if (i == 3) |
| | 365 | continue; |
| | 366 | printf("%d", i); |
| | 367 | } |
| | 368 | printf("\n"); |
| | 369 | |
| | 370 | /* break/continue tests */ |
| | 371 | i = 0; |
| | 372 | do { |
| | 373 | if (i == 6) |
| | 374 | break; |
| | 375 | i++; |
| | 376 | if (i == 3) |
| | 377 | continue; |
| | 378 | printf("%d", i); |
| | 379 | } while(1); |
| | 380 | printf("\n"); |
| | 381 | |
| | 382 | for(i = 0;i < 10;i++) { |
| | 383 | if (i == 3) |
| | 384 | continue; |
| | 385 | printf("%d", i); |
| | 386 | } |
| | 387 | printf("\n"); |
| | 388 | } |
| | 389 | |
| | 390 | |
| | 391 | void goto_test() |
| | 392 | { |
| | 393 | int i; |
| | 394 | static void *label_table[3] = { &&label1, &&label2, &&label3 }; |
| | 395 | |
| | 396 | printf("goto:\n"); |
| | 397 | i = 0; |
| | 398 | s_loop: |
| | 399 | if (i >= 10) |
| | 400 | goto s_end; |
| | 401 | printf("%d", i); |
| | 402 | i++; |
| | 403 | goto s_loop; |
| | 404 | s_end: |
| | 405 | printf("\n"); |
| | 406 | |
| | 407 | /* we also test computed gotos (GCC extension) */ |
| | 408 | for(i=0;i<3;i++) { |
| | 409 | goto *label_table[i]; |
| | 410 | label1: |
| | 411 | printf("label1\n"); |
| | 412 | goto next; |
| | 413 | label2: |
| | 414 | printf("label2\n"); |
| | 415 | goto next; |
| | 416 | label3: |
| | 417 | printf("label3\n"); |
| | 418 | next: ; |
| | 419 | } |
| | 420 | } |
| | 421 | |
| | 422 | enum { |
| | 423 | E0, |
| | 424 | E1 = 2, |
| | 425 | E2 = 4, |
| | 426 | E3, |
| | 427 | E4, |
| | 428 | }; |
| | 429 | |
| | 430 | enum test { |
| | 431 | E5 = 1000, |
| | 432 | }; |
| | 433 | |
| | 434 | void enum_test() |
| | 435 | { |
| | 436 | enum test b1; |
| | 437 | printf("enum:\n%d %d %d %d %d %d\n", |
| | 438 | E0, E1, E2, E3, E4, E5); |
| | 439 | b1 = 1; |
| | 440 | printf("b1=%d\n", b1); |
| | 441 | } |
| | 442 | |
| | 443 | typedef int *my_ptr; |
| | 444 | |
| | 445 | typedef int mytype1; |
| | 446 | typedef int mytype2; |
| | 447 | |
| | 448 | void typedef_test() |
| | 449 | { |
| | 450 | my_ptr a; |
| | 451 | mytype1 mytype2; |
| | 452 | int b; |
| | 453 | |
| | 454 | a = &b; |
| | 455 | *a = 1234; |
| | 456 | printf("typedef:\n"); |
| | 457 | printf("a=%d\n", *a); |
| | 458 | mytype2 = 2; |
| | 459 | printf("mytype2=%d\n", mytype2); |
| | 460 | } |
| | 461 | |
| | 462 | void forward_test() |
| | 463 | { |
| | 464 | printf("forward:\n"); |
| | 465 | forward_ref(); |
| | 466 | forward_ref(); |
| | 467 | } |
| | 468 | |
| | 469 | |
| | 470 | void forward_ref(void) |
| | 471 | { |
| | 472 | printf("forward ok\n"); |
| | 473 | } |
| | 474 | |
| | 475 | typedef struct struct1 { |
| | 476 | int f1; |
| | 477 | int f2, f3; |
| | 478 | union union1 { |
| | 479 | int v1; |
| | 480 | int v2; |
| | 481 | } u; |
| | 482 | char str[3]; |
| | 483 | } struct1; |
| | 484 | |
| | 485 | struct struct2 { |
| | 486 | int a; |
| | 487 | char b; |
| | 488 | }; |
| | 489 | |
| | 490 | union union2 { |
| | 491 | int w1; |
| | 492 | int w2; |
| | 493 | }; |
| | 494 | |
| | 495 | struct struct1 st1, st2; |
| | 496 | |
| | 497 | int main(int argc, char **argv) |
| | 498 | { |
| | 499 | string_test(); |
| | 500 | expr_test(); |
| | 501 | macro_test(); |
| | 502 | scope_test(); |
| | 503 | forward_test(); |
| | 504 | funcptr_test(); |
| | 505 | loop_test(); |
| | 506 | switch_test(); |
| | 507 | goto_test(); |
| | 508 | enum_test(); |
| | 509 | typedef_test(); |
| | 510 | struct_test(); |
| | 511 | array_test(); |
| | 512 | expr_ptr_test(); |
| | 513 | bool_test(); |
| | 514 | expr2_test(); |
| | 515 | constant_expr_test(); |
| | 516 | expr_cmp_test(); |
| | 517 | char_short_test(); |
| | 518 | init_test(); |
| | 519 | compound_literal_test(); |
| | 520 | kr_test(); |
| | 521 | struct_assign_test(); |
| | 522 | cast_test(); |
| | 523 | bitfield_test(); |
| | 524 | c99_bool_test(); |
| | 525 | float_test(); |
| | 526 | longlong_test(); |
| | 527 | manyarg_test(); |
| | 528 | stdarg_test(); |
| | 529 | whitespace_test(); |
| | 530 | relocation_test(); |
| | 531 | old_style_function(); |
| | 532 | sizeof_test(); |
| | 533 | typeof_test(); |
| | 534 | statement_expr_test(); |
| | 535 | local_label_test(); |
| | 536 | asm_test(); |
| | 537 | builtin_test(); |
| | 538 | return 0; |
| | 539 | } |
| | 540 | |
| | 541 | int tab[3]; |
| | 542 | int tab2[3][2]; |
| | 543 | |
| | 544 | int g; |
| | 545 | |
| | 546 | void f1(g) |
| | 547 | { |
| | 548 | printf("g1=%d\n", g); |
| | 549 | } |
| | 550 | |
| | 551 | void scope_test() |
| | 552 | { |
| | 553 | printf("scope:\n"); |
| | 554 | g = 2; |
| | 555 | f1(1); |
| | 556 | printf("g2=%d\n", g); |
| | 557 | { |
| | 558 | int g; |
| | 559 | g = 3; |
| | 560 | printf("g3=%d\n", g); |
| | 561 | { |
| | 562 | int g; |
| | 563 | g = 4; |
| | 564 | printf("g4=%d\n", g); |
| | 565 | } |
| | 566 | } |
| | 567 | printf("g5=%d\n", g); |
| | 568 | } |
| | 569 | |
| | 570 | void array_test(int a[4]) |
| | 571 | { |
| | 572 | int i, j; |
| | 573 | |
| | 574 | printf("array:\n"); |
| | 575 | printf("sizeof(a) = %d\n", sizeof(a)); |
| | 576 | printf("sizeof(\"a\") = %d\n", sizeof("a")); |
| | 577 | #ifdef C99_MACROS |
| | 578 | printf("sizeof(__func__) = %d\n", sizeof(__func__)); |
| | 579 | #endif |
| | 580 | printf("sizeof tab %d\n", sizeof(tab)); |
| | 581 | printf("sizeof tab2 %d\n", sizeof tab2); |
| | 582 | tab[0] = 1; |
| | 583 | tab[1] = 2; |
| | 584 | tab[2] = 3; |
| | 585 | printf("%d %d %d\n", tab[0], tab[1], tab[2]); |
| | 586 | for(i=0;i<3;i++) |
| | 587 | for(j=0;j<2;j++) |
| | 588 | tab2[i][j] = 10 * i + j; |
| | 589 | for(i=0;i<3*2;i++) { |
| | 590 | printf(" %3d", ((int *)tab2)[i]); |
| | 591 | } |
| | 592 | printf("\n"); |
| | 593 | } |
| | 594 | |
| | 595 | void expr_test() |
| | 596 | { |
| | 597 | int a, b; |
| | 598 | a = 0; |
| | 599 | printf("%d\n", a += 1); |
| | 600 | printf("%d\n", a -= 2); |
| | 601 | printf("%d\n", a *= 31232132); |
| | 602 | printf("%d\n", a /= 4); |
| | 603 | printf("%d\n", a %= 20); |
| | 604 | printf("%d\n", a &= 6); |
| | 605 | printf("%d\n", a ^= 7); |
| | 606 | printf("%d\n", a |= 8); |
| | 607 | printf("%d\n", a >>= 3); |
| | 608 | printf("%d\n", a <<= 4); |
| | 609 | |
| | 610 | a = 22321; |
| | 611 | b = -22321; |
| | 612 | printf("%d\n", a + 1); |
| | 613 | printf("%d\n", a - 2); |
| | 614 | printf("%d\n", a * 312); |
| | 615 | printf("%d\n", a / 4); |
| | 616 | printf("%d\n", b / 4); |
| | 617 | printf("%d\n", (unsigned)b / 4); |
| | 618 | printf("%d\n", a % 20); |
| | 619 | printf("%d\n", b % 20); |
| | 620 | printf("%d\n", (unsigned)b % 20); |
| | 621 | printf("%d\n", a & 6); |
| | 622 | printf("%d\n", a ^ 7); |
| | 623 | printf("%d\n", a | 8); |
| | 624 | printf("%d\n", a >> 3); |
| | 625 | printf("%d\n", b >> 3); |
| | 626 | printf("%d\n", (unsigned)b >> 3); |
| | 627 | printf("%d\n", a << 4); |
| | 628 | printf("%d\n", ~a); |
| | 629 | printf("%d\n", -a); |
| | 630 | printf("%d\n", +a); |
| | 631 | |
| | 632 | printf("%d\n", 12 + 1); |
| | 633 | printf("%d\n", 12 - 2); |
| | 634 | printf("%d\n", 12 * 312); |
| | 635 | printf("%d\n", 12 / 4); |
| | 636 | printf("%d\n", 12 % 20); |
| | 637 | printf("%d\n", 12 & 6); |
| | 638 | printf("%d\n", 12 ^ 7); |
| | 639 | printf("%d\n", 12 | 8); |
| | 640 | printf("%d\n", 12 >> 2); |
| | 641 | printf("%d\n", 12 << 4); |
| | 642 | printf("%d\n", ~12); |
| | 643 | printf("%d\n", -12); |
| | 644 | printf("%d\n", +12); |
| | 645 | printf("%d %d %d %d\n", |
| | 646 | isid('a'), |
| | 647 | isid('g'), |
| | 648 | isid('T'), |
| | 649 | isid('(')); |
| | 650 | } |
| | 651 | |
| | 652 | int isid(int c) |
| | 653 | { |
| | 654 | return (c >= 'a' & c <= 'z') | (c >= 'A' & c <= 'Z') | c == '_'; |
| | 655 | } |
| | 656 | |
| | 657 | /**********************/ |
| | 658 | |
| | 659 | int vstack[10], *vstack_ptr; |
| | 660 | |
| | 661 | void vpush(int vt, int vc) |
| | 662 | { |
| | 663 | *vstack_ptr++ = vt; |
| | 664 | *vstack_ptr++ = vc; |
| | 665 | } |
| | 666 | |
| | 667 | void vpop(int *ft, int *fc) |
| | 668 | { |
| | 669 | *fc = *--vstack_ptr; |
| | 670 | *ft = *--vstack_ptr; |
| | 671 | } |
| | 672 | |
| | 673 | void expr2_test() |
| | 674 | { |
| | 675 | int a, b; |
| | 676 | |
| | 677 | printf("expr2:\n"); |
| | 678 | vstack_ptr = vstack; |
| | 679 | vpush(1432432, 2); |
| | 680 | vstack_ptr[-2] &= ~0xffffff80; |
| | 681 | vpop(&a, &b); |
| | 682 | printf("res= %d %d\n", a, b); |
| | 683 | } |
| | 684 | |
| | 685 | void constant_expr_test() |
| | 686 | { |
| | 687 | int a; |
| | 688 | printf("constant_expr:\n"); |
| | 689 | a = 3; |
| | 690 | printf("%d\n", a * 16); |
| | 691 | printf("%d\n", a * 1); |
| | 692 | printf("%d\n", a + 0); |
| | 693 | } |
| | 694 | |
| | 695 | int tab4[10]; |
| | 696 | |
| | 697 | void expr_ptr_test() |
| | 698 | { |
| | 699 | int *p, *q; |
| | 700 | int i = -1; |
| | 701 | |
| | 702 | printf("expr_ptr:\n"); |
| | 703 | p = tab4; |
| | 704 | q = tab4 + 10; |
| | 705 | printf("diff=%d\n", q - p); |
| | 706 | p++; |
| | 707 | printf("inc=%d\n", p - tab4); |
| | 708 | p--; |
| | 709 | printf("dec=%d\n", p - tab4); |
| | 710 | ++p; |
| | 711 | printf("inc=%d\n", p - tab4); |
| | 712 | --p; |
| | 713 | printf("dec=%d\n", p - tab4); |
| | 714 | printf("add=%d\n", p + 3 - tab4); |
| | 715 | printf("add=%d\n", 3 + p - tab4); |
| | 716 | |
| | 717 | /* check if 64bit support is ok */ |
| | 718 | q = p = 0; |
| | 719 | q += i; |
| | 720 | printf("%p %p %ld\n", q, p, p-q); |
| | 721 | printf("%d %d %d %d %d %d\n", |
| | 722 | p == q, p != q, p < q, p <= q, p >= q, p > q); |
| | 723 | i = 0xf0000000; |
| | 724 | p += i; |
| | 725 | printf("%p %p %ld\n", q, p, p-q); |
| | 726 | printf("%d %d %d %d %d %d\n", |
| | 727 | p == q, p != q, p < q, p <= q, p >= q, p > q); |
| | 728 | p = (int *)((char *)p + 0xf0000000); |
| | 729 | printf("%p %p %ld\n", q, p, p-q); |
| | 730 | printf("%d %d %d %d %d %d\n", |
| | 731 | p == q, p != q, p < q, p <= q, p >= q, p > q); |
| | 732 | p += 0xf0000000; |
| | 733 | printf("%p %p %ld\n", q, p, p-q); |
| | 734 | printf("%d %d %d %d %d %d\n", |
| | 735 | p == q, p != q, p < q, p <= q, p >= q, p > q); |
| | 736 | { |
| | 737 | struct size12 { |
| | 738 | int i, j, k; |
| | 739 | }; |
| | 740 | struct size12 s[2], *sp = s; |
| | 741 | int i, j; |
| | 742 | sp->i = 42; |
| | 743 | sp++; |
| | 744 | j = -1; |
| | 745 | printf("%d\n", sp[j].i); |
| | 746 | } |
| | 747 | } |
| | 748 | |
| | 749 | void expr_cmp_test() |
| | 750 | { |
| | 751 | int a, b; |
| | 752 | printf("constant_expr:\n"); |
| | 753 | a = -1; |
| | 754 | b = 1; |
| | 755 | printf("%d\n", a == a); |
| | 756 | printf("%d\n", a != a); |
| | 757 | |
| | 758 | printf("%d\n", a < b); |
| | 759 | printf("%d\n", a <= b); |
| | 760 | printf("%d\n", a <= a); |
| | 761 | printf("%d\n", b >= a); |
| | 762 | printf("%d\n", a >= a); |
| | 763 | printf("%d\n", b > a); |
| | 764 | |
| | 765 | printf("%d\n", (unsigned)a < b); |
| | 766 | printf("%d\n", (unsigned)a <= b); |
| | 767 | printf("%d\n", (unsigned)a <= a); |
| | 768 | printf("%d\n", (unsigned)b >= a); |
| | 769 | printf("%d\n", (unsigned)a >= a); |
| | 770 | printf("%d\n", (unsigned)b > a); |
| | 771 | } |
| | 772 | |
| | 773 | struct empty { |
| | 774 | }; |
| | 775 | |
| | 776 | struct aligntest1 { |
| | 777 | char a[10]; |
| | 778 | }; |
| | 779 | |
| | 780 | struct aligntest2 { |
| | 781 | int a; |
| | 782 | char b[10]; |
| | 783 | }; |
| | 784 | |
| | 785 | struct aligntest3 { |
| | 786 | double a, b; |
| | 787 | }; |
| | 788 | |
| | 789 | struct aligntest4 { |
| | 790 | double a[0]; |
| | 791 | }; |
| | 792 | |
| | 793 | void struct_test() |
| | 794 | { |
| | 795 | struct1 *s; |
| | 796 | union union2 u; |
| | 797 | |
| | 798 | printf("struct:\n"); |
| | 799 | printf("sizes: %d %d %d %d\n", |
| | 800 | sizeof(struct struct1), |
| | 801 | sizeof(struct struct2), |
| | 802 | sizeof(union union1), |
| | 803 | sizeof(union union2)); |
| | 804 | st1.f1 = 1; |
| | 805 | st1.f2 = 2; |
| | 806 | st1.f3 = 3; |
| | 807 | printf("st1: %d %d %d\n", |
| | 808 | st1.f1, st1.f2, st1.f3); |
| | 809 | st1.u.v1 = 1; |
| | 810 | st1.u.v2 = 2; |
| | 811 | printf("union1: %d\n", st1.u.v1); |
| | 812 | u.w1 = 1; |
| | 813 | u.w2 = 2; |
| | 814 | printf("union2: %d\n", u.w1); |
| | 815 | s = &st2; |
| | 816 | s->f1 = 3; |
| | 817 | s->f2 = 2; |
| | 818 | s->f3 = 1; |
| | 819 | printf("st2: %d %d %d\n", |
| | 820 | s->f1, s->f2, s->f3); |
| | 821 | printf("str_addr=%x\n", (int)st1.str - (int)&st1.f1); |
| | 822 | |
| | 823 | /* align / size tests */ |
| | 824 | printf("aligntest1 sizeof=%d alignof=%d\n", |
| | 825 | sizeof(struct aligntest1), __alignof__(struct aligntest1)); |
| | 826 | printf("aligntest2 sizeof=%d alignof=%d\n", |
| | 827 | sizeof(struct aligntest2), __alignof__(struct aligntest2)); |
| | 828 | printf("aligntest3 sizeof=%d alignof=%d\n", |
| | 829 | sizeof(struct aligntest3), __alignof__(struct aligntest3)); |
| | 830 | printf("aligntest4 sizeof=%d alignof=%d\n", |
| | 831 | sizeof(struct aligntest4), __alignof__(struct aligntest4)); |
| | 832 | |
| | 833 | /* empty structures (GCC extension) */ |
| | 834 | printf("sizeof(struct empty) = %d\n", sizeof(struct empty)); |
| | 835 | printf("alignof(struct empty) = %d\n", __alignof__(struct empty)); |
| | 836 | } |
| | 837 | |
| | 838 | /* XXX: depend on endianness */ |
| | 839 | void char_short_test() |
| | 840 | { |
| | 841 | int var1, var2; |
| | 842 | |
| | 843 | printf("char_short:\n"); |
| | 844 | |
| | 845 | var1 = 0x01020304; |
| | 846 | var2 = 0xfffefdfc; |
| | 847 | printf("s8=%d %d\n", |
| | 848 | *(char *)&var1, *(char *)&var2); |
| | 849 | printf("u8=%d %d\n", |
| | 850 | *(unsigned char *)&var1, *(unsigned char *)&var2); |
| | 851 | printf("s16=%d %d\n", |
| | 852 | *(short *)&var1, *(short *)&var2); |
| | 853 | printf("u16=%d %d\n", |
| | 854 | *(unsigned short *)&var1, *(unsigned short *)&var2); |
| | 855 | printf("s32=%d %d\n", |
| | 856 | *(int *)&var1, *(int *)&var2); |
| | 857 | printf("u32=%d %d\n", |
| | 858 | *(unsigned int *)&var1, *(unsigned int *)&var2); |
| | 859 | *(char *)&var1 = 0x08; |
| | 860 | printf("var1=%x\n", var1); |
| | 861 | *(short *)&var1 = 0x0809; |
| | 862 | printf("var1=%x\n", var1); |
| | 863 | *(int *)&var1 = 0x08090a0b; |
| | 864 | printf("var1=%x\n", var1); |
| | 865 | } |
| | 866 | |
| | 867 | /******************/ |
| | 868 | |
| | 869 | typedef struct Sym { |
| | 870 | int v; |
| | 871 | int t; |
| | 872 | int c; |
| | 873 | struct Sym *next; |
| | 874 | struct Sym *prev; |
| | 875 | } Sym; |
| | 876 | |
| | 877 | #define ISLOWER(c) ('a' <= (c) && (c) <= 'z') |
| | 878 | #define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) |
| | 879 | |
| | 880 | static int toupper1(int a) |
| | 881 | { |
| | 882 | return TOUPPER(a); |
| | 883 | } |
| | 884 | |
| | 885 | void bool_test() |
| | 886 | { |
| | 887 | int *s, a, b, t, f, i; |
| | 888 | |
| | 889 | a = 0; |
| | 890 | s = (void*)0; |
| | 891 | printf("!s=%d\n", !s); |
| | 892 | |
| | 893 | if (!s || !s[0]) |
| | 894 | a = 1; |
| | 895 | printf("a=%d\n", a); |
| | 896 | |
| | 897 | printf("a=%d %d %d\n", 0 || 0, 0 || 1, 1 || 1); |
| | 898 | printf("a=%d %d %d\n", 0 && 0, 0 && 1, 1 && 1); |
| | 899 | printf("a=%d %d\n", 1 ? 1 : 0, 0 ? 1 : 0); |
| | 900 | #if 1 && 1 |
| | 901 | printf("a1\n"); |
| | 902 | #endif |
| | 903 | #if 1 || 0 |
| | 904 | printf("a2\n"); |
| | 905 | #endif |
| | 906 | #if 1 ? 0 : 1 |
| | 907 | printf("a3\n"); |
| | 908 | #endif |
| | 909 | #if 0 ? 0 : 1 |
| | 910 | printf("a4\n"); |
| | 911 | #endif |
| | 912 | |
| | 913 | a = 4; |
| | 914 | printf("b=%d\n", a + (0 ? 1 : a / 2)); |
| | 915 | |
| | 916 | /* test register spilling */ |
| | 917 | a = 10; |
| | 918 | b = 10; |
| | 919 | a = (a + b) * ((a < b) ? |
| | 920 | ((b - a) * (a - b)): a + b); |
| | 921 | printf("a=%d\n", a); |
| | 922 | |
| | 923 | /* test complex || or && expressions */ |
| | 924 | t = 1; |
| | 925 | f = 0; |
| | 926 | a = 32; |
| | 927 | printf("exp=%d\n", f == (32 <= a && a <= 3)); |
| | 928 | printf("r=%d\n", (t || f) + (t && f)); |
| | 929 | |
| | 930 | /* test ? : cast */ |
| | 931 | { |
| | 932 | int aspect_on; |
| | 933 | int aspect_native = 65536; |
| | 934 | double bfu_aspect = 1.0; |
| | 935 | int aspect; |
| | 936 | for(aspect_on = 0; aspect_on < 2; aspect_on++) { |
| | 937 | aspect=aspect_on?(aspect_native*bfu_aspect+0.5):65535UL; |
| | 938 | printf("aspect=%d\n", aspect); |
| | 939 | } |
| | 940 | } |
| | 941 | |
| | 942 | /* test ? : GCC extension */ |
| | 943 | { |
| | 944 | static int v1 = 34 ? : -1; /* constant case */ |
| | 945 | static int v2 = 0 ? : -1; /* constant case */ |
| | 946 | int a = 30; |
| | 947 | |
| | 948 | printf("%d %d\n", v1, v2); |
| | 949 | printf("%d %d\n", a - 30 ? : a * 2, a + 1 ? : a * 2); |
| | 950 | } |
| | 951 | |
| | 952 | /* again complex expression */ |
| | 953 | for(i=0;i<256;i++) { |
| | 954 | if (toupper1 (i) != TOUPPER (i)) |
| | 955 | printf("error %d\n", i); |
| | 956 | } |
| | 957 | } |
| | 958 | |
| | 959 | /* GCC accepts that */ |
| | 960 | static int tab_reinit[]; |
| | 961 | static int tab_reinit[10]; |
| | 962 | |
| | 963 | //int cinit1; /* a global variable can be defined several times without error ! */ |
| | 964 | int cinit1; |
| | 965 | int cinit1; |
| | 966 | int cinit1 = 0; |
| | 967 | int *cinit2 = (int []){3, 2, 1}; |
| | 968 | |
| | 969 | void compound_literal_test(void) |
| | 970 | { |
| | 971 | int *p, i; |
| | 972 | char *q, *q3; |
| | 973 | |
| | 974 | printf("compound_test:\n"); |
| | 975 | |
| | 976 | p = (int []){1, 2, 3}; |
| | 977 | for(i=0;i<3;i++) |
| | 978 | printf(" %d", p[i]); |
| | 979 | printf("\n"); |
| | 980 | |
| | 981 | for(i=0;i<3;i++) |
| | 982 | printf("%d", cinit2[i]); |
| | 983 | printf("\n"); |
| | 984 | |
| | 985 | q = "tralala1"; |
| | 986 | printf("q1=%s\n", q); |
| | 987 | |
| | 988 | q = (char *){ "tralala2" }; |
| | 989 | printf("q2=%s\n", q); |
| | 990 | |
| | 991 | q3 = (char *){ q }; |
| | 992 | printf("q3=%s\n", q3); |
| | 993 | |
| | 994 | q = (char []){ "tralala3" }; |
| | 995 | printf("q4=%s\n", q); |
| | 996 | |
| | 997 | #ifdef ALL_ISOC99 |
| | 998 | p = (int []){1, 2, cinit1 + 3}; |
| | 999 | for(i=0;i<3;i++) |
| | 1000 | printf(" %d", p[i]); |
| | 1001 | printf("\n"); |
| | 1002 | |
| | 1003 | for(i=0;i<3;i++) { |
| | 1004 | p = (int []){1, 2, 4 + i}; |
| | 1005 | printf("%d %d %d\n", |
| | 1006 | p[0], |
| | 1007 | p[1], |
| | 1008 | p[2]); |
| | 1009 | } |
| | 1010 | #endif |
| | 1011 | } |
| | 1012 | |
| | 1013 | /* K & R protos */ |
| | 1014 | |
| | 1015 | kr_func1(a, b) |
| | 1016 | { |
| | 1017 | return a + b; |
| | 1018 | } |
| | 1019 | |
| | 1020 | int kr_func2(a, b) |
| | 1021 | { |
| | 1022 | return a + b; |
| | 1023 | } |
| | 1024 | |
| | 1025 | kr_test() |
| | 1026 | { |
| | 1027 | printf("kr_test:\n"); |
| | 1028 | printf("func1=%d\n", kr_func1(3, 4)); |
| | 1029 | printf("func2=%d\n", kr_func2(3, 4)); |
| | 1030 | return 0; |
| | 1031 | } |
| | 1032 | |
| | 1033 | void num(int n) |
| | 1034 | { |
| | 1035 | char *tab, *p; |
| | 1036 | tab = (char*)malloc(20); |
| | 1037 | p = tab; |
| | 1038 | while (1) { |
| | 1039 | *p = 48 + (n % 10); |
| | 1040 | p++; |
| | 1041 | n = n / 10; |
| | 1042 | if (n == 0) |
| | 1043 | break; |
| | 1044 | } |
| | 1045 | while (p != tab) { |
| | 1046 | p--; |
| | 1047 | printf("%c", *p); |
| | 1048 | } |
| | 1049 | printf("\n"); |
| | 1050 | } |
| | 1051 | |
| | 1052 | /* structure assignment tests */ |
| | 1053 | struct structa1 { |
| | 1054 | int f1; |
| | 1055 | char f2; |
| | 1056 | }; |
| | 1057 | |
| | 1058 | struct structa1 ssta1; |
| | 1059 | |
| | 1060 | void struct_assign_test1(struct structa1 s1, int t) |
| | 1061 | { |
| | 1062 | printf("%d %d %d\n", s1.f1, s1.f2, t); |
| | 1063 | } |
| | 1064 | |
| | 1065 | struct structa1 struct_assign_test2(struct structa1 s1, int t) |
| | 1066 | { |
| | 1067 | s1.f1 += t; |
| | 1068 | s1.f2 -= t; |
| | 1069 | return s1; |
| | 1070 | } |
| | 1071 | |
| | 1072 | void struct_assign_test(void) |
| | 1073 | { |
| | 1074 | struct structa1 lsta1, lsta2; |
| | 1075 | |
| | 1076 | #if 0 |
| | 1077 | printf("struct_assign_test:\n"); |
| | 1078 | |
| | 1079 | lsta1.f1 = 1; |
| | 1080 | lsta1.f2 = 2; |
| | 1081 | printf("%d %d\n", lsta1.f1, lsta1.f2); |
| | 1082 | lsta2 = lsta1; |
| | 1083 | printf("%d %d\n", lsta2.f1, lsta2.f2); |
| | 1084 | #else |
| | 1085 | lsta2.f1 = 1; |
| | 1086 | lsta2.f2 = 2; |
| | 1087 | #endif |
| | 1088 | struct_assign_test1(lsta2, 3); |
| | 1089 | |
| | 1090 | printf("before call: %d %d\n", lsta2.f1, lsta2.f2); |
| | 1091 | lsta2 = struct_assign_test2(lsta2, 4); |
| | 1092 | printf("after call: %d %d\n", lsta2.f1, lsta2.f2); |
| | 1093 | } |
| | 1094 | |
| | 1095 | /* casts to short/char */ |
| | 1096 | |
| | 1097 | void cast1(char a, short b, unsigned char c, unsigned short d) |
| | 1098 | { |
| | 1099 | printf("%d %d %d %d\n", a, b, c, d); |
| | 1100 | } |
| | 1101 | |
| | 1102 | char bcast; |
| | 1103 | short scast; |
| | 1104 | |
| | 1105 | void cast_test() |
| | 1106 | { |
| | 1107 | int a; |
| | 1108 | char c; |
| | 1109 | char tab[10]; |
| | 1110 | unsigned b,d; |
| | 1111 | short s; |
| | 1112 | char *p = NULL; |
| | 1113 | p -= 0x700000000042; |
| | 1114 | |
| | 1115 | printf("cast_test:\n"); |
| | 1116 | a = 0xfffff; |
| | 1117 | cast1(a, a, a, a); |
| | 1118 | a = 0xffffe; |
| | 1119 | printf("%d %d %d %d\n", |
| | 1120 | (char)(a + 1), |
| | 1121 | (short)(a + 1), |
| | 1122 | (unsigned char)(a + 1), |
| | 1123 | (unsigned short)(a + 1)); |
| | 1124 | printf("%d %d %d %d\n", |
| | 1125 | (char)0xfffff, |
| | 1126 | (short)0xfffff, |
| | 1127 | (unsigned char)0xfffff, |
| | 1128 | (unsigned short)0xfffff); |
| | 1129 | |
| | 1130 | a = (bcast = 128) + 1; |
| | 1131 | printf("%d\n", a); |
| | 1132 | a = (scast = 65536) + 1; |
| | 1133 | printf("%d\n", a); |
| | 1134 | |
| | 1135 | printf("sizeof(c) = %d, sizeof((int)c) = %d\n", sizeof(c), sizeof((int)c)); |
| | 1136 | |
| | 1137 | /* test cast from unsigned to signed short to int */ |
| | 1138 | b = 0xf000; |
| | 1139 | d = (short)b; |
| | 1140 | printf("((unsigned)(short)0x%08x) = 0x%08x\n", b, d); |
| | 1141 | b = 0xf0f0; |
| | 1142 | d = (char)b; |
| | 1143 | printf("((unsigned)(char)0x%08x) = 0x%08x\n", b, d); |
| | 1144 | |
| | 1145 | /* test implicit int casting for array accesses */ |
| | 1146 | c = 0; |
| | 1147 | tab[1] = 2; |
| | 1148 | tab[c] = 1; |
| | 1149 | printf("%d %d\n", tab[0], tab[1]); |
| | 1150 | |
| | 1151 | /* test implicit casting on some operators */ |
| | 1152 | printf("sizeof(+(char)'a') = %d\n", sizeof(+(char)'a')); |
| | 1153 | printf("sizeof(-(char)'a') = %d\n", sizeof(-(char)'a')); |
| | 1154 | printf("sizeof(~(char)'a') = %d\n", sizeof(-(char)'a')); |
| | 1155 | |
| | 1156 | /* from pointer to integer types */ |
| | 1157 | printf("%d %d %ld %ld %lld %lld\n", |
| | 1158 | (int)p, (unsigned int)p, |
| | 1159 | (long)p, (unsigned long)p, |
| | 1160 | (long long)p, (unsigned long long)p); |
| | 1161 | |
| | 1162 | /* from integers to pointers */ |
| | 1163 | printf("%p %p %p %p\n", |
| | 1164 | (void *)a, (void *)b, (void *)c, (void *)d); |
| | 1165 | } |
| | 1166 | |
| | 1167 | /* initializers tests */ |
| | 1168 | struct structinit1 { |
| | 1169 | int f1; |
| | 1170 | char f2; |
| | 1171 | short f3; |
| | 1172 | int farray[3]; |
| | 1173 | }; |
| | 1174 | |
| | 1175 | int sinit1 = 2; |
| | 1176 | int sinit2 = { 3 }; |
| | 1177 | int sinit3[3] = { 1, 2, {{3}}, }; |
| | 1178 | int sinit4[3][2] = { {1, 2}, {3, 4}, {5, 6} }; |
| | 1179 | int sinit5[3][2] = { 1, 2, 3, 4, 5, 6 }; |
| | 1180 | int sinit6[] = { 1, 2, 3 }; |
| | 1181 | int sinit7[] = { [2] = 3, [0] = 1, 2 }; |
| | 1182 | char sinit8[] = "hello" "trala"; |
| | 1183 | |
| | 1184 | struct structinit1 sinit9 = { 1, 2, 3 }; |
| | 1185 | struct structinit1 sinit10 = { .f2 = 2, 3, .f1 = 1 }; |
| | 1186 | struct structinit1 sinit11 = { .f2 = 2, 3, .f1 = 1, |
| | 1187 | #ifdef ALL_ISOC99 |
| | 1188 | .farray[0] = 10, |
| | 1189 | .farray[1] = 11, |
| | 1190 | .farray[2] = 12, |
| | 1191 | #endif |
| | 1192 | }; |
| | 1193 | |
| | 1194 | char *sinit12 = "hello world"; |
| | 1195 | char *sinit13[] = { |
| | 1196 | "test1", |
| | 1197 | "test2", |
| | 1198 | "test3", |
| | 1199 | }; |
| | 1200 | char sinit14[10] = { "abc" }; |
| | 1201 | int sinit15[3] = { sizeof(sinit15), 1, 2 }; |
| | 1202 | |
| | 1203 | struct { int a[3], b; } sinit16[] = { { 1 }, 2 }; |
| | 1204 | |
| | 1205 | struct bar { |
| | 1206 | char *s; |
| | 1207 | int len; |
| | 1208 | } sinit17[] = { |
| | 1209 | "a1", 4, |
| | 1210 | "a2", 1 |
| | 1211 | }; |
| | 1212 | |
| | 1213 | int sinit18[10] = { |
| | 1214 | [2 ... 5] = 20, |
| | 1215 | 2, |
| | 1216 | [8] = 10, |
| | 1217 | }; |
| | 1218 | |
| | 1219 | void init_test(void) |
| | 1220 | { |
| | 1221 | int linit1 = 2; |
| | 1222 | int linit2 = { 3 }; |
| | 1223 | int linit4[3][2] = { {1, 2}, {3, 4}, {5, 6} }; |
| | 1224 | int linit6[] = { 1, 2, 3 }; |
| | 1225 | int i, j; |
| | 1226 | char linit8[] = "hello" "trala"; |
| | 1227 | int linit12[10] = { 1, 2 }; |
| | 1228 | int linit13[10] = { 1, 2, [7] = 3, [3] = 4, }; |
| | 1229 | char linit14[10] = "abc"; |
| | 1230 | int linit15[10] = { linit1, linit1 + 1, [6] = linit1 + 2, }; |
| | 1231 | struct linit16 { int a1, a2, a3, a4; } linit16 = { 1, .a3 = 2 }; |
| | 1232 | int linit17 = sizeof(linit17); |
| | 1233 | |
| | 1234 | printf("init_test:\n"); |
| | 1235 | |
| | 1236 | printf("sinit1=%d\n", sinit1); |
| | 1237 | printf("sinit2=%d\n", sinit2); |
| | 1238 | printf("sinit3=%d %d %d %d\n", |
| | 1239 | sizeof(sinit3), |
| | 1240 | sinit3[0], |
| | 1241 | sinit3[1], |
| | 1242 | sinit3[2] |
| | 1243 | ); |
| | 1244 | printf("sinit6=%d\n", sizeof(sinit6)); |
| | 1245 | printf("sinit7=%d %d %d %d\n", |
| | 1246 | sizeof(sinit7), |
| | 1247 | sinit7[0], |
| | 1248 | sinit7[1], |
| | 1249 | sinit7[2] |
| | 1250 | ); |
| | 1251 | printf("sinit8=%s\n", sinit8); |
| | 1252 | printf("sinit9=%d %d %d\n", |
| | 1253 | sinit9.f1, |
| | 1254 | sinit9.f2, |
| | 1255 | sinit9.f3 |
| | 1256 | ); |
| | 1257 | printf("sinit10=%d %d %d\n", |
| | 1258 | sinit10.f1, |
| | 1259 | sinit10.f2, |
| | 1260 | sinit10.f3 |
| | 1261 | ); |
| | 1262 | printf("sinit11=%d %d %d %d %d %d\n", |
| | 1263 | sinit11.f1, |
| | 1264 | sinit11.f2, |
| | 1265 | sinit11.f3, |
| | 1266 | sinit11.farray[0], |
| | 1267 | sinit11.farray[1], |
| | 1268 | sinit11.farray[2] |
| | 1269 | ); |
| | 1270 | |
| | 1271 | for(i=0;i<3;i++) |
| | 1272 | for(j=0;j<2;j++) |
| | 1273 | printf("[%d][%d] = %d %d %d\n", |
| | 1274 | i, j, sinit4[i][j], sinit5[i][j], linit4[i][j]); |
| | 1275 | printf("linit1=%d\n", linit1); |
| | 1276 | printf("linit2=%d\n", linit2); |
| | 1277 | printf("linit6=%d\n", sizeof(linit6)); |
| | 1278 | printf("linit8=%d %s\n", sizeof(linit8), linit8); |
| | 1279 | |
| | 1280 | printf("sinit12=%s\n", sinit12); |
| | 1281 | printf("sinit13=%d %s %s %s\n", |
| | 1282 | sizeof(sinit13), |
| | 1283 | sinit13[0], |
| | 1284 | sinit13[1], |
| | 1285 | sinit13[2]); |
| | 1286 | printf("sinit14=%s\n", sinit14); |
| | 1287 | |
| | 1288 | for(i=0;i<10;i++) printf(" %d", linit12[i]); |
| | 1289 | printf("\n"); |
| | 1290 | for(i=0;i<10;i++) printf(" %d", linit13[i]); |
| | 1291 | printf("\n"); |
| | 1292 | for(i=0;i<10;i++) printf(" %d", linit14[i]); |
| | 1293 | printf("\n"); |
| | 1294 | for(i=0;i<10;i++) printf(" %d", linit15[i]); |
| | 1295 | printf("\n"); |
| | 1296 | printf("%d %d %d %d\n", |
| | 1297 | linit16.a1, |
| | 1298 | linit16.a2, |
| | 1299 | linit16.a3, |
| | 1300 | linit16.a4); |
| | 1301 | /* test that initialisation is done after variable declare */ |
| | 1302 | printf("linit17=%d\n", linit17); |
| | 1303 | printf("sinit15=%d\n", sinit15[0]); |
| | 1304 | printf("sinit16=%d %d\n", sinit16[0].a[0], sinit16[1].a[0]); |
| | 1305 | printf("sinit17=%s %d %s %d\n", |
| | 1306 | sinit17[0].s, sinit17[0].len, |
| | 1307 | sinit17[1].s, sinit17[1].len); |
| | 1308 | for(i=0;i<10;i++) |
| | 1309 | printf("%x ", sinit18[i]); |
| | 1310 | printf("\n"); |
| | 1311 | } |
| | 1312 | |
| | 1313 | |
| | 1314 | void switch_test() |
| | 1315 | { |
| | 1316 | int i; |
| | 1317 | |
| | 1318 | for(i=0;i<15;i++) { |
| | 1319 | switch(i) { |
| | 1320 | case 0: |
| | 1321 | case 1: |
| | 1322 | printf("a"); |
| | 1323 | break; |
| | 1324 | default: |
| | 1325 | printf("%d", i); |
| | 1326 | break; |
| | 1327 | case 8 ... 12: |
| | 1328 | printf("c"); |
| | 1329 | break; |
| | 1330 | case 3: |
| | 1331 | printf("b"); |
| | 1332 | break; |
| | 1333 | } |
| | 1334 | } |
| | 1335 | printf("\n"); |
| | 1336 | } |
| | 1337 | |
| | 1338 | /* ISOC99 _Bool type */ |
| | 1339 | void c99_bool_test(void) |
| | 1340 | { |
| | 1341 | #ifdef BOOL_ISOC99 |
| | 1342 | int a; |
| | 1343 | _Bool b; |
| | 1344 | |
| | 1345 | printf("bool_test:\n"); |
| | 1346 | printf("sizeof(_Bool) = %d\n", sizeof(_Bool)); |
| | 1347 | a = 3; |
| | 1348 | printf("cast: %d %d %d\n", (_Bool)10, (_Bool)0, (_Bool)a); |
| | 1349 | b = 3; |
| | 1350 | printf("b = %d\n", b); |
| | 1351 | b++; |
| | 1352 | printf("b = %d\n", b); |
| | 1353 | #endif |
| | 1354 | } |
| | 1355 | |
| | 1356 | void bitfield_test(void) |
| | 1357 | { |
| | 1358 | int a; |
| | 1359 | struct sbf1 { |
| | 1360 | int f1 : 3; |
| | 1361 | int : 2; |
| | 1362 | int f2 : 1; |
| | 1363 | int : 0; |
| | 1364 | int f3 : 5; |
| | 1365 | int f4 : 7; |
| | 1366 | unsigned int f5 : 7; |
| | 1367 | } st1; |
| | 1368 | printf("bitfield_test:"); |
| | 1369 | printf("sizeof(st1) = %d\n", sizeof(st1)); |
| | 1370 | |
| | 1371 | st1.f1 = 3; |
| | 1372 | st1.f2 = 1; |
| | 1373 | st1.f3 = 15; |
| | 1374 | a = 120; |
| | 1375 | st1.f4 = a; |
| | 1376 | st1.f5 = a; |
| | 1377 | st1.f5++; |
| | 1378 | printf("%d %d %d %d %d\n", |
| | 1379 | st1.f1, st1.f2, st1.f3, st1.f4, st1.f5); |
| | 1380 | |
| | 1381 | st1.f1 = 7; |
| | 1382 | if (st1.f1 == -1) |
| | 1383 | printf("st1.f1 == -1\n"); |
| | 1384 | else |
| | 1385 | printf("st1.f1 != -1\n"); |
| | 1386 | if (st1.f2 == -1) |
| | 1387 | printf("st1.f2 == -1\n"); |
| | 1388 | else |
| | 1389 | printf("st1.f2 != -1\n"); |
| | 1390 | |
| | 1391 | /* bit sizes below must be bigger than 32 since GCC doesn't allow |
| | 1392 | long-long bitfields whose size is not bigger than int */ |
| | 1393 | struct sbf2 { |
| | 1394 | long long f1 : 45; |
| | 1395 | long long : 2; |
| | 1396 | long long f2 : 35; |
| | 1397 | unsigned long long f3 : 38; |
| | 1398 | } st2; |
| | 1399 | st2.f1 = 0x123456789ULL; |
| | 1400 | a = 120; |
| | 1401 | st2.f2 = (long long)a << 25; |
| | 1402 | st2.f3 = a; |
| | 1403 | st2.f2++; |
| | 1404 | printf("%lld %lld %lld\n", st2.f1, st2.f2, st2.f3); |
| | 1405 | } |
| | 1406 | |
| | 1407 | #ifdef __x86_64__ |
| | 1408 | #define FLOAT_FMT "%f\n" |
| | 1409 | #else |
| | 1410 | /* x86's float isn't compatible with GCC */ |
| | 1411 | #define FLOAT_FMT "%.5f\n" |
| | 1412 | #endif |
| | 1413 | |
| | 1414 | /* declare strto* functions as they are C99 */ |
| | 1415 | double strtod(const char *nptr, char **endptr); |
| | 1416 | float strtof(const char *nptr, char **endptr); |
| | 1417 | long double strtold(const char *nptr, char **endptr); |
| | 1418 | |
| | 1419 | #define FTEST(prefix, type, fmt)\ |
| | 1420 | void prefix ## cmp(type a, type b)\ |
| | 1421 | {\ |
| | 1422 | printf("%d %d %d %d %d %d\n",\ |
| | 1423 | a == b,\ |
| | 1424 | a != b,\ |
| | 1425 | a < b,\ |
| | 1426 | a > b,\ |
| | 1427 | a >= b,\ |
| | 1428 | a <= b);\ |
| | 1429 | printf(fmt " " fmt " " fmt " " fmt " " fmt " " fmt " " fmt "\n",\ |
| | 1430 | a,\ |
| | 1431 | b,\ |
| | 1432 | a + b,\ |
| | 1433 | a - b,\ |
| | 1434 | a * b,\ |
| | 1435 | a / b,\ |
| | 1436 | -a);\ |
| | 1437 | printf(fmt "\n", ++a);\ |
| | 1438 | printf(fmt "\n", a++);\ |
| | 1439 | printf(fmt "\n", a);\ |
| | 1440 | b = 0;\ |
| | 1441 | printf("%d %d\n", !a, !b);\ |
| | 1442 | }\ |
| | 1443 | void prefix ## fcast(type a)\ |
| | 1444 | {\ |
| | 1445 | float fa;\ |
| | 1446 | double da;\ |
| | 1447 | long double la;\ |
| | 1448 | int ia;\ |
| | 1449 | unsigned int ua;\ |
| | 1450 | type b;\ |
| | 1451 | fa = a;\ |
| | 1452 | da = a;\ |
| | 1453 | la = a;\ |
| | 1454 | printf("ftof: %f %f %Lf\n", fa, da, la);\ |
| | 1455 | ia = (int)a;\ |
| | 1456 | ua = (unsigned int)a;\ |
| | 1457 | printf("ftoi: %d %u\n", ia, ua);\ |
| | 1458 | ia = -1234;\ |
| | 1459 | ua = 0x81234500;\ |
| | 1460 | b = ia;\ |
| | 1461 | printf("itof: " fmt "\n", b);\ |
| | 1462 | b = ua;\ |
| | 1463 | printf("utof: " fmt "\n", b);\ |
| | 1464 | }\ |
| | 1465 | \ |
| | 1466 | float prefix ## retf(type a) { return a; }\ |
| | 1467 | double prefix ## retd(type a) { return a; }\ |
| | 1468 | long double prefix ## retld(type a) { return a; }\ |
| | 1469 | \ |
| | 1470 | void prefix ## call(void)\ |
| | 1471 | {\ |
| | 1472 | printf("float: " FLOAT_FMT, prefix ## retf(42.123456789));\ |
| | 1473 | printf("double: %f\n", prefix ## retd(42.123456789));\ |
| | 1474 | printf("long double: %Lf\n", prefix ## retld(42.123456789));\ |
| | 1475 | printf("strto%s: %f\n", #prefix, (double)strto ## prefix("1.2", NULL));\ |
| | 1476 | }\ |
| | 1477 | \ |
| | 1478 | void prefix ## test(void)\ |
| | 1479 | {\ |
| | 1480 | printf("testing '%s'\n", #type);\ |
| | 1481 | prefix ## cmp(1, 2.5);\ |
| | 1482 | prefix ## cmp(2, 1.5);\ |
| | 1483 | prefix ## cmp(1, 1);\ |
| | 1484 | prefix ## fcast(234.6);\ |
| | 1485 | prefix ## fcast(-2334.6);\ |
| | 1486 | prefix ## call();\ |
| | 1487 | } |
| | 1488 | |
| | 1489 | FTEST(f, float, "%f") |
| | 1490 | FTEST(d, double, "%f") |
| | 1491 | FTEST(ld, long double, "%Lf") |
| | 1492 | |
| | 1493 | double ftab1[3] = { 1.2, 3.4, -5.6 }; |
| | 1494 | |
| | 1495 | |
| | 1496 | void float_test(void) |
| | 1497 | { |
| | 1498 | float fa, fb; |
| | 1499 | double da, db; |
| | 1500 | int a; |
| | 1501 | unsigned int b; |
| | 1502 | |
| | 1503 | printf("float_test:\n"); |
| | 1504 | printf("sizeof(float) = %d\n", sizeof(float)); |
| | 1505 | printf("sizeof(double) = %d\n", sizeof(double)); |
| | 1506 | printf("sizeof(long double) = %d\n", sizeof(long double)); |
| | 1507 | ftest(); |
| | 1508 | dtest(); |
| | 1509 | ldtest(); |
| | 1510 | printf("%f %f %f\n", ftab1[0], ftab1[1], ftab1[2]); |
| | 1511 | printf("%f %f %f\n", 2.12, .5, 2.3e10); |
| | 1512 | // printf("%f %f %f\n", 0x1234p12, 0x1e23.23p10, 0x12dp-10); |
| | 1513 | da = 123; |
| | 1514 | printf("da=%f\n", da); |
| | 1515 | fa = 123; |
| | 1516 | printf("fa=%f\n", fa); |
| | 1517 | a = 4000000000; |
| | 1518 | da = a; |
| | 1519 | printf("da = %f\n", da); |
| | 1520 | b = 4000000000; |
| | 1521 | db = b; |
| | 1522 | printf("db = %f\n", db); |
| | 1523 | } |
| | 1524 | |
| | 1525 | int fib(int n) |
| | 1526 | { |
| | 1527 | if (n <= 2) |
| | 1528 | return 1; |
| | 1529 | else |
| | 1530 | return fib(n-1) + fib(n-2); |
| | 1531 | } |
| | 1532 | |
| | 1533 | void funcptr_test() |
| | 1534 | { |
| | 1535 | void (*func)(int); |
| | 1536 | int a; |
| | 1537 | struct { |
| | 1538 | int dummy; |
| | 1539 | void (*func)(int); |
| | 1540 | } st1; |
| | 1541 | |
| | 1542 | printf("funcptr:\n"); |
| | 1543 | func = # |
| | 1544 | (*func)(12345); |
| | 1545 | func = num; |
| | 1546 | a = 1; |
| | 1547 | a = 1; |
| | 1548 | func(12345); |
| | 1549 | /* more complicated pointer computation */ |
| | 1550 | st1.func = num; |
| | 1551 | st1.func(12346); |
| | 1552 | printf("sizeof1 = %d\n", sizeof(funcptr_test)); |
| | 1553 | printf("sizeof2 = %d\n", sizeof funcptr_test); |
| | 1554 | printf("sizeof3 = %d\n", sizeof(&funcptr_test)); |
| | 1555 | printf("sizeof4 = %d\n", sizeof &funcptr_test); |
| | 1556 | } |
| | 1557 | |
| | 1558 | void lloptest(long long a, long long b) |
| | 1559 | { |
| | 1560 | unsigned long long ua, ub; |
| | 1561 | |
| | 1562 | ua = a; |
| | 1563 | ub = b; |
| | 1564 | /* arith */ |
| | 1565 | printf("arith: %Ld %Ld %Ld\n", |
| | 1566 | a + b, |
| | 1567 | a - b, |
| | 1568 | a * b); |
| | 1569 | |
| | 1570 | if (b != 0) { |
| | 1571 | printf("arith1: %Ld %Ld\n", |
| | 1572 | a / b, |
| | 1573 | a % b); |
| | 1574 | } |
| | 1575 | |
| | 1576 | /* binary */ |
| | 1577 | printf("bin: %Ld %Ld %Ld\n", |
| | 1578 | a & b, |
| | 1579 | a | b, |
| | 1580 | a ^ b); |
| | 1581 | |
| | 1582 | /* tests */ |
| | 1583 | printf("test: %d %d %d %d %d %d\n", |
| | 1584 | a == b, |
| | 1585 | a != b, |
| | 1586 | a < b, |
| | 1587 | a > b, |
| | 1588 | a >= b, |
| | 1589 | a <= b); |
| | 1590 | |
| | 1591 | printf("utest: %d %d %d %d %d %d\n", |
| | 1592 | ua == ub, |
| | 1593 | ua != ub, |
| | 1594 | ua < ub, |
| | 1595 | ua > ub, |
| | 1596 | ua >= ub, |
| | 1597 | ua <= ub); |
| | 1598 | |
| | 1599 | /* arith2 */ |
| | 1600 | a++; |
| | 1601 | b++; |
| | 1602 | printf("arith2: %Ld %Ld\n", a, b); |
| | 1603 | printf("arith2: %Ld %Ld\n", a++, b++); |
| | 1604 | printf("arith2: %Ld %Ld\n", --a, --b); |
| | 1605 | printf("arith2: %Ld %Ld\n", a, b); |
| | 1606 | b = ub = 0; |
| | 1607 | printf("not: %d %d %d %d\n", !a, !ua, !b, !ub); |
| | 1608 | } |
| | 1609 | |
| | 1610 | void llshift(long long a, int b) |
| | 1611 | { |
| | 1612 | printf("shift: %Ld %Ld %Ld\n", |
| | 1613 | (unsigned long long)a >> b, |
| | 1614 | a >> b, |
| | 1615 | a << b); |
| | 1616 | printf("shiftc: %Ld %Ld %Ld\n", |
| | 1617 | (unsigned long long)a >> 3, |
| | 1618 | a >> 3, |
| | 1619 | a << 3); |
| | 1620 | printf("shiftc: %Ld %Ld %Ld\n", |
| | 1621 | (unsigned long long)a >> 35, |
| | 1622 | a >> 35, |
| | 1623 | a << 35); |
| | 1624 | } |
| | 1625 | |
| | 1626 | void llfloat(void) |
| | 1627 | { |
| | 1628 | float fa; |
| | 1629 | double da; |
| | 1630 | long double lda; |
| | 1631 | long long la, lb, lc; |
| | 1632 | unsigned long long ula, ulb, ulc; |
| | 1633 | la = 0x12345678; |
| | 1634 | ula = 0x72345678; |
| | 1635 | la = (la << 20) | 0x12345; |
| | 1636 | ula = ula << 33; |
| | 1637 | printf("la=%Ld ula=%Lu\n", la, ula); |
| | 1638 | |
| | 1639 | fa = la; |
| | 1640 | da = la; |
| | 1641 | lda = la; |
| | 1642 | printf("lltof: %f %f %Lf\n", fa, da, lda); |
| | 1643 | |
| | 1644 | la = fa; |
| | 1645 | lb = da; |
| | 1646 | lc = lda; |
| | 1647 | printf("ftoll: %Ld %Ld %Ld\n", la, lb, lc); |
| | 1648 | |
| | 1649 | fa = ula; |
| | 1650 | da = ula; |
| | 1651 | lda = ula; |
| | 1652 | printf("ulltof: %f %f %Lf\n", fa, da, lda); |
| | 1653 | |
| | 1654 | ula = fa; |
| | 1655 | ulb = da; |
| | 1656 | ulc = lda; |
| | 1657 | printf("ftoull: %Lu %Lu %Lu\n", ula, ulb, ulc); |
| | 1658 | } |
| | 1659 | |
| | 1660 | long long llfunc1(int a) |
| | 1661 | { |
| | 1662 | return a * 2; |
| | 1663 | } |
| | 1664 | |
| | 1665 | struct S { |
| | 1666 | int id; |
| | 1667 | char item; |
| | 1668 | }; |
| | 1669 | |
| | 1670 | long long int value(struct S *v) |
| | 1671 | { |
| | 1672 | return ((long long int)v->item); |
| | 1673 | } |
| | 1674 | |
| | 1675 | void longlong_test(void) |
| | 1676 | { |
| | 1677 | long long a, b, c; |
| | 1678 | int ia; |
| | 1679 | unsigned int ua; |
| | 1680 | printf("longlong_test:\n"); |
| | 1681 | printf("sizeof(long long) = %d\n", sizeof(long long)); |
| | 1682 | ia = -1; |
| | 1683 | ua = -2; |
| | 1684 | a = ia; |
| | 1685 | b = ua; |
| | 1686 | printf("%Ld %Ld\n", a, b); |
| | 1687 | printf("%Ld %Ld %Ld %Lx\n", |
| | 1688 | (long long)1, |
| | 1689 | (long long)-2, |
| | 1690 | 1LL, |
| | 1691 | 0x1234567812345679); |
| | 1692 | a = llfunc1(-3); |
| | 1693 | printf("%Ld\n", a); |
| | 1694 | |
| | 1695 | lloptest(1000, 23); |
| | 1696 | lloptest(0xff, 0x1234); |
| | 1697 | b = 0x72345678 << 10; |
| | 1698 | lloptest(-3, b); |
| | 1699 | llshift(0x123, 5); |
| | 1700 | llshift(-23, 5); |
| | 1701 | b = 0x72345678LL << 10; |
| | 1702 | llshift(b, 47); |
| | 1703 | |
| | 1704 | llfloat(); |
| | 1705 | #if 1 |
| | 1706 | b = 0x12345678; |
| | 1707 | a = -1; |
| | 1708 | c = a + b; |
| | 1709 | printf("%Lx\n", c); |
| | 1710 | #endif |
| | 1711 | |
| | 1712 | /* long long reg spill test */ |
| | 1713 | { |
| | 1714 | struct S a; |
| | 1715 | |
| | 1716 | a.item = 3; |
| | 1717 | printf("%lld\n", value(&a)); |
| | 1718 | } |
| | 1719 | lloptest(0x80000000, 0); |
| | 1720 | |
| | 1721 | /* another long long spill test */ |
| | 1722 | { |
| | 1723 | long long *p, v; |
| | 1724 | v = 1; |
| | 1725 | p = &v; |
| | 1726 | p[0]++; |
| | 1727 | printf("%lld\n", *p); |
| | 1728 | } |
| | 1729 | |
| | 1730 | a = 68719476720LL; |
| | 1731 | b = 4294967295LL; |
| | 1732 | printf("%d %d %d %d\n", a > b, a < b, a >= b, a <= b); |
| | 1733 | |
| | 1734 | printf("%Ld\n", 0x123456789LLU); |
| | 1735 | } |
| | 1736 | |
| | 1737 | void manyarg_test(void) |
| | 1738 | { |
| | 1739 | long double ld = 1234567891234LL; |
| | 1740 | printf("manyarg_test:\n"); |
| | 1741 | printf("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f\n", |
| | 1742 | 1, 2, 3, 4, 5, 6, 7, 8, |
| | 1743 | 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0); |
| | 1744 | printf("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f " |
| | 1745 | "%Ld %Ld %f %f\n", |
| | 1746 | 1, 2, 3, 4, 5, 6, 7, 8, |
| | 1747 | 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0, |
| | 1748 | 1234567891234LL, 987654321986LL, |
| | 1749 | 42.0, 43.0); |
| | 1750 | printf("%Lf %d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f " |
| | 1751 | "%Ld %Ld %f %f\n", |
| | 1752 | ld, 1, 2, 3, 4, 5, 6, 7, 8, |
| | 1753 | 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0, |
| | 1754 | 1234567891234LL, 987654321986LL, |
| | 1755 | 42.0, 43.0); |
| | 1756 | /* XXX: known bug of x86-64 */ |
| | 1757 | #ifndef __x86_64__ |
| | 1758 | printf("%d %d %d %d %d %d %d %d %Lf\n", |
| | 1759 | 1, 2, 3, 4, 5, 6, 7, 8, ld); |
| | 1760 | printf("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f " |
| | 1761 | "%Ld %Ld %f %f %Lf\n", |
| | 1762 | 1, 2, 3, 4, 5, 6, 7, 8, |
| | 1763 | 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0, |
| | 1764 | 1234567891234LL, 987654321986LL, |
| | 1765 | 42.0, 43.0, ld); |
| | 1766 | printf("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f " |
| | 1767 | "%Lf %Ld %Ld %f %f %Lf\n", |
| | 1768 | 1, 2, 3, 4, 5, 6, 7, 8, |
| | 1769 | 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0, |
| | 1770 | ld, 1234567891234LL, 987654321986LL, |
| | 1771 | 42.0, 43.0, ld); |
| | 1772 | #endif |
| | 1773 | } |
| | 1774 | |
| | 1775 | void vprintf1(const char *fmt, ...) |
| | 1776 | { |
| | 1777 | va_list ap; |
| | 1778 | const char *p; |
| | 1779 | int c, i; |
| | 1780 | double d; |
| | 1781 | long long ll; |
| | 1782 | long double ld; |
| | 1783 | |
| | 1784 | va_start(ap, fmt); |
| | 1785 | |
| | 1786 | p = fmt; |
| | 1787 | for(;;) { |
| | 1788 | c = *p; |
| | 1789 | if (c == '\0') |
| | 1790 | break; |
| | 1791 | p++; |
| | 1792 | if (c == '%') { |
| | 1793 | c = *p; |
| | 1794 | switch(c) { |
| | 1795 | case '\0': |
| | 1796 | goto the_end; |
| | 1797 | case 'd': |
| | 1798 | i = va_arg(ap, int); |
| | 1799 | printf("%d", i); |
| | 1800 | break; |
| | 1801 | case 'f': |
| | 1802 | d = va_arg(ap, double); |
| | 1803 | printf("%f", d); |
| | 1804 | break; |
| | 1805 | case 'l': |
| | 1806 | ll = va_arg(ap, long long); |
| | 1807 | printf("%Ld", ll); |
| | 1808 | break; |
| | 1809 | case 'F': |
| | 1810 | ld = va_arg(ap, long double); |
| | 1811 | printf("%Lf", ld); |
| | 1812 | break; |
| | 1813 | } |
| | 1814 | p++; |
| | 1815 | } else { |
| | 1816 | putchar(c); |
| | 1817 | } |
| | 1818 | } |
| | 1819 | the_end: |
| | 1820 | va_end(ap); |
| | 1821 | } |
| | 1822 | |
| | 1823 | |
| | 1824 | void stdarg_test(void) |
| | 1825 | { |
| | 1826 | long double ld = 1234567891234LL; |
| | 1827 | vprintf1("%d %d %d\n", 1, 2, 3); |
| | 1828 | vprintf1("%f %d %f\n", 1.0, 2, 3.0); |
| | 1829 | vprintf1("%l %l %d %f\n", 1234567891234LL, 987654321986LL, 3, 1234.0); |
| | 1830 | vprintf1("%F %F %F\n", 1.2L, 2.3L, 3.4L); |
| | 1831 | #ifdef __x86_64__ |
| | 1832 | /* a bug of x86's TCC */ |
| | 1833 | vprintf1("%d %f %l %F %d %f %l %F\n", |
| | 1834 | 1, 1.2, 3L, 4.5L, 6, 7.8, 9L, 0.1L); |
| | 1835 | #endif |
| | 1836 | vprintf1("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f\n", |
| | 1837 | 1, 2, 3, 4, 5, 6, 7, 8, |
| | 1838 | 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8); |
| | 1839 | vprintf1("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f\n", |
| | 1840 | 1, 2, 3, 4, 5, 6, 7, 8, |
| | 1841 | 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0); |
| | 1842 | vprintf1("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f " |
| | 1843 | "%l %l %f %f\n", |
| | 1844 | 1, 2, 3, 4, 5, 6, 7, 8, |
| | 1845 | 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0, |
| | 1846 | 1234567891234LL, 987654321986LL, |
| | 1847 | 42.0, 43.0); |
| | 1848 | vprintf1("%F %d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f " |
| | 1849 | "%l %l %f %f\n", |
| | 1850 | ld, 1, 2, 3, 4, 5, 6, 7, 8, |
| | 1851 | 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0, |
| | 1852 | 1234567891234LL, 987654321986LL, |
| | 1853 | 42.0, 43.0); |
| | 1854 | vprintf1("%d %d %d %d %d %d %d %d %F\n", |
| | 1855 | 1, 2, 3, 4, 5, 6, 7, 8, ld); |
| | 1856 | vprintf1("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f " |
| | 1857 | "%l %l %f %f %F\n", |
| | 1858 | 1, 2, 3, 4, 5, 6, 7, 8, |
| | 1859 | 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0, |
| | 1860 | 1234567891234LL, 987654321986LL, |
| | 1861 | 42.0, 43.0, ld); |
| | 1862 | vprintf1("%d %d %d %d %d %d %d %d %f %f %f %f %f %f %f %f %f %f " |
| | 1863 | "%F %l %l %f %f %F\n", |
| | 1864 | 1, 2, 3, 4, 5, 6, 7, 8, |
| | 1865 | 0.1, 1.2, 2.3, 3.4, 4.5, 5.6, 6.7, 7.8, 8.9, 9.0, |
| | 1866 | ld, 1234567891234LL, 987654321986LL, |
| | 1867 | 42.0, 43.0, ld); |
| | 1868 | } |
| | 1869 | |
| | 1870 | void whitespace_test(void) |
| | 1871 | { |
| | 1872 | char *str; |
| | 1873 | |
| | 1874 |
#if 1 |
| | 1875 | pri\ |
| | 1876 | ntf("whitspace:\n"); |
| | 1877 | #endif |
| | 1878 | pf("N=%d\n", 2); |
| | 1879 | |
| | 1880 | #ifdef CORRECT_CR_HANDLING |
| | 1881 | pri\ |
| | 1882 | ntf("aaa=%d\n", 3); |
| | 1883 | #endif |
| | 1884 | |
| | 1885 | pri\ |
| | 1886 | \ |
| | 1887 | ntf("min=%d\n", 4); |
| | 1888 | |
| | 1889 | #ifdef ACCEPT_CR_IN_STRINGS |
| | 1890 | printf("len1=%d\n", strlen(" |
| | 1891 | ")); |
| | 1892 | #ifdef CORRECT_CR_HANDLING |
| | 1893 | str = " |
| | 1894 | "; |
| | 1895 | printf("len1=%d str[0]=%d\n", strlen(str), str[0]); |
| | 1896 | #endif |
| | 1897 | printf("len1=%d\n", strlen("
a |
| | 1898 | ")); |
| | 1899 | #endif /* ACCEPT_CR_IN_STRINGS */ |
| | 1900 | } |
| | 1901 | |
| | 1902 | int reltab[3] = { 1, 2, 3 }; |
| | 1903 | |
| | 1904 | int *rel1 = &reltab[1]; |
| | 1905 | int *rel2 = &reltab[2]; |
| | 1906 | |
| | 1907 | void relocation_test(void) |
| | 1908 | { |
| | 1909 | printf("*rel1=%d\n", *rel1); |
| | 1910 | printf("*rel2=%d\n", *rel2); |
| | 1911 | } |
| | 1912 | |
| | 1913 | void old_style_f(a,b,c) |
| | 1914 | int a, b; |
| | 1915 | double c; |
| | 1916 | { |
| | 1917 | printf("a=%d b=%d b=%f\n", a, b, c); |
| | 1918 | } |
| | 1919 | |
| | 1920 | void decl_func1(int cmpfn()) |
| | 1921 | { |
| | 1922 | printf("cmpfn=%lx\n", (long)cmpfn); |
| | 1923 | } |
| | 1924 | |
| | 1925 | void decl_func2(cmpfn) |
| | 1926 | int cmpfn(); |
| | 1927 | { |
| | 1928 | printf("cmpfn=%lx\n", (long)cmpfn); |
| | 1929 | } |
| | 1930 | |
| | 1931 | void old_style_function(void) |
| | 1932 | { |
| | 1933 | old_style_f((void *)1, 2, 3.0); |
| | 1934 | decl_func1(NULL); |
| | 1935 | decl_func2(NULL); |
| | 1936 | } |
| | 1937 | |
| | 1938 | void sizeof_test(void) |
| | 1939 | { |
| | 1940 | int a; |
| | 1941 | int **ptr; |
| | 1942 | |
| | 1943 | printf("sizeof(int) = %d\n", sizeof(int)); |
| | 1944 | printf("sizeof(unsigned int) = %d\n", sizeof(unsigned int)); |
| | 1945 | printf("sizeof(long) = %d\n", sizeof(long)); |
| | 1946 | printf("sizeof(unsigned long) = %d\n", sizeof(unsigned long)); |
| | 1947 | printf("sizeof(short) = %d\n", sizeof(short)); |
| | 1948 | printf("sizeof(unsigned short) = %d\n", sizeof(unsigned short)); |
| | 1949 | printf("sizeof(char) = %d\n", sizeof(char)); |
| | 1950 | printf("sizeof(unsigned char) = %d\n", sizeof(unsigned char)); |
| | 1951 | printf("sizeof(func) = %d\n", sizeof sizeof_test()); |
| | 1952 | a = 1; |
| | 1953 | printf("sizeof(a++) = %d\n", sizeof a++); |
| | 1954 | printf("a=%d\n", a); |
| | 1955 | ptr = NULL; |
| | 1956 | printf("sizeof(**ptr) = %d\n", sizeof (**ptr)); |
| | 1957 | |
| | 1958 | /* some alignof tests */ |
| | 1959 | printf("__alignof__(int) = %d\n", __alignof__(int)); |
| | 1960 | printf("__alignof__(unsigned int) = %d\n", __alignof__(unsigned int)); |
| | 1961 | printf("__alignof__(short) = %d\n", __alignof__(short)); |
| | 1962 | printf("__alignof__(unsigned short) = %d\n", __alignof__(unsigned short)); |
| | 1963 | printf("__alignof__(char) = %d\n", __alignof__(char)); |
| | 1964 | printf("__alignof__(unsigned char) = %d\n", __alignof__(unsigned char)); |
| | 1965 | printf("__alignof__(func) = %d\n", __alignof__ sizeof_test()); |
| | 1966 | } |
| | 1967 | |
| | 1968 | void typeof_test(void) |
| | 1969 | { |
| | 1970 | double a; |
| | 1971 | typeof(a) b; |
| | 1972 | typeof(float) c; |
| | 1973 | |
| | 1974 | a = 1.5; |
| | 1975 | b = 2.5; |
| | 1976 | c = 3.5; |
| | 1977 | printf("a=%f b=%f c=%f\n", a, b, c); |
| | 1978 | } |
| | 1979 | |
| | 1980 | void statement_expr_test(void) |
| | 1981 | { |
| | 1982 | int a, i; |
| | 1983 | |
| | 1984 | a = 0; |
| | 1985 | for(i=0;i<10;i++) { |
| | 1986 | a += 1 + |
| | 1987 | ( { int b, j; |
| | 1988 | b = 0; |
| | 1989 | for(j=0;j<5;j++) |
| | 1990 | b += j; b; |
| | 1991 | } ); |
| | 1992 | } |
| | 1993 | printf("a=%d\n", a); |
| | 1994 | |
| | 1995 | } |
| | 1996 | |
| | 1997 | void local_label_test(void) |
| | 1998 | { |
| | 1999 | int a; |
| | 2000 | goto l1; |
| | 2001 | l2: |
| | 2002 | a = 1 + ({ |
| | 2003 | __label__ l1, l2, l3, l4; |
| | 2004 | goto l1; |
| | 2005 | l4: |
| | 2006 | printf("aa1\n"); |
| | 2007 | goto l3; |
| | 2008 | l2: |
| | 2009 | printf("aa3\n"); |
| | 2010 | goto l4; |
| | 2011 | l1: |
| | 2012 | printf("aa2\n"); |
| | 2013 | goto l2; |
| | 2014 | l3:; |
| | 2015 | 1; |
| | 2016 | }); |
| | 2017 | printf("a=%d\n", a); |
| | 2018 | return; |
| | 2019 | l4: |
| | 2020 | printf("bb1\n"); |
| | 2021 | goto l2; |
| | 2022 | l1: |
| | 2023 | printf("bb2\n"); |
| | 2024 | goto l4; |
| | 2025 | } |
| | 2026 | |
| | 2027 | /* inline assembler test */ |
| | 2028 | #ifdef __i386__ |
| | 2029 | |
| | 2030 | /* from linux kernel */ |
| | 2031 | static char * strncat1(char * dest,const char * src,size_t count) |
| | 2032 | { |
| | 2033 | int d0, d1, d2, d3; |
| | 2034 | __asm__ __volatile__( |
| | 2035 | "repne\n\t" |
| | 2036 | "scasb\n\t" |
| | 2037 | "decl %1\n\t" |
| | 2038 | "movl %8,%3\n" |
| | 2039 | "1:\tdecl %3\n\t" |
| | 2040 | "js 2f\n\t" |
| | 2041 | "lodsb\n\t" |
| | 2042 | "stosb\n\t" |
| | 2043 | "testb %%al,%%al\n\t" |
| | 2044 | "jne 1b\n" |
| | 2045 | "2:\txorl %2,%2\n\t" |
| | 2046 | "stosb" |
| | 2047 | : "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3) |
| | 2048 | : "0" (src),"1" (dest),"2" (0),"3" (0xffffffff), "g" (count) |
| | 2049 | : "memory"); |
| | 2050 | return dest; |
| | 2051 | } |
| | 2052 | |
| | 2053 | static inline void * memcpy1(void * to, const void * from, size_t n) |
| | 2054 | { |
| | 2055 | int d0, d1, d2; |
| | 2056 | __asm__ __volatile__( |
| | 2057 | "rep ; movsl\n\t" |
| | 2058 | "testb $2,%b4\n\t" |
| | 2059 | "je 1f\n\t" |
| | 2060 | "movsw\n" |
| | 2061 | "1:\ttestb $1,%b4\n\t" |
| | 2062 | "je 2f\n\t" |
| | 2063 | "movsb\n" |
| | 2064 | "2:" |
| | 2065 | : "=&c" (d0), "=&D" (d1), "=&S" (d2) |
| | 2066 | :"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from) |
| | 2067 | : "memory"); |
| | 2068 | return (to); |
| | 2069 | } |
| | 2070 | |
| | 2071 | static __inline__ void sigaddset1(unsigned int *set, int _sig) |
| | 2072 | { |
| | 2073 | __asm__("btsl %1,%0" : "=m"(*set) : "Ir"(_sig - 1) : "cc"); |
| | 2074 | } |
| | 2075 | |
| | 2076 | static __inline__ void sigdelset1(unsigned int *set, int _sig) |
| | 2077 | { |
| | 2078 | asm("btrl %1,%0" : "=m"(*set) : "Ir"(_sig - 1) : "cc"); |
| | 2079 | } |
| | 2080 | |
| | 2081 | static __inline__ __const__ unsigned int swab32(unsigned int x) |
| | 2082 | { |
| | 2083 | __asm__("xchgb %b0,%h0\n\t" /* swap lower bytes */ |
| | 2084 | "rorl $16,%0\n\t" /* swap words */ |
| | 2085 | "xchgb %b0,%h0" /* swap higher bytes */ |
| | 2086 | :"=q" (x) |
| | 2087 | : "0" (x)); |
| | 2088 | return x; |
| | 2089 | } |
| | 2090 | |
| | 2091 | static __inline__ unsigned long long mul64(unsigned int a, unsigned int b) |
| | 2092 | { |
| | 2093 | unsigned long long res; |
| | 2094 | __asm__("mull %2" : "=A" (res) : "a" (a), "r" (b)); |
| | 2095 | return res; |
| | 2096 | } |
| | 2097 | |
| | 2098 | static __inline__ unsigned long long inc64(unsigned long long a) |
| | 2099 | { |
| | 2100 | unsigned long long res; |
| | 2101 | __asm__("addl $1, %%eax ; adcl $0, %%edx" : "=A" (res) : "A" (a)); |
| | 2102 | return res; |
| | 2103 | } |
| | 2104 | |
| | 2105 | unsigned int set; |
| | 2106 | |
| | 2107 | void asm_test(void) |
| | 2108 | { |
| | 2109 | char buf[128]; |
| | 2110 | unsigned int val; |
| | 2111 | |
| | 2112 | printf("inline asm:\n"); |
| | 2113 | /* test the no operand case */ |
| | 2114 | asm volatile ("xorl %eax, %eax"); |
| | 2115 | |
| | 2116 | memcpy1(buf, "hello", 6); |
| | 2117 | strncat1(buf, " worldXXXXX", 3); |
| | 2118 | printf("%s\n", buf); |
| | 2119 | |
| | 2120 | /* 'A' constraint test */ |
| | 2121 | printf("mul64=0x%Lx\n", mul64(0x12345678, 0xabcd1234)); |
| | 2122 | printf("inc64=0x%Lx\n", inc64(0x12345678ffffffff)); |
| | 2123 | |
| | 2124 | set = 0xff; |
| | 2125 | sigdelset1(&set, 2); |
| | 2126 | sigaddset1(&set, 16); |
| | 2127 | /* NOTE: we test here if C labels are correctly restored after the |
| | 2128 | asm statement */ |
| | 2129 | goto label1; |
| | 2130 | label2: |
| | 2131 | __asm__("btsl %1,%0" : "=m"(set) : "Ir"(20) : "cc"); |
| | 2132 | #ifdef __GNUC__ // works strange with GCC 4.3 |
| | 2133 | set=0x1080fd; |
| | 2134 | #endif |
| | 2135 | printf("set=0x%x\n", set); |
| | 2136 | val = 0x01020304; |
| | 2137 | printf("swab32(0x%08x) = 0x%0x\n", val, swab32(val)); |
| | 2138 | return; |
| | 2139 | label1: |
| | 2140 | goto label2; |
| | 2141 | } |
| | 2142 | |
| | 2143 | #else |
| | 2144 | |
| | 2145 | void asm_test(void) |
| | 2146 | { |
| | 2147 | } |
| | 2148 | |
| | 2149 | #endif |
| | 2150 | |
| | 2151 | #define COMPAT_TYPE(type1, type2) \ |
| | 2152 | {\ |
| | 2153 | printf("__builtin_types_compatible_p(%s, %s) = %d\n", #type1, #type2, \ |
| | 2154 | __builtin_types_compatible_p (type1, type2));\ |
| | 2155 | } |
| | 2156 | |
| | 2157 | int constant_p_var; |
| | 2158 | |
| | 2159 | void builtin_test(void) |
| | 2160 | { |
| | 2161 | #if GCC_MAJOR >= 3 |
| | 2162 | COMPAT_TYPE(int, int); |
| | 2163 | COMPAT_TYPE(int, unsigned int); |
| | 2164 | COMPAT_TYPE(int, char); |
| | 2165 | COMPAT_TYPE(int, const int); |
| | 2166 | COMPAT_TYPE(int, volatile int); |
| | 2167 | COMPAT_TYPE(int *, int *); |
| | 2168 | COMPAT_TYPE(int *, void *); |
| | 2169 | COMPAT_TYPE(int *, const int *); |
| | 2170 | COMPAT_TYPE(char *, unsigned char *); |
| | 2171 | /* space is needed because tcc preprocessor introduces a space between each token */ |
| | 2172 | COMPAT_TYPE(char * *, void *); |
| | 2173 | #endif |
| | 2174 | printf("res = %d\n", __builtin_constant_p(1)); |
| | 2175 | printf("res = %d\n", __builtin_constant_p(1 + 2)); |
| | 2176 | printf("res = %d\n", __builtin_constant_p(&constant_p_var)); |
| | 2177 | printf("res = %d\n", __builtin_constant_p(constant_p_var)); |
| | 2178 | } |
| | 2179 | |
| | 2180 | |
| | 2181 | void const_func(const int a) |
| | 2182 | { |
| | 2183 | } |
| | 2184 | |
| | 2185 | void const_warn_test(void) |
| | 2186 | { |
| | 2187 | const_func(1); |
| | 2188 | } |