// filename:c2011-6-10-3-5-ex.c
// original examples and/or notes:
// 		(c) ISO/IEC JTC1 SC22 WG14 N1570, April 12, 2011
// http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf
// 			C2011 6.10.3.5 Scope of macro definitions
// compile and output mechanism:
// 		(c) Ogawa Kiyoshi, kaizen@gifu-u.ac.jp, December.29, 2013
// compile errors and/or wornings:
// 1	(c) Apple LLVM version 4.2 (clang-425.0.27) (based on LLVM 3.2svn)
// 			Target: x86_64-apple-darwin11.4.2 //Thread model: posix
// 		(c) LLVM 2003-2009 University of Illinois at Urbana-Champaign.
// 2    gcc-4.9 (GCC) 4.9.0 20131229 (experimental)
//      Copyright (C) 2013 Free Software Foundation, Inc.
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>

//int f(int);
// Example 1
#define TABSIZE 100
int table[TABSIZE];

// Example 2
#define max(a, b) ((a) > (b) ? (a) : (b))

// Example 3
#define x 3
#define f(a) f(x * (a))
#undef x
#define x 2
#define g f
#define z z[0]
#define h2 g(~
#define m(a) a(w)
#define w 0,1
#define t(a) a
#define p() int
#define q(x) x
#define r(x,y) x ## y
#define str(x) # x

void func1(void){
int y,z,z2[5];
f(y+1) + f(f(z)) % t(t(g)(0) + t)(1);
g(x+(3,4)-w) | h2 5) & m
(f)^m(m);
p() i[q()] = { q(1), r(2,3), r(4,), r(,5), r(,) };
char c[2][6] = { str(hello), str() };

//f(2 * (y+1)) + f(2 * (f(2 * (z2[0])))) % f(2 * (0)) + t(1);
//f(2 * (2+(3,4)-0,1)) | f(2 * (~ 5)) & f(2 * (0,1))^m(0,1);
//int i2[] = { 1, 23, 4, 5, };
//char c2[2][6] = { "hello", "" };
}
// Example 4
//#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
#define glue(a, b) a ## b
#define xglue(a, b) glue(a, b)
#define HIGHLOW "hello"
#define LOW LOW ", world"

void func2(void){
int x1,x2;
char * s;
debug(1, 2);
fputs(str(strncmp("abc\0d", "abc", '\4') /* this goes away*/	== 0) str(: @\n), s);
	
glue(HIGH, LOW);
xglue(HIGH, LOW);
}
#include xstr(INCFILE(2).h)


//printf("x" "1" "= %d, x" "2" "= %s", x1, x2);
//fputs(
//"strncmp(\"abc\\0d\", \"abc\", '\\4') == 0" ": @\n",
//	s);

//#include "vers2.h" (after macro replacement, before file access)

//void func4(void){
//int x1,x2;
//char * s;
//"hello";
//"hello" ", world"

//printf("x1= %d, x2= %s", x1, x2);
//fputs(
//"strncmp(\"abc\\0d\", \"abc\", '\\4') == 0: @\n",
//			s);
//}
//#include "vers2.h" (after macro replacement, before file access)
//"hello";
//"hello, world"

// Example 5
#define t2(x,y,z) x ## y ## z
int j[] = { t2(1,2,3), t2(,4,5), t2(6,,7), t2(8,9,),t2(10,,), t2(,11,), t2(,,12), t2(,,) };

//int j[] = { 123, 45, 67, 89,
//10, 11, 12, };

//EXAMPLE 6 To demonstrate the redefinition rules, the following sequence is valid.
#define OBJ_LIKE (1-1)
#define OBJ_LIKE /* white space */ (1-1) /* other */
#define FUNC_LIKE(a) ( a )
#define FUNC_LIKE( a )( /* note the white space */ \
a /* other stuff on this line*/ )

//#define OBJ_LIKE (0) // different token sequence
//#define OBJ_LIKE (1 - 1) // different white space
//#define FUNC_LIKE(b) ( a ) // different parameter usage
//#define FUNC_LIKE(b) ( b ) // different parameter spelling

// EXAMPLE 7 Finally, to show the variable argument list macro facilities:
#define debug2(...) fprintf(stderr, __VA_ARGS__)
#define showlist(...) puts(#__VA_ARGS__)
#define report(test, ...) ((test)?puts(#test):\
	printf(__VA_ARGS__))
int main(void)
{
int y;

debug2("Flag");
debug2("X = %d\n", x);
showlist(The first, second, and third items.);
report(x>y, "x is %d but y is %d", x, y);

//fprintf(stderr, "Flag" );
//fprintf(stderr, "X = %d\n", x );
//puts( "The first, second, and third items." );
//((x>y)?puts("x>y"):
//printf("x is %d but y is %d", x, y));

return printf("6.10.3.5 Scope of macro definitions \n");	
}
// output may be
