// This implements the C(x,y) and S(x) macros which works like ETP's & operator // and automatic conversion to string, respectively. #include extern size_t cant_print_this_type; #define __strsize(__v,__t) \ (__builtin_choose_expr(__builtin_types_compatible_p(__t,char *) \ ||__builtin_types_compatible_p(__t,signed char *) \ ||__builtin_types_compatible_p(__t,unsigned char *) \ ||__builtin_types_compatible_p(__t,const char *) \ ||__builtin_types_compatible_p(__t,const signed char *) \ ||__builtin_types_compatible_p(__t,const unsigned char *) \ ||__builtin_types_compatible_p(__t,char []) \ ||__builtin_types_compatible_p(__t,signed char []) \ ||__builtin_types_compatible_p(__t,unsigned char []) \ ||__builtin_types_compatible_p(__t,const char []) \ ||__builtin_types_compatible_p(__t,const signed char []) \ ||__builtin_types_compatible_p(__t,const unsigned char []) \ ,strlen((const char *)(unsigned long)__v), \ __builtin_choose_expr(__builtin_types_compatible_p(__t,char) \ ||__builtin_types_compatible_p(__t,signed char) \ ||__builtin_types_compatible_p(__t,unsigned char),1UL, \ __builtin_choose_expr(__builtin_types_compatible_p(__t,unsigned short) \ ||__builtin_types_compatible_p(__t,unsigned int),5UL, \ __builtin_choose_expr(__builtin_types_compatible_p(__t,short) \ ||__builtin_types_compatible_p(__t,int),6UL, \ __builtin_choose_expr(__builtin_types_compatible_p(__t,unsigned long),10UL, \ __builtin_choose_expr(__builtin_types_compatible_p(__t,long),11UL, \ __builtin_choose_expr(__builtin_types_compatible_p(__t,float) \ ||__builtin_types_compatible_p(__t,double) \ ||__builtin_types_compatible_p(__t,long double),29UL, \ cant_print_this_type)))))))) #define __strfmt(__t) \ (__builtin_choose_expr(__builtin_types_compatible_p(__t,char *) \ ||__builtin_types_compatible_p(__t,signed char *) \ ||__builtin_types_compatible_p(__t,unsigned char *) \ ||__builtin_types_compatible_p(__t,const char *) \ ||__builtin_types_compatible_p(__t,const signed char *) \ ||__builtin_types_compatible_p(__t,const unsigned char *) \ ||__builtin_types_compatible_p(__t,char []) \ ||__builtin_types_compatible_p(__t,signed char []) \ ||__builtin_types_compatible_p(__t,unsigned char []) \ ||__builtin_types_compatible_p(__t,const char []) \ ||__builtin_types_compatible_p(__t,const signed char []) \ ||__builtin_types_compatible_p(__t,const unsigned char []),"%s", \ __builtin_choose_expr(__builtin_types_compatible_p(__t,char) \ ||__builtin_types_compatible_p(__t,signed char) \ ||__builtin_types_compatible_p(__t,unsigned char),"%c", \ __builtin_choose_expr(__builtin_types_compatible_p(__t,unsigned short) \ ||__builtin_types_compatible_p(__t,unsigned int),"%u", \ __builtin_choose_expr(__builtin_types_compatible_p(__t,short) \ ||__builtin_types_compatible_p(__t,int),"%d", \ __builtin_choose_expr(__builtin_types_compatible_p(__t,unsigned long),"%lu", \ __builtin_choose_expr(__builtin_types_compatible_p(__t,long),"%ld", \ __builtin_choose_expr(__builtin_types_compatible_p(__t,float) \ ||__builtin_types_compatible_p(__t,double) \ ||__builtin_types_compatible_p(__t,long double),"%g", \ "")))))))) #define S(__val) ({ \ __typeof__((__val)+0) __v=__val; \ char *__result=__builtin_alloca(__strsize(__v,__typeof__((__val)))+1); \ sprintf(__result,__strfmt(__typeof__((__val))),__v); \ __result;}) #define __strfmt2(__t1,__t2) \ (__builtin_choose_expr(__builtin_types_compatible_p(__t1,char *) \ ||__builtin_types_compatible_p(__t1,signed char *) \ ||__builtin_types_compatible_p(__t1,unsigned char *) \ ||__builtin_types_compatible_p(__t1,const char *) \ ||__builtin_types_compatible_p(__t1,const signed char *) \ ||__builtin_types_compatible_p(__t1,const unsigned char *) \ ||__builtin_types_compatible_p(__t1,char []) \ ||__builtin_types_compatible_p(__t1,signed char []) \ ||__builtin_types_compatible_p(__t1,unsigned char []) \ ||__builtin_types_compatible_p(__t1,const char []) \ ||__builtin_types_compatible_p(__t1,const signed char []) \ ||__builtin_types_compatible_p(__t1,const unsigned char []), \ (__builtin_choose_expr(__builtin_types_compatible_p(__t2,char *) \ ||__builtin_types_compatible_p(__t2,signed char *) \ ||__builtin_types_compatible_p(__t2,unsigned char *) \ ||__builtin_types_compatible_p(__t2,const char *) \ ||__builtin_types_compatible_p(__t2,const signed char *) \ ||__builtin_types_compatible_p(__t2,const unsigned char *) \ ||__builtin_types_compatible_p(__t2,char []) \ ||__builtin_types_compatible_p(__t2,signed char []) \ ||__builtin_types_compatible_p(__t2,unsigned char []) \ ||__builtin_types_compatible_p(__t2,const char []) \ ||__builtin_types_compatible_p(__t2,const signed char []) \ ||__builtin_types_compatible_p(__t2,const unsigned char []),"%s%s", \ __builtin_choose_expr(__builtin_types_compatible_p(__t2,char) \ ||__builtin_types_compatible_p(__t2,signed char) \ ||__builtin_types_compatible_p(__t2,unsigned char),"%s%c", \ __builtin_choose_expr(__builtin_types_compatible_p(__t2,unsigned short) \ ||__builtin_types_compatible_p(__t2,unsigned int),"%s%u", \ __builtin_choose_expr(__builtin_types_compatible_p(__t2,short) \ ||__builtin_types_compatible_p(__t2,int),"%s%d", \ __builtin_choose_expr(__builtin_types_compatible_p(__t2,unsigned long),"%s%lu", \ __builtin_choose_expr(__builtin_types_compatible_p(__t2,long),"%s%ld", \ __builtin_choose_expr(__builtin_types_compatible_p(__t2,float) \ ||__builtin_types_compatible_p(__t2,double) \ ||__builtin_types_compatible_p(__t2,long double),"%s%g", \ "")))))))), \ __builtin_choose_expr(__builtin_types_compatible_p(__t1,char) \ ||__builtin_types_compatible_p(__t1,signed char) \ ||__builtin_types_compatible_p(__t1,unsigned char), \ (__builtin_choose_expr(__builtin_types_compatible_p(__t2,char *) \ ||__builtin_types_compatible_p(__t2,signed char *) \ ||__builtin_types_compatible_p(__t2,unsigned char *) \ ||__builtin_types_compatible_p(__t2,const char *) \ ||__builtin_types_compatible_p(__t2,const signed char *) \ ||__builtin_types_compatible_p(__t2,const unsigned char *) \ ||__builtin_types_compatible_p(__t2,char []) \ ||__builtin_types_compatible_p(__t2,signed char []) \ ||__builtin_types_compatible_p(__t2,unsigned char []) \ ||__builtin_types_compatible_p(__t2,const char []) \ ||__builtin_types_compatible_p(__t2,const signed char []) \ ||__builtin_types_compatible_p(__t2,const unsigned char []),"%c%s", \ __builtin_choose_expr(__builtin_types_compatible_p(__t2,char) \ ||__builtin_types_compatible_p(__t2,signed char) \ ||__builtin_types_compatible_p(__t2,unsigned char),"%c%c", \ __builtin_choose_expr(__builtin_types_compatible_p(__t2,unsigned short) \ ||__builtin_types_compatible_p(__t2,unsigned int),"%c%u", \ __builtin_choose_expr(__builtin_types_compatible_p(__t2,short) \ ||__builtin_types_compatible_p(__t2,int),"%c%d", \ __builtin_choose_expr(__builtin_types_compatible_p(__t2,unsigned long),"%c%lu", \ __builtin_choose_expr(__builtin_types_compatible_p(__t2,long),"%c%ld", \ __builtin_choose_expr(__builtin_types_compatible_p(__t2,float) \ ||__builtin_types_compatible_p(__t2,double) \ ||__builtin_types_compatible_p(__t2,long double),"%c%g", \ "")))))))), \ __builtin_choose_expr(__builtin_types_compatible_p(__t1,unsigned short) \ ||__builtin_types_compatible_p(__t1,unsigned int), \ (__builtin_choose_expr(__builtin_types_compatible_p(__t2,char *) \ ||__builtin_types_compatible_p(__t2,signed char *) \ ||__builtin_types_compatible_p(__t2,unsigned char *) \ ||__builtin_types_compatible_p(__t2,const char *) \ ||__builtin_types_compatible_p(__t2,const signed char *) \ ||__builtin_types_compatible_p(__t2,const unsigned char *) \ ||__builtin_types_compatible_p(__t2,char []) \ ||__builtin_types_compatible_p(__t2,signed char []) \ ||__builtin_types_compatible_p(__t2,unsigned char []) \ ||__builtin_types_compatible_p(__t2,const char []) \ ||__builtin_types_compatible_p(__t2,const signed char []) \ ||__builtin_types_compatible_p(__t2,const unsigned char []),"%u%s", \ __builtin_choose_expr(__builtin_types_compatible_p(__t2,char) \ ||__builtin_types_compatible_p(__t2,signed char) \ ||__builtin_types_compatible_p(__t2,unsigned char),"%u%c", \ __builtin_choose_expr(__builtin_types_compatible_p(__t2,unsigned short) \ ||__builtin_types_compatible_p(__t2,unsigned int),"%u%u", \ __builtin_choose_expr(__builtin_types_compatible_p(__t2,short) \ ||__builtin_types_compatible_p(__t2,int),"%u%d", \ __builtin_choose_expr(__builtin_types_compatible_p(__t2,unsigned long),"%u%lu", \ __builtin_choose_expr(__builtin_types_compatible_p(__t2,long),"%u%ld", \ __builtin_choose_expr(__builtin_types_compatible_p(__t2,float) \ ||__builtin_types_compatible_p(__t2,double) \ ||__builtin_types_compatible_p(__t2,long double),"%u%g", \ "")))))))), \ __builtin_choose_expr(__builtin_types_compatible_p(__t1,short) \ ||__builtin_types_compatible_p(__t1,int), \ (__builtin_choose_expr(__builtin_types_compatible_p(__t2,char *) \ ||__builtin_types_compatible_p(__t2,signed char *) \ ||__builtin_types_compatible_p(__t2,unsigned char *) \ ||__builtin_types_compatible_p(__t2,const char *) \ ||__builtin_types_compatible_p(__t2,const signed char *) \ ||__builtin_types_compatible_p(__t2,const unsigned char *) \ ||__builtin_types_compatible_p(__t2,char []) \ ||__builtin_types_compatible_p(__t2,signed char []) \ ||__builtin_types_compatible_p(__t2,unsigned char []) \ ||__builtin_types_compatible_p(__t2,const char []) \ ||__builtin_types_compatible_p(__t2,const signed char []) \ ||__builtin_types_compatible_p(__t2,const unsigned char []),"%d%s", \ __builtin_choose_expr(__builtin_types_compatible_p(__t2,char) \ ||__builtin_types_compatible_p(__t2,signed char) \ ||__builtin_types_compatible_p(__t2,unsigned char),"%d%c", \ __builtin_choose_expr(__builtin_types_compatible_p(__t2,unsigned short) \ ||__builtin_types_compatible_p(__t2,unsigned int),"%d%u", \ __builtin_choose_expr(__builtin_types_compatible_p(__t2,short) \ ||__builtin_types_compatible_p(__t2,int),"%d%d", \ __builtin_choose_expr(__builtin_types_compatible_p(__t2,unsigned long),"%d%lu", \ __builtin_choose_expr(__builtin_types_compatible_p(__t2,long),"%d%ld", \ __builtin_choose_expr(__builtin_types_compatible_p(__t2,float) \ ||__builtin_types_compatible_p(__t2,double) \ ||__builtin_types_compatible_p(__t2,long double),"%d%g", \ "")))))))), \ __builtin_choose_expr(__builtin_types_compatible_p(__t1,unsigned long), \ (__builtin_choose_expr(__builtin_types_compatible_p(__t2,char *) \ ||__builtin_types_compatible_p(__t2,signed char *) \ ||__builtin_types_compatible_p(__t2,unsigned char *) \ ||__builtin_types_compatible_p(__t2,const char *) \ ||__builtin_types_compatible_p(__t2,const signed char *) \ ||__builtin_types_compatible_p(__t2,const unsigned char *) \ ||__builtin_types_compatible_p(__t2,char []) \ ||__builtin_types_compatible_p(__t2,signed char []) \ ||__builtin_types_compatible_p(__t2,unsigned char []) \ ||__builtin_types_compatible_p(__t2,const char []) \ ||__builtin_types_compatible_p(__t2,const signed char []) \ ||__builtin_types_compatible_p(__t2,const unsigned char []),"%lu%s", \ __builtin_choose_expr(__builtin_types_compatible_p(__t2,char) \ ||__builtin_types_compatible_p(__t2,signed char) \ ||__builtin_types_compatible_p(__t2,unsigned char),"%lu%c", \ __builtin_choose_expr(__builtin_types_compatible_p(__t2,unsigned short) \ ||__builtin_types_compatible_p(__t2,unsigned int),"%lu%u", \ __builtin_choose_expr(__builtin_types_compatible_p(__t2,short) \ ||__builtin_types_compatible_p(__t2,int),"%lu%d", \ __builtin_choose_expr(__builtin_types_compatible_p(__t2,unsigned long),"%lu%lu", \ __builtin_choose_expr(__builtin_types_compatible_p(__t2,long),"%lu%ld", \ __builtin_choose_expr(__builtin_types_compatible_p(__t2,float) \ ||__builtin_types_compatible_p(__t2,double) \ ||__builtin_types_compatible_p(__t2,long double),"%lu%g", \ "")))))))), \ __builtin_choose_expr(__builtin_types_compatible_p(__t1,long), \ (__builtin_choose_expr(__builtin_types_compatible_p(__t2,char *) \ ||__builtin_types_compatible_p(__t2,signed char *) \ ||__builtin_types_compatible_p(__t2,unsigned char *) \ ||__builtin_types_compatible_p(__t2,const char *) \ ||__builtin_types_compatible_p(__t2,const signed char *) \ ||__builtin_types_compatible_p(__t2,const unsigned char *) \ ||__builtin_types_compatible_p(__t2,char []) \ ||__builtin_types_compatible_p(__t2,signed char []) \ ||__builtin_types_compatible_p(__t2,unsigned char []) \ ||__builtin_types_compatible_p(__t2,const char []) \ ||__builtin_types_compatible_p(__t2,const signed char []) \ ||__builtin_types_compatible_p(__t2,const unsigned char []),"%ld%s", \ __builtin_choose_expr(__builtin_types_compatible_p(__t2,char) \ ||__builtin_types_compatible_p(__t2,signed char) \ ||__builtin_types_compatible_p(__t2,unsigned char),"%ld%c", \ __builtin_choose_expr(__builtin_types_compatible_p(__t2,unsigned short) \ ||__builtin_types_compatible_p(__t2,unsigned int),"%ld%u", \ __builtin_choose_expr(__builtin_types_compatible_p(__t2,short) \ ||__builtin_types_compatible_p(__t2,int),"%ld%d", \ __builtin_choose_expr(__builtin_types_compatible_p(__t2,unsigned long),"%ld%lu", \ __builtin_choose_expr(__builtin_types_compatible_p(__t2,long),"%ld%ld", \ __builtin_choose_expr(__builtin_types_compatible_p(__t2,float) \ ||__builtin_types_compatible_p(__t2,double) \ ||__builtin_types_compatible_p(__t2,long double),"%ld%g", \ "")))))))), \ __builtin_choose_expr(__builtin_types_compatible_p(__t1,float) \ ||__builtin_types_compatible_p(__t1,double) \ ||__builtin_types_compatible_p(__t1,long double), \ (__builtin_choose_expr(__builtin_types_compatible_p(__t2,char *) \ ||__builtin_types_compatible_p(__t2,signed char *) \ ||__builtin_types_compatible_p(__t2,unsigned char *) \ ||__builtin_types_compatible_p(__t2,const char *) \ ||__builtin_types_compatible_p(__t2,const signed char *) \ ||__builtin_types_compatible_p(__t2,const unsigned char *) \ ||__builtin_types_compatible_p(__t2,char []) \ ||__builtin_types_compatible_p(__t2,signed char []) \ ||__builtin_types_compatible_p(__t2,unsigned char []) \ ||__builtin_types_compatible_p(__t2,const char []) \ ||__builtin_types_compatible_p(__t2,const signed char []) \ ||__builtin_types_compatible_p(__t2,const unsigned char []),"%g%s", \ __builtin_choose_expr(__builtin_types_compatible_p(__t2,char) \ ||__builtin_types_compatible_p(__t2,signed char) \ ||__builtin_types_compatible_p(__t2,unsigned char),"%g%c", \ __builtin_choose_expr(__builtin_types_compatible_p(__t2,unsigned short) \ ||__builtin_types_compatible_p(__t2,unsigned int),"%g%u", \ __builtin_choose_expr(__builtin_types_compatible_p(__t2,short) \ ||__builtin_types_compatible_p(__t2,int),"%g%d", \ __builtin_choose_expr(__builtin_types_compatible_p(__t2,unsigned long),"%g%lu", \ __builtin_choose_expr(__builtin_types_compatible_p(__t2,long),"%g%ld", \ __builtin_choose_expr(__builtin_types_compatible_p(__t2,float) \ ||__builtin_types_compatible_p(__t2,double) \ ||__builtin_types_compatible_p(__t2,long double),"%g%g", \ "")))))))), \ "")))))))) #define C(__val1,__val2) ({ \ __typeof__((__val1)+0) __v1=__val1; \ __typeof__((__val2)+0) __v2=__val2; \ char *__result=__builtin_alloca(__strsize(__v1,__typeof__((__val1)))+__strsize(__v2,__typeof__((__val2)))+1); \ sprintf(__result,__strfmt2(__typeof__((__val1)),__typeof__((__val2))),__v1,__v2); \ __result;})