/* * M I S C . T * 1998/08 Made public. kmatsui * 2003/11 Slightly revised. kmatsui * 2004/11 Split samples for "Reiser cpp" as "trad.t". * Removed duplicate samples with other testcases. * kmatsui * * Miscellaneous texts for test of preprocessor. * * PART 1, 2 are excerpts from * ISO C 6.8.3 "Examples" * Some other examples are excerpted from : * P.J.Plauger "The Standard C Library", * GCC "cpp.info" */ /* * PART 1 * Weird tests of macro rescan. */ #define x 3 #define f(a) f(x * (a)) #undef x #define x 2 #define g f #define z z[0] #define h g(~ #define m(a) a(w) #define w 0,1 #define t(a) a rescan() { /* f(y+1) + f(f(z)) % t(t(g)(0) + t)(1); * * should expand to: * * f(2 * (y+1)) + f(2 * (f(2 * (z[0])))) % f(2 * (0)) + t(1); */ f(y+1) + f(f(z)) % t(t(g)(0) + t)(1); /* g(x+(3,4)-w) | h 5) & m * (f)^m(m); * * should result in: * * f(2 * (2+(3,4)-0,1)) | f(2 * (~ 5)) & f(2 * (0,1))^m(0,1); */ g(x+(3,4)-w) | h 5) & m (f)^m(m); } /* * PART 2 * Tests of creating string literal and concatenation of tokens. */ #define str(s) # s #define xstr(s) str(s) #define debug(s,t) printf("x" # s "= %d, x" # t "= %s", \ x ## s, x ## t) #define INCFILE(n) vers ## n /* comment */ #define glue(a, b) a ## b #define xglue(a, b) glue(a, b) #define HIGHLOW "hello" #define LOW LOW ", world" stringize() { /* debug(1, 2); * * should result in: * * printf("x" "1" "= %d, x" "2" "= %s", x1, x2); * * after concatenation of the character string literals: * * printf("x1= %d, x2= %s", x1, x2); */ debug(1, 2); /* fputs(str(strncmp("abc\0d", "abc", '\4') * == 0) str(: @\n), s); * * should result in: * * fputs("strncmp(\"abc\\0d\", \"abc\", '\\4') == 0" ": @\n", s); * * after concatenation of the character string literals (exactly, the each * escape sequences are converted to a corresponding character prior to the * concatenation): * * fputs("strncmp(\"abc\\0d\", \"abc\", '\\4') == 0: @\n", s); */ fputs(str(strncmp("abc\0d", "abc", '\4') /* this goes away */ == 0) str(: @\n), s); /* glue(HIGH, LOW); * * should result in: * * "hello"; */ glue(HIGH, LOW); /* xglue(HIGH, LOW) * * should result in: * * "hello" ", world" * * after concatenation of the character string literals: * * "hello, world" */ xglue(HIGH, LOW) } #undef f #undef g #undef h #undef m #undef t #undef w #undef x #undef z /* #include xstr(INCFILE(2).h) * * should expand to (after macro replacement, before file access): * * #include "vers2.h" * * "vers2.h" includes and for the later tests. */ #include xstr(INCFILE(2).h) /* * PART 3 * More tests of token concatenation, taken from * Kernighan & Ritchie "The C Programming Language", 2nd. Ed., A12.3. */ concat() { /* This is expanded to: * abc; */ xglue( xglue( a, b), c); /* This is also expanded to: * abc; */ xglue( glue( a, b), c); /* Results of these macro calls are undefined, once expanded to: * glue( a, b)c; * xglue( a, b)c; * ')c' is not a valid preprocessing token. */ glue( glue( a, b), c); glue( xglue( a, b), c); } /* * PART 4 * More samples of token concatenation. */ #define COMMAND( name) { # name, name ## _command } struct command commands[] = { /* { "quit", quit_command }, */ COMMAND (quit), /* { "help", help_command }, */ COMMAND (help), }; #define maxof( type) maxof ## type #define DefMax( type) \ type maxof( type)( type a, type b) \ { \ return (( a > b) ? a : b); \ } /* int maxofint( int a, int b) { return (( a > b) ? a : b); } */ DefMax( int) /* double maxofdouble( double a, double b) * { return (( a > b) ? a : b); } */ DefMax( double) /* * PART 5 * Test of stringization. */ line() { /* 211; "211"; "__LINE__"; */ __LINE__; xstr( __LINE__); str( __LINE__); } /* * PART 6 * Tests of handling escape sequences. * Tests of concatenation of string literals. */ escape() { #undef NDEBUG #include /* In ASCII character set */ assert( '\a' == 7); /* After string concatenation : * results somehow as this: * ((strcmp( "132", "132") == 0) ? (void) 0 : * _assert( "strcmp( \"\\x31\" \"32\", \"132\") == 0", * "misc.t",270)); * ((strcmp( "132", "132") == 0) ? (void) 0 : * _assert( "strcmp( \"\\61\" \"32\", \"132\") == 0", * "misc.t",271)); */ assert( strcmp( "\x31" "32", "132") == 0); assert( strcmp( "\61" "32", "132") == 0); /* * In the messy encoding of KANJI called shift-JIS, "表" is encoded as * "\x95\x5C", the latter byte is not a beginning of an escape sequence. */ assert( strcmp( "表" "作成", "表作成") == 0); } /* * PART 7 * Tests of evaluating constant expression in long, unsigned long. * Tests of , . */ #include #if INT_MAX < INT_MIN || UINT_MAX <= INT_MAX # error bad int properties #endif #if LONG_MAX < 2147483647 || -2147483647 < LONG_MIN || LONG_MAX < INT_MAX # error bad long properties #endif #define NDEBUG #include assert_long() { /* This macro is ineffective now that NDEBUG is defined. */ assert( LONG_MAX >= 2147483647 && -2147483647 >= LONG_MIN && LONG_MAX >= INT_MAX); } ulong() { /* For the compiler which has unsigned long data type */ #if defined ULONG_MAX && (ULONG_MAX < 4294967295 \ || ULONG_MAX / 2 < LONG_MAX || ULONG_MAX < UINT_MAX) # error bad unsigned long properties #endif } internal() { /* The following 2 samlpes overflow on two's complement representation. */ #if -LONG_MIN == LONG_MAX This is not a "two's complement" representation. #endif #if LONG_MIN * -1 == LONG_MAX This is not a "two's complement" representation. #endif /* On two's complement representation this expression evaluate to false. */ #if defined (ULONG_MAX) && ULONG_MAX / 2 > LONG_MIN This is not "two's complement" representation or mis-implementation. #endif /* Right bit-shift of negative number is implementation-defined. */ #if -2 >> 1 == -1 Arithmetic right shift of negative number. #elif -2 >> 1 == LONG_MAX Logical shift of negative number of "two's complement" representation. #else Maybe logical shift of other than "two's complement" representation. #endif /* Dividing or modulo containing negative operand is not portable. */ #if -7 / 3 != -2 Not algebraic dividing of negative number. #endif #if -7 % 3 != -1 What ? #endif } /* * PART 8 * Extended or obsolete facilities. */ non_standard() { #if defined __cplusplus || __STDC_VERSION__ == 199901L // Comment in C++ style, terminating with '\x95\x5C' encoded in shift-JIS 表 "__cplusplus" is defined or "__STDC_VERSION__" equals 199901L. #endif /* sizeof in #if expression is disallowed in Standard C */ #if sizeof (long) < sizeof (int) # error bad long properties #endif #if sizeof (char *) == 2 && sizeof (int (*)()) == 2 puts( "This is a small memory model."); #endif #if __MCPP > 1 /* Trace the process of macro expansion */ #ifdef __STDC__ #pragma MCPP debug memory /* list heap memory */ #pragma MCPP debug token /* trace token */ #else #debug memory #debug token #endif /* glue ( a, b)c; */ glue( glue( a, b), c); #ifdef __STDC__ #pragma MCPP end_debug token /* no debug */ #else #end_debug token #endif #endif /* __MCPP */ #define TRUE 1 #define FALSE 0 #ifndef __STDC__ #ifdef __MCPP #assert TRUE != 0 && FALSE == 0 #endif #endif } put_long() { char * line = "line"; #ifndef __STDC__ #ifdef __MWC09__ /* Assemly source for Microware-C/09 */ /* fputs( line, stdout); */ #asm leax _iob+13,y /* stdout */ pshs x ldd 2,s /* line */ pshs d lbsr fputs leas 4,s #endasm #endif #endif } /* * PART 9 * Ambiguous macros and others. */ wide_and_nonwide() { /* Wide-character string literal following string literal and vice versa. */ "string" L"漢字"; L"漢字" "string"; } ambiguous() { /* Result of "f(2)(9)" is left intentionally ambiguous by Standard (ANSI C "Rationale", 3.8.3.4). */ /* 2*f(9); or 2*9*g; */ #define f(a) a*g #define g(a) f(a) f(2)(9); }