Zen-C
Loading...
Searching...
No Matches
compat.h
Go to the documentation of this file.
1
2#ifndef ZC_COMPAT_H
3#define ZC_COMPAT_H
4
5#ifdef __cplusplus
6/* C++ mode */
7#define ZC_AUTO auto
8#define ZC_CAST(T, x) static_cast<T>(x)
9#define ZC_REINTERPRET(T, x) reinterpret_cast<T>(x)
10#define ZC_EXTERN_C extern "C"
11#define ZC_EXTERN_C_BEGIN \
12 extern "C" \
13 {
14#define ZC_EXTERN_C_END }
15#else
16/* C mode */
17#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202300L
18#define ZC_AUTO auto
19#else
20#define ZC_AUTO __auto_type
21#endif
22#define ZC_CAST(T, x) ((T)(x))
23#define ZC_REINTERPRET(T, x) ((T)(x))
24#define ZC_EXTERN_C
25#define ZC_EXTERN_C_BEGIN
26#define ZC_EXTERN_C_END
27#endif
28
29#ifdef __TINYC__
30/* TCC compatibility */
31#ifndef __auto_type
32#define __auto_type __typeof__
33#endif
34
35#ifndef __builtin_expect
36#define __builtin_expect(x, v) (x)
37#endif
38
39#ifndef __builtin_unreachable
40#define __builtin_unreachable()
41#endif
42#endif
43
44/* Centralized string definition for codegen emission */
45#define ZC_TCC_COMPAT_STR \
46 "#ifdef __TINYC__\n" \
47 "#ifndef __auto_type\n" \
48 "#define __auto_type __typeof__\n" \
49 "#endif\n" \
50 "\n" \
51 "#ifndef __builtin_expect\n" \
52 "#define __builtin_expect(x, v) (x)\n" \
53 "#endif\n" \
54 "\n" \
55 "#ifndef __builtin_unreachable\n" \
56 "#define __builtin_unreachable()\n" \
57 "#endif\n" \
58 "#endif\n"
59
60/* Generic selection string for C mode */
61#define ZC_C_GENERIC_STR \
62 "#ifdef __OBJC__\n" \
63 "#define _z_objc_map ,id: \"%s\", Class: \"%s\", SEL: \"%s\"\n" \
64 "#define _z_objc_arg_map(x) ,id: [(id)(x) description].UTF8String, Class: " \
65 "class_getName((Class)(x)), SEL: sel_getName((SEL)(x))\n" \
66 "#else\n" \
67 "#define _z_objc_map\n" \
68 "#define _z_objc_arg_map(x)\n" \
69 "#endif\n" \
70 "\n" \
71 "#define _z_str(x) _Generic((x), _Bool: \"%s\", char: \"%c\", " \
72 "signed char: \"%c\", unsigned char: \"%u\", short: \"%d\", " \
73 "unsigned short: \"%u\", int: \"%d\", unsigned int: \"%u\", " \
74 "long: \"%ld\", unsigned long: \"%lu\", long long: \"%lld\", " \
75 "unsigned long long: \"%llu\", float: \"%f\", double: \"%f\", " \
76 "char*: \"%s\", void*: \"%p\" _z_objc_map)\n"
77
78#define ZC_C_ARG_GENERIC_STR \
79 "#define _z_arg(x) _Generic((x), _Bool: _z_bool_str(x) _z_objc_arg_map(x), default: (x))\n"
80
81#ifdef __cplusplus
82#include <type_traits>
83
84inline const char *_zc_fmt(bool)
85{
86 return "%d";
87}
88inline const char *_zc_fmt(char)
89{
90 return "%c";
91}
92inline const char *_zc_fmt(signed char)
93{
94 return "%c";
95}
96inline const char *_zc_fmt(unsigned char)
97{
98 return "%u";
99}
100inline const char *_zc_fmt(short)
101{
102 return "%d";
103}
104inline const char *_zc_fmt(unsigned short)
105{
106 return "%u";
107}
108inline const char *_zc_fmt(int)
109{
110 return "%d";
111}
112inline const char *_zc_fmt(unsigned int)
113{
114 return "%u";
115}
116inline const char *_zc_fmt(long)
117{
118 return "%ld";
119}
120inline const char *_zc_fmt(unsigned long)
121{
122 return "%lu";
123}
124inline const char *_zc_fmt(long long)
125{
126 return "%lld";
127}
128inline const char *_zc_fmt(unsigned long long)
129{
130 return "%llu";
131}
132inline const char *_zc_fmt(float)
133{
134 return "%f";
135}
136inline const char *_zc_fmt(double)
137{
138 return "%f";
139}
140inline const char *_zc_fmt(char *)
141{
142 return "%s";
143}
144inline const char *_zc_fmt(const char *)
145{
146 return "%s";
147}
148inline const char *_zc_fmt(void *)
149{
150 return "%p";
151}
152
153#define _z_str(x) _zc_fmt(x)
154
155#ifdef __OBJC__
156#include <objc/objc.h>
157#include <objc/runtime.h>
158#include <objc/message.h> // for direct calls if needed, but [x description] is fine
159
160inline const char *_zc_fmt(id x)
161{
162 return [[x description] UTF8String];
163}
164inline const char *_zc_fmt(Class x)
165{
166 return class_getName(x);
167}
168inline const char *_zc_fmt(SEL x)
169{
170 return sel_getName(x);
171}
172// BOOL is signed char usually, already handled?
173// "typedef signed char BOOL;" on standard apple headers.
174// If it maps to signed char, `_zc_fmt(signed char)` handles it ("%c").
175// We might want "YES"/"NO" for BOOL.
176// But we can't distinguish typedefs in C++ function overloads easily if underlying type is same.
177// We'll leave BOOL as %c or %d for now to avoid ambiguity errors.
178#endif
179
180#endif
181
182#endif