ir_instr_delete_quick needs to clear _m_ops
[xonotic/gmqcc.git] / gmqcc.h
1 #ifndef GMQCC_HDR
2 #define GMQCC_HDR
3 #include <vector>
4 #include <string>
5 #include <utility>
6 #include <memory>
7 using std::move;
8 #include <stdarg.h>
9 #include <stddef.h>
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <time.h>
13
14 #define GMQCC_VERSION_MAJOR 0
15 #define GMQCC_VERSION_MINOR 3
16 #define GMQCC_VERSION_PATCH 6
17 #define GMQCC_VERSION ((GMQCC_VERSION_MAJOR<<16)|(GMQCC_VERSION_MINOR<<8)|GMQCC_VERSION_PATCH)
18
19 #ifdef GMQCC_VERSION_TYPE_RELEASE
20 #    ifdef GMQCC_GITINFO
21 #        define GMQCC_DEV_VERSION_STRING "git build: " GMQCC_GITINFO "\n"
22 #    elif defined(GMQCC_VERSION_TYPE_DEVEL)
23 #        define GMQCC_DEV_VERSION_STRING "development build\n"
24 #    else
25 #        define GMQCC_DEV_VERSION_STRING
26 #    endif /*! GMQCC_GITINGO */
27 #else
28 #    define GMQCC_DEV_VERSION_STRING
29 #endif
30
31 #define GMQCC_STRINGIFY(x) #x
32 #define GMQCC_IND_STRING(x) GMQCC_STRINGIFY(x)
33 #define GMQCC_FULL_VERSION_STRING \
34 "GMQCC " \
35 GMQCC_IND_STRING(GMQCC_VERSION_MAJOR) "." \
36 GMQCC_IND_STRING(GMQCC_VERSION_MINOR) "." \
37 GMQCC_IND_STRING(GMQCC_VERSION_PATCH) \
38 " Built " __DATE__ " " __TIME__ \
39 "\n" GMQCC_DEV_VERSION_STRING
40
41 #ifndef __cplusplus
42 #   define false (unsigned char)(0)
43 #   define true  (unsigned char)(1)
44     typedef unsigned char bool;
45 #endif
46
47 #if defined(__GNUC__) || defined(__CLANG__)
48 #   include <stdint.h>
49 #   if (__GNUC__ >= 2) || defined(__CLANG__)
50 #       define GMQCC_NORETURN    __attribute__((noreturn))
51 #       define GMQCC_FORCEINLINE __attribute__((always_inline))
52 #       define GMQCC_INLINE      __inline
53 #   endif
54 #   define GMQCC_LIKELY(X)   __builtin_expect((X), 1)
55 #   define GMQCC_UNLIKELY(X) __builtin_expect((X), 0)
56 #   define GMQCC_WARN        __attribute__((warn_unused_result))
57 #   define GMQCC_USED        __attribute__((used))
58 #   define GMQCC_RESTRICT    __restrict__
59 #else
60 #   ifdef _MSC_VER
61         /* conversion from 'int' to 'float', possible loss of data */
62 #       pragma warning(disable : 4244)
63
64         typedef unsigned __int8  uint8_t;
65         typedef unsigned __int16 uint16_t;
66         typedef unsigned __int32 uint32_t;
67         typedef unsigned __int64 uint64_t;
68         typedef __int16          int16_t;
69         typedef __int32          int32_t;
70         typedef __int64          int64_t;
71 #       define GMQCC_NORETURN    __declspec(noreturn)
72 #       define GMQCC_FORCEINLINE __forceinline
73 #       define GMQCC_INLINE      __inline
74 #       define GMQCC_RESTRICT    __restrict
75 #   else
76 #       define GMQCC_NORETURN
77 #       define GMQCC_FORCEINLINE
78 #       define GMQCC_INLINE
79 #       define GMQCC_RESTRICT
80 #   endif
81 #   define GMQCC_LIKELY(X)   (X)
82 #   define GMQCC_UNLIKELY(X) (X)
83 #   define GMQCC_WARN
84 #   define GMQCC_USED
85 #endif
86
87 #define GMQCC_BYTE_ORDER_LITTLE 1234
88 #define GMQCC_BYTE_ORDER_BIG    4321
89
90 #if defined (__GNUC__) || defined (__GNU_LIBRARY__)
91 #   if defined (__FreeBSD__) || defined (__OpenBSD__)
92 #       include <sys/endian.h>
93 #   elif defined (BSD) && (BSD >= 199103) || defined (__DJGPP__) || defined (__CYGWIN32__)
94 #       include <machine/endian.h>
95 #   elif defined (__APPLE__)
96 #       if defined (__BIG_ENDIAN__) && !defined(BIG_ENDIAN)
97 #           define BIG_ENDIAN
98 #       elif defined (__LITTLE_ENDIAN__) && !defined (LITTLE_ENDIAN)
99 #           define LITTLE_ENDIAN
100 #       endif /*! defined (__BIG_ENDIAN__) && !defined(BIG_ENDIAN) */
101 #   elif !defined (__MINGW32__)
102 #       include <endian.h>
103 #       if !defined (__BEOS__)
104 #           include <byteswap.h>
105 #       endif /*! !definde (__BEOS__) */
106 #   endif /*! defined (__FreeBSD__) || defined (__OpenBSD__) */
107 #endif /*! defined (__GNUC__) || defined (__GNU_LIBRARY__) */
108 #if !defined(PLATFORM_BYTE_ORDER)
109 #   if defined (LITTLE_ENDIAN) || defined (BIG_ENDIAN)
110 #       if defined (LITTLE_ENDIAN) && !defined(BIG_ENDIAN)
111 #           define PLATFORM_BYTE_ORDER GMQCC_BYTE_ORDER_LITTLE
112 #       elif !defined (LITTLE_ENDIAN) && defined (BIG_ENDIAN)
113 #           define PLATFORM_BYTE_ORDER GMQCC_BYTE_ORDER_BIG
114 #       elif defined (BYTE_ORDER) && (BYTE_ORDER == LITTLE_ENDIAN)
115 #           define PLATFORM_BYTE_ORDER GMQCC_BYTE_ORDER_LITTLE
116 #       elif defined (BYTE_ORDER) && (BYTE_ORDER == BIG_ENDIAN)
117 #           define PLATFORM_BYTE_ORDER GMQCC_BYTE_ORDER_BIG
118 #       endif /*! defined (LITTLE_ENDIAN) && !defined(BIG_ENDIAN) */
119 #   elif defined (_LITTLE_ENDIAN) || defined (_BIG_ENDIAN)
120 #       if defined (_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)
121 #           define PLATFORM_BYTE_ORDER GMQCC_BYTE_ORDER_LITTLE
122 #       elif !defined (_LITTLE_ENDIAN) && defined (_BIG_ENDIAN)
123 #           define PLATFORM_BYTE_ORDER GMQCC_BYTE_ORDER_BIG
124 #       elif defined (_BYTE_ORDER) && (_BYTE_ORDER == _LITTLE_ENDIAN)
125 #           define PLATFORM_BYTE_ORDER GMQCC_BYTE_ORDER_LITTLE
126 #       elif defined (_BYTE_ORDER) && (_BYTE_ORDER == _BIG_ENDIAN)
127 #           define PLATFORM_BYTE_ORDER GMQCC_BYTE_ORDER_BIG
128 #       endif /*! defined (_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN) */
129 #   elif defined (__LITTLE_ENDIAN__) || defined (__BIG_ENDIAN__)
130 #       if defined (__LITTLE_ENDIAN__) && !defined (__BIG_ENDIAN__)
131 #           define PLATFORM_BYTE_ORDER GMQCC_BYTE_ORDER_LITTLE
132 #       elif !defined (__LITTLE_ENDIAN__) && defined (__BIG_ENDIAN__)
133 #           define PLATFORM_BYTE_ORDER GMQCC_BYTE_ORDER_BIG
134 #       elif defined (__BYTE_ORDER__) && (__BYTE_ORDER__ == __LITTLE_ENDIAN__)
135 #           define PLATFORM_BYTE_ORDER GMQCC_BYTE_ORDER_LITTLE
136 #       elif defined (__BYTE_ORDER__) && (__BYTE_ORDER__ == __BIG_ENDIAN__)
137 #           define PLATFORM_BYTE_ORDER GMQCC_BYTE_ORDER_BIG
138 #       endif /*! defined (__LITTLE_ENDIAN__) && !defined (__BIG_ENDIAN__) */
139 #   endif /*! defined(LITTLE_ENDIAN) || defined (BIG_ENDIAN) */
140 #endif /*! !defined(PLATFORM_BYTE_ORDER) */
141 #if !defined (PLATFORM_BYTE_ORDER)
142 #   if   defined (__alpha__) || defined (__alpha)    || defined (i386)       || \
143          defined (__i386__)  || defined (_M_I86)     || defined (_M_IX86)    || \
144          defined (__OS2__)   || defined (sun386)     || defined (__TURBOC__) || \
145          defined (vax)       || defined (vms)        || defined (VMS)        || \
146          defined (__VMS)     || defined (__x86_64__) || defined (_M_IA64)    || \
147          defined (_M_X64)    || defined (__i386)     || defined (__x86_64)
148 #       define PLATFORM_BYTE_ORDER GMQCC_BYTE_ORDER_LITTLE
149 #   elif defined (AMIGA)     || defined (applec)     || defined (__AS400__)  || \
150          defined (_CRAY)     || defined (__hppa)     || defined (__hp9000)   || \
151          defined (ibm370)    || defined (mc68000)    || defined (m68k)       || \
152          defined (__MRC__)   || defined (__MVS__)    || defined (__MWERKS__) || \
153          defined (sparc)     || defined (__sparc)    || defined (SYMANTEC_C) || \
154          defined (__TANDEM)  || defined (THINK_C)    || defined (__VMCMS__)  || \
155          defined (__PPC__)   || defined (__PPC)      || defined (PPC)
156 #       define PLATFORM_BYTE_ORDER GMQCC_BYTE_ORDER_BIG
157 #   else
158 #       define PLATFORM_BYTE_ORDER -1
159 #   endif
160 #endif
161
162 #define GMQCC_ARRAY_COUNT(X) (sizeof(X) / sizeof((X)[0]))
163
164 /* stat.c */
165 char *stat_mem_strdup(const char *, bool);
166
167 #define mem_a(SIZE)              malloc(SIZE)
168 #define mem_d(PTRN)              free((void*)PTRN)
169 #define mem_r(PTRN, SIZE)        realloc((void*)PTRN, SIZE)
170
171 #define util_strdup(SRC)         stat_mem_strdup((char*)(SRC), false)
172 #define util_strdupe(SRC)        stat_mem_strdup((char*)(SRC), true)
173
174 #define util_isalpha(a) ((((unsigned)(a)|32)-'a') < 26)
175 #define util_isdigit(a) (((unsigned)(a)-'0') < 10)
176 #define util_islower(a) (((unsigned)(a)-'a') < 26)
177 #define util_isupper(a) (((unsigned)(a)-'A') < 26)
178 #define util_isprint(a) (((unsigned)(a)-0x20) < 0x5F)
179 #define util_isspace(a) (((a) >= 9 && (a) <= 13) || (a) == ' ')
180
181 bool  util_strupper(const char *);
182 bool  util_strdigit(const char *);
183
184 void  util_endianswap(void *, size_t, unsigned int);
185
186 size_t util_strtocmd         (const char *, char *, size_t);
187 size_t util_strtononcmd      (const char *, char *, size_t);
188 size_t util_optimizationtostr(const char *, char *, size_t);
189
190 uint16_t util_crc16(uint16_t crc, const char *data, size_t len);
191
192 void     util_seed(uint32_t);
193 uint32_t util_rand(void);
194
195 int      util_asprintf (char **ret, const char *fmt, ...);
196 int      util_sscanf   (const char *str, const char *format, ...);
197 char    *util_strncpy  (char *dest, const char *src, size_t n);
198 char    *util_strncat  (char *dest, const char *src, size_t n);
199 char    *util_strcat   (char *dest, const char *src);
200 const char *util_strerror(int err);
201
202 const struct tm *util_localtime(const time_t *timer);
203 const char      *util_ctime    (const time_t *timer);
204
205 bool             util_isatty(FILE *);
206 size_t           hash(const char *key);
207
208 /*
209  * A flexible vector implementation: all vector pointers contain some
210  * data about themselfs exactly - sizeof(vector_t) behind the pointer
211  * this data is represented in the structure below.  Doing this allows
212  * us to use the array [] to access individual elements from the vector
213  * opposed to using set/get methods.
214  */
215 struct vector_t {
216     size_t  allocated;
217     size_t  used;
218
219     /* can be extended now! whoot */
220 };
221
222 /* hidden interface */
223 void _util_vec_grow(void **a, size_t i, size_t s);
224 void _util_vec_delete(void *vec);
225
226 #define GMQCC_VEC_WILLGROW(X, Y) ( \
227     ((!(X) || vec_meta(X)->used + Y >= vec_meta(X)->allocated)) ? \
228         (void)_util_vec_grow(((void**)&(X)), (Y), sizeof(*(X))) : \
229         (void)0                                                   \
230 )
231
232 /* exposed interface */
233 #define vec_meta(A)       ((vector_t*)(((char *)(A)) - sizeof(vector_t)))
234 #define vec_free(A)       ((void)((A) ? (_util_vec_delete((void *)(A)), (A) = nullptr) : 0))
235 #define vec_push(A,V)     (GMQCC_VEC_WILLGROW((A),1), (A)[vec_meta(A)->used++] = (V))
236 #define vec_size(A)       ((A) ? vec_meta(A)->used : 0)
237 #define vec_add(A,N)      (GMQCC_VEC_WILLGROW((A),(N)), vec_meta(A)->used += (N), &(A)[vec_meta(A)->used-(N)])
238 #define vec_last(A)       ((A)[vec_meta(A)->used - 1])
239 #define vec_pop(A)        ((void)(vec_meta(A)->used -= 1))
240 #define vec_shrinkto(A,N) ((void)(vec_meta(A)->used  = (N)))
241 #define vec_shrinkby(A,N) ((void)(vec_meta(A)->used -= (N)))
242 #define vec_append(A,N,S) ((void)(memcpy(vec_add((A), (N)), (S), (N) * sizeof(*(S)))))
243 #define vec_remove(A,I,N) ((void)(memmove((A)+(I),(A)+((I)+(N)),sizeof(*(A))*(vec_meta(A)->used-(I)-(N))),vec_meta(A)->used-=(N)))
244
245 typedef struct hash_table_s {
246     size_t                size;
247     struct hash_node_t **table;
248 } hash_table_t, *ht;
249
250 hash_table_t *util_htnew (size_t size);
251 void util_htrem(hash_table_t *ht, void (*callback)(void *data));
252 void util_htset(hash_table_t *ht, const char *key, void *value);
253 void util_htdel(hash_table_t *ht);
254 size_t util_hthash(hash_table_t *ht, const char *key);
255 void util_htseth(hash_table_t *ht, const char *key, size_t hash, void *value);
256 void util_htrmh(hash_table_t *ht, const char *key, size_t bin, void (*cb)(void*));
257 void util_htrm(hash_table_t *ht, const char *key, void (*cb)(void*));
258 void *util_htget(hash_table_t *ht, const char *key);
259 void *util_htgeth(hash_table_t *ht, const char *key, size_t hash);
260 int util_snprintf(char *str, size_t, const char *fmt, ...);
261 int util_getline(char  **, size_t *, FILE *);
262
263 /* code.c */
264
265 /* Note: if you change the order, fix type_sizeof in ir.c */
266 enum qc_type {
267     TYPE_VOID     ,
268     TYPE_STRING   ,
269     TYPE_FLOAT    ,
270     TYPE_VECTOR   ,
271     TYPE_ENTITY   ,
272     TYPE_FIELD    ,
273     TYPE_FUNCTION ,
274     TYPE_POINTER  ,
275     TYPE_INTEGER  ,
276     TYPE_VARIANT  ,
277     TYPE_STRUCT   ,
278     TYPE_UNION    ,
279     TYPE_ARRAY    ,
280
281     TYPE_NIL      , /* it's its own type / untyped */
282     TYPE_NOEXPR   , /* simply invalid in expressions */
283
284     TYPE_COUNT
285 };
286
287 /* const/var qualifiers */
288 #define CV_NONE   0
289 #define CV_CONST  1
290 #define CV_VAR   -1