]> git.xonotic.org Git - xonotic/gmqcc.git/blob - gmqcc.h
cleanup
[xonotic/gmqcc.git] / gmqcc.h
1 /*
2  * Copyright (C) 2012, 2013
3  *     Dale Weiler
4  *     Wolfgang Bumiller
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy of
7  * this software and associated documentation files (the "Software"), to deal in
8  * the Software without restriction, including without limitation the rights to
9  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
10  * of the Software, and to permit persons to whom the Software is furnished to do
11  * so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in all
14  * copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
24 #ifndef GMQCC_HDR
25 #define GMQCC_HDR
26 #include <stdarg.h>
27 #include <stddef.h>
28 #include <time.h>
29
30 #define GMQCC_VERSION_MAJOR 0
31 #define GMQCC_VERSION_MINOR 3
32 #define GMQCC_VERSION_PATCH 6
33 #define GMQCC_VERSION ((GMQCC_VERSION_MAJOR<<16)|(GMQCC_VERSION_MINOR<<8)|GMQCC_VERSION_PATCH)
34
35 #ifdef GMQCC_VERSION_TYPE_RELEASE
36 #    ifdef GMQCC_GITINFO
37 #        define GMQCC_DEV_VERSION_STRING "git build: " GMQCC_GITINFO "\n"
38 #    elif defined(GMQCC_VERSION_TYPE_DEVEL)
39 #        define GMQCC_DEV_VERSION_STRING "development build\n"
40 #    else
41 #        define GMQCC_DEV_VERSION_STRING
42 #    endif /*! GMQCC_GITINGO */
43 #else
44 #    define GMQCC_DEV_VERSION_STRING
45 #endif
46
47 #define GMQCC_STRINGIFY(x) #x
48 #define GMQCC_IND_STRING(x) GMQCC_STRINGIFY(x)
49 #define GMQCC_FULL_VERSION_STRING \
50 "GMQCC " \
51 GMQCC_IND_STRING(GMQCC_VERSION_MAJOR) "." \
52 GMQCC_IND_STRING(GMQCC_VERSION_MINOR) "." \
53 GMQCC_IND_STRING(GMQCC_VERSION_PATCH) \
54 " Built " __DATE__ " " __TIME__ \
55 "\n" GMQCC_DEV_VERSION_STRING
56
57 #ifndef __cplusplus
58 #   define false (unsigned char)(0)
59 #   define true  (unsigned char)(1)
60     typedef unsigned char bool;
61 #endif
62
63 #if defined(__GNUC__) || defined(__CLANG__)
64 #   include <stdint.h>
65 #   if (__GNUC__ >= 2) || defined(__CLANG__)
66 #       define GMQCC_NORETURN    __attribute__((noreturn))
67 #       define GMQCC_FORCEINLINE __attribute__((always_inline))
68 #       define GMQCC_INLINE      __inline
69 #   endif
70 #   define GMQCC_LIKELY(X)   __builtin_expect((X), 1)
71 #   define GMQCC_UNLIKELY(X) __builtin_expect((X), 0)
72 #   define GMQCC_WARN        __attribute__((warn_unused_result))
73 #   define GMQCC_USED        __attribute__((used))
74 #   define GMQCC_RESTRICT    __restrict__
75 #else
76 #   ifdef _MSC_VER
77         /* conversion from 'int' to 'float', possible loss of data */
78 #       pragma warning(disable : 4244 )
79
80         typedef unsigned __int8  uint8_t;
81         typedef unsigned __int16 uint16_t;
82         typedef unsigned __int32 uint32_t;
83         typedef unsigned __int64 uint64_t;
84         typedef __int16          int16_t;
85         typedef __int32          int32_t;
86         typedef __int64          int64_t;
87 #       define GMQCC_NORETURN    __declspec(noreturn)
88 #       define GMQCC_FORCEINLINE __forceinline
89 #       define GMQCC_INLINE      __inline
90 #       define GMQCC_RESTRICT    __restrict
91 #   endif
92 #   define GMQCC_LIKELY(X)   (X)
93 #   define GMQCC_UNLIKELY(X) (X)
94 #   define GMQCC_WARN
95 #   define GMQCC_USED
96 #endif
97
98 #define GMQCC_BYTE_ORDER_LITTLE 1234
99 #define GMQCC_BYTE_ORDER_BIG    4321
100
101 #if defined (__GNUC__) || defined (__GNU_LIBRARY__)
102 #   if defined (__FreeBSD__) || defined (__OpenBSD__)
103 #       include <sys/endian.h>
104 #   elif defined (BSD) && (BSD >= 199103) || defined (__DJGPP__) || defined (__CYGWIN32__)
105 #       include <machine/endian.h>
106 #   elif defined (__APPLE__)
107 #       if defined (__BIG_ENDIAN__) && !defined(BIG_ENDIAN)
108 #           define BIG_ENDIAN
109 #       elif defined (__LITTLE_ENDIAN__) && !defined (LITTLE_ENDIAN)
110 #           define LITTLE_ENDIAN
111 #       endif /*! defined (__BIG_ENDIAN__) && !defined(BIG_ENDIAN) */
112 #   elif !defined (__MINGW32__)
113 #       include <endian.h>
114 #       if !defined (__BEOS__)
115 #           include <byteswap.h>
116 #       endif /*! !definde (__BEOS__) */
117 #   endif /*! defined (__FreeBSD__) || defined (__OpenBSD__) */
118 #endif /*! defined (__GNUC__) || defined (__GNU_LIBRARY__) */
119 #if !defined(PLATFORM_BYTE_ORDER)
120 #   if defined (LITTLE_ENDIAN) || defined (BIG_ENDIAN)
121 #       if defined (LITTLE_ENDIAN) && !defined(BIG_ENDIAN)
122 #           define PLATFORM_BYTE_ORDER GMQCC_BYTE_ORDER_LITTLE
123 #       elif !defined (LITTLE_ENDIAN) && defined (BIG_ENDIAN)
124 #           define PLATFORM_BYTE_ORDER GMQCC_BYTE_ORDER_BIG
125 #       elif defined (BYTE_ORDER) && (BYTE_ORDER == LITTLE_ENDIAN)
126 #           define PLATFORM_BYTE_ORDER GMQCC_BYTE_ORDER_LITTLE
127 #       elif defined (BYTE_ORDER) && (BYTE_ORDER == BIG_ENDIAN)
128 #           define PLATFORM_BYTE_ORDER GMQCC_BYTE_ORDER_BIG
129 #       endif /*! defined (LITTLE_ENDIAN) && !defined(BIG_ENDIAN) */
130 #   elif defined (_LITTLE_ENDIAN) || defined (_BIG_ENDIAN)
131 #       if defined (_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)
132 #           define PLATFORM_BYTE_ORDER GMQCC_BYTE_ORDER_LITTLE
133 #       elif !defined (_LITTLE_ENDIAN) && defined (_BIG_ENDIAN)
134 #           define PLATFORM_BYTE_ORDER GMQCC_BYTE_ORDER_BIG
135 #       elif defined (_BYTE_ORDER) && (_BYTE_ORDER == _LITTLE_ENDIAN)
136 #           define PLATFORM_BYTE_ORDER GMQCC_BYTE_ORDER_LITTLE
137 #       elif defined (_BYTE_ORDER) && (_BYTE_ORDER == _BIG_ENDIAN)
138 #           define PLATFORM_BYTE_ORDER GMQCC_BYTE_ORDER_BIG
139 #       endif /*! defined (_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN) */
140 #   elif defined (__LITTLE_ENDIAN__) || defined (__BIG_ENDIAN__)
141 #       if defined (__LITTLE_ENDIAN__) && !defined (__BIG_ENDIAN__)
142 #           define PLATFORM_BYTE_ORDER GMQCC_BYTE_ORDER_LITTLE
143 #       elif !defined (__LITTLE_ENDIAN__) && defined (__BIG_ENDIAN__)
144 #           define PLATFORM_BYTE_ORDER GMQCC_BYTE_ORDER_BIG
145 #       elif defined (__BYTE_ORDER__) && (__BYTE_ORDER__ == __LITTLE_ENDIAN__)
146 #           define PLATFORM_BYTE_ORDER GMQCC_BYTE_ORDER_LITTLE
147 #       elif defined (__BYTE_ORDER__) && (__BYTE_ORDER__ == __BIG_ENDIAN__)
148 #           define PLATFORM_BYTE_ORDER GMQCC_BYTE_ORDER_BIG
149 #       endif /*! defined (__LITTLE_ENDIAN__) && !defined (__BIG_ENDIAN__) */
150 #   endif /*! defined(LITTLE_ENDIAN) || defined (BIG_ENDIAN) */
151 #endif /*! !defined(PLATFORM_BYTE_ORDER) */
152 #if !defined (PLATFORM_BYTE_ORDER)
153 #   if   defined (__alpha__) || defined (__alpha)    || defined (i386)       || \
154          defined (__i386__)  || defined (_M_I86)     || defined (_M_IX86)    || \
155          defined (__OS2__)   || defined (sun386)     || defined (__TURBOC__) || \
156          defined (vax)       || defined (vms)        || defined (VMS)        || \
157          defined (__VMS)     || defined (__x86_64__) || defined (_M_IA64)    || \
158          defined (_M_X64)    || defined (__i386)     || defined (__x86_64)
159 #       define PLATFORM_BYTE_ORDER GMQCC_BYTE_ORDER_LITTLE
160 #   elif defined (AMIGA)     || defined (applec)     || defined (__AS400__)  || \
161          defined (_CRAY)     || defined (__hppa)     || defined (__hp9000)   || \
162          defined (ibm370)    || defined (mc68000)    || defined (m68k)       || \
163          defined (__MRC__)   || defined (__MVS__)    || defined (__MWERKS__) || \
164          defined (sparc)     || defined (__sparc)    || defined (SYMANTEC_C) || \
165          defined (__TANDEM)  || defined (THINK_C)    || defined (__VMCMS__)  || \
166          defined (__PPC__)   || defined (__PPC)      || defined (PPC)
167 #       define PLATFORM_BYTE_ORDER GMQCC_BYTE_ORDER_BIG
168 #   else
169 #       define PLATFORM_BYTE_ORDER -1
170 #   endif
171 #endif
172
173 #define GMQCC_ARRAY_COUNT(X) (sizeof(X) / sizeof((X)[0]))
174
175 /* stat.c */
176 void  stat_info          (void);
177 char *stat_mem_strdup    (const char *, size_t,         const char *, bool);
178 void *stat_mem_reallocate(void *,       size_t, size_t, const char *, const char *);
179 void  stat_mem_deallocate(void *);
180 void *stat_mem_allocate  (size_t, size_t, const char *, const char *);
181
182 #define mem_a(SIZE)              stat_mem_allocate  ((SIZE), __LINE__, __FILE__, #SIZE)
183 #define mem_d(PTRN)              stat_mem_deallocate((void*)(PTRN))
184 #define mem_r(PTRN, SIZE)        stat_mem_reallocate((void*)(PTRN), (SIZE), __LINE__, __FILE__, #SIZE)
185 #define mem_af(SIZE, FILE, LINE) stat_mem_allocate  ((SIZE), (LINE), (FILE), #SIZE)
186
187 /* TODO: rename to mem variations */
188 #define util_strdup(SRC)         stat_mem_strdup((char*)(SRC), __LINE__, __FILE__, false)
189 #define util_strdupe(SRC)        stat_mem_strdup((char*)(SRC), __LINE__, __FILE__, true)
190
191 /* util.c */
192
193 /*
194  * Microsoft implements against the spec versions of ctype.h. Which
195  * means what ever the current set locale is will render the actual
196  * results of say isalpha('A') wrong for what ever retarded locale
197  * is used. Simalerly these are also implemented inefficently on
198  * some toolchains and end up becoming actual library calls. Perhaps
199  * this is why tools like yacc provide their own? Regardless implementing
200  * these as functions is equally as silly, the call overhead is not
201  * justified when this could happen on every character from an input
202  * stream. We provide our own as macros for absolute inlinability.
203  */
204 #define util_isalpha(a) ((((unsigned)(a)|32)-'a') < 26)
205 #define util_isdigit(a) (((unsigned)(a)-'0') < 10)
206 #define util_islower(a) (((unsigned)(a)-'a') < 26)
207 #define util_isupper(a) (((unsigned)(a)-'A') < 26)
208 #define util_isprint(a) (((unsigned)(a)-0x20) < 0x5F)
209 #define util_isspace(a) (((a) >= 9 && (a) <= 13) || (a) == ' ')
210
211 bool  util_strupper      (const char *);
212 bool  util_strdigit      (const char *);
213 void  util_endianswap    (void *, size_t, unsigned int);
214
215 size_t util_strtocmd         (const char *, char *, size_t);
216 size_t util_strtononcmd      (const char *, char *, size_t);
217 size_t util_optimizationtostr(const char *, char *, size_t);
218
219 uint16_t util_crc16(uint16_t crc, const char *data, size_t len);
220
221 void     util_seed(uint32_t);
222 uint32_t util_rand(void);
223
224 int      util_asprintf (char **ret, const char *fmt, ...);
225 int      util_sscanf   (const char *str, const char *format, ...);
226 char    *util_strncpy  (char *dest, const char *src, size_t n);
227 char    *util_strncat  (char *dest, const char *src, size_t n);
228 char    *util_strcat   (char *dest, const char *src);
229 const char *util_strerror(int err);
230
231 const struct tm *util_localtime(const time_t *timer);
232 const char      *util_ctime    (const time_t *timer);
233
234 typedef struct fs_file_s fs_file_t;
235
236 bool             util_isatty(fs_file_t *);
237
238 /*
239  * A flexible vector implementation: all vector pointers contain some
240  * data about themselfs exactly - sizeof(vector_t) behind the pointer
241  * this data is represented in the structure below.  Doing this allows
242  * us to use the array [] to access individual elements from the vector
243  * opposed to using set/get methods.
244  */
245 typedef struct {
246     size_t  allocated;
247     size_t  used;
248
249     /* can be extended now! whoot */
250 } vector_t;
251
252 /* hidden interface */
253 void _util_vec_grow(void **a, size_t i, size_t s);
254 #define GMQCC_VEC_WILLGROW(X,Y) ( \
255     ((!(X) || vec_meta(X)->used + Y >= vec_meta(X)->allocated)) ? \
256         (void)_util_vec_grow(((void**)&(X)), (Y), sizeof(*(X))) : \
257         (void)0                                                   \
258 )
259
260 /* exposed interface */
261 #define vec_meta(A)       (((vector_t*)((void*)A)) - 1)
262 #define vec_free(A)       ((void)((A) ? (mem_d((void*)vec_meta(A)), (A) = NULL) : 0))
263 #define vec_push(A,V)     (GMQCC_VEC_WILLGROW((A),1), (A)[vec_meta(A)->used++] = (V))
264 #define vec_size(A)       ((A) ? vec_meta(A)->used : 0)
265 #define vec_add(A,N)      (GMQCC_VEC_WILLGROW((A),(N)), vec_meta(A)->used += (N), &(A)[vec_meta(A)->used-(N)])
266 #define vec_last(A)       ((A)[vec_meta(A)->used - 1])
267 #define vec_pop(A)        ((void)(vec_meta(A)->used -= 1))
268 #define vec_shrinkto(A,N) ((void)(vec_meta(A)->used  = (N)))
269 #define vec_shrinkby(A,N) ((void)(vec_meta(A)->used -= (N)))
270 #define vec_append(A,N,S) ((void)(memcpy(vec_add((A), (N)), (S), (N) * sizeof(*(S)))))
271 #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)))
272
273 typedef struct hash_table_s {
274     size_t                size;
275     struct hash_node_t **table;
276 } hash_table_t, *ht;
277
278 /*
279  * hashtable implementation:
280  *
281  * Note:
282  *      This was designed for pointers:  you manage the life of the object yourself
283  *      if you do use this for non-pointers please be warned that the object may not
284  *      be valid if the duration of it exceeds (i.e on stack).  So you need to allocate
285  *      yourself, or put those in global scope to ensure duration is for the whole
286  *      runtime.
287  *
288  * util_htnew(size)                             -- to make a new hashtable
289  * util_htset(table, key, value, sizeof(value)) -- to set something in the table
290  * util_htget(table, key)                       -- to get something from the table
291  * util_htdel(table)                            -- to delete the table
292  *
293  * example of use:
294  *
295  * ht    foo  = util_htnew(1024);
296  * int   data = 100;
297  * char *test = "hello world\n";
298  * util_htset(foo, "foo", (void*)&data);
299  * util_gtset(foo, "bar", (void*)test);
300  *
301  * printf("foo: %d, bar %s",
302  *     *((int *)util_htget(foo, "foo")),
303  *      ((char*)util_htget(foo, "bar"))
304  * );
305  *
306  * util_htdel(foo);
307  */
308 hash_table_t *util_htnew (size_t size);
309 void          util_htrem (hash_table_t *ht, void (*callback)(void *data));
310 void          util_htset (hash_table_t *ht, const char *key, void *value);
311 void          util_htdel (hash_table_t *ht);
312 size_t        util_hthash(hash_table_t *ht, const char *key);
313 void          util_htseth(hash_table_t *ht, const char *key, size_t hash, void *value);
314 void          util_htrmh (hash_table_t *ht, const char *key, size_t bin, void (*cb)(void*));
315 void          util_htrm  (hash_table_t *ht, const char *key, void (*cb)(void*));
316
317 void         *util_htget (hash_table_t *ht, const char *key);
318 void         *util_htgeth(hash_table_t *ht, const char *key, size_t hash);
319
320 int           util_snprintf(char *str, size_t, const char *fmt, ...);
321
322
323 /* fs.c */
324 #define FS_FILE_SEEK_SET  0
325 #define FS_FILE_SEEK_CUR  1
326 #define FS_FILE_SEEK_END  2
327 #define FS_FILE_EOF      -1
328
329 typedef struct fs_dir_s  fs_dir_t;
330 /*typedef struct fs_file_s fs_file_t;*/
331 typedef struct dirent    fs_dirent_t;
332
333 void           fs_file_close  (fs_file_t *);
334 int            fs_file_error  (fs_file_t *);
335 int            fs_file_getc   (fs_file_t *);
336 int            fs_file_printf (fs_file_t *, const char *, ...);
337 int            fs_file_puts   (fs_file_t *, const char *);
338 int            fs_file_seek   (fs_file_t *, long int, int);
339 long           fs_file_tell   (fs_file_t *);
340 int            fs_file_flush  (fs_file_t *);
341
342 size_t         fs_file_read   (void *,        size_t, size_t, fs_file_t *);
343 size_t         fs_file_write  (const void *,  size_t, size_t, fs_file_t *);
344
345 fs_file_t     *fs_file_open   (const char *, const char *);
346 int            fs_file_getline(char  **, size_t *, fs_file_t *);
347
348 int            fs_dir_make    (const char *);
349 fs_dir_t      *fs_dir_open    (const char *);
350 int            fs_dir_close   (fs_dir_t *);
351 fs_dirent_t   *fs_dir_read    (fs_dir_t *);
352
353
354 /* correct.c */
355 typedef struct correct_trie_s {
356     void                  *value;
357     struct correct_trie_s *entries;
358 } correct_trie_t;
359
360 correct_trie_t* correct_trie_new(void);
361
362 typedef struct {
363     char   ***edits;
364     size_t  **lens;
365 } correction_t;
366
367 void  correct_del (correct_trie_t*, size_t **);
368 void  correct_add (correct_trie_t*, size_t ***, const char *);
369 char *correct_str (correction_t *, correct_trie_t*, const char *);
370 void  correct_init(correction_t *);
371 void  correct_free(correction_t *);
372
373
374 /* code.c */
375
376 /* Note: if you change the order, fix type_sizeof in ir.c */
377 enum {
378     TYPE_VOID     ,
379     TYPE_STRING   ,
380     TYPE_FLOAT    ,
381     TYPE_VECTOR   ,
382     TYPE_ENTITY   ,
383     TYPE_FIELD    ,
384     TYPE_FUNCTION ,
385     TYPE_POINTER  ,
386     TYPE_INTEGER  ,
387     TYPE_VARIANT  ,
388     TYPE_STRUCT   ,
389     TYPE_UNION    ,
390     TYPE_ARRAY    ,
391
392     TYPE_NIL      , /* it's its own type / untyped */
393     TYPE_NOEXPR   , /* simply invalid in expressions */
394
395     TYPE_COUNT
396 };
397
398 /* const/var qualifiers */
399 #define CV_NONE   0
400 #define CV_CONST  1
401 #define CV_VAR   -1
402 #define CV_WRONG  0x8000 /* magic number to help parsing */
403
404 extern const char    *type_name        [TYPE_COUNT];
405 extern const uint16_t type_store_instr [TYPE_COUNT];
406 extern const uint16_t field_store_instr[TYPE_COUNT];
407
408 /*
409  * could use type_store_instr + INSTR_STOREP_F - INSTR_STORE_F
410  * but this breaks when TYPE_INTEGER is added, since with the enhanced
411  * instruction set, the old ones are left untouched, thus the _I instructions
412  * are at a seperate place.
413  */
414 extern const uint16_t type_storep_instr[TYPE_COUNT];
415 extern const uint16_t type_eq_instr    [TYPE_COUNT];
416 extern const uint16_t type_ne_instr    [TYPE_COUNT];
417 extern const uint16_t type_not_instr   [TYPE_COUNT];
418
419 typedef struct {
420     uint32_t offset;      /* Offset in file of where data begins  */
421     uint32_t length;      /* Length of section (how many of)      */
422 } prog_section_t;
423
424 typedef struct {
425     uint32_t       version;      /* Program version (6)     */
426     uint16_t       crc16;
427     uint16_t       skip;
428
429     prog_section_t statements;   /* prog_section_statement  */
430     prog_section_t defs;         /* prog_section_def        */
431     prog_section_t fields;       /* prog_section_field      */
432     prog_section_t functions;    /* prog_section_function   */
433     prog_section_t strings;
434     prog_section_t globals;
435     uint32_t       entfield;     /* Number of entity fields */
436 } prog_header_t;
437
438 /*
439  * Each paramater incerements by 3 since vector types hold
440  * 3 components (x,y,z).
441  */
442 #define OFS_NULL      0
443 #define OFS_RETURN    1
444 #define OFS_PARM0     (OFS_RETURN+3)
445 #define OFS_PARM1     (OFS_PARM0 +3)
446 #define OFS_PARM2     (OFS_PARM1 +3)
447 #define OFS_PARM3     (OFS_PARM2 +3)
448 #define OFS_PARM4     (OFS_PARM3 +3)
449 #define OFS_PARM5     (OFS_PARM4 +3)
450 #define OFS_PARM6     (OFS_PARM5 +3)
451 #define OFS_PARM7     (OFS_PARM6 +3)
452
453 typedef struct {
454     uint16_t opcode;
455
456     /* operand 1 */
457     union {
458         int16_t  s1; /* signed   */
459         uint16_t u1; /* unsigned */
460     } o1;
461     /* operand 2 */
462     union {
463         int16_t  s1; /* signed   */
464         uint16_t u1; /* unsigned */
465     } o2;
466     /* operand 3 */
467     union {
468         int16_t  s1; /* signed   */
469         uint16_t u1; /* unsigned */
470     } o3;
471
472     /*
473      * This is the same as the structure in darkplaces
474      * {
475      *     unsigned short op;
476      *     short          a,b,c;
477      * }
478      * But this one is more sane to work with, and the
479      * type sizes are guranteed.
480      */
481 } prog_section_statement_t;
482
483 typedef struct {
484     /*
485      * The types:
486      * 0 = ev_void
487      * 1 = ev_string
488      * 2 = ev_float
489      * 3 = ev_vector
490      * 4 = ev_entity
491      * 5 = ev_field
492      * 6 = ev_function
493      * 7 = ev_pointer -- engine only
494      * 8 = ev_bad     -- engine only
495      */
496     uint16_t type;
497     uint16_t offset;
498     uint32_t name;
499 } prog_section_both_t;
500
501 typedef prog_section_both_t prog_section_def_t;
502 typedef prog_section_both_t prog_section_field_t;
503
504 /* this is ORed to the type */
505 #define DEF_SAVEGLOBAL (1<<15)
506 #define DEF_TYPEMASK   ((1<<15)-1)
507
508 typedef struct {
509     int32_t   entry;      /* in statement table for instructions  */
510     uint32_t  firstlocal; /* First local in local table           */
511     uint32_t  locals;     /* Total ints of params + locals        */
512     uint32_t  profile;    /* Always zero (engine uses this)       */
513     uint32_t  name;       /* name of function in string table     */
514     uint32_t  file;       /* file of the source file              */
515     int32_t   nargs;      /* number of arguments                  */
516     uint8_t   argsize[8]; /* size of arguments (keep 8 always?)   */
517 } prog_section_function_t;
518
519 /*
520  * Instructions
521  * These are the external instructions supported by the interperter
522  * this is what things compile to (from the C code).
523  */
524 enum {
525     INSTR_DONE,
526     INSTR_MUL_F,
527     INSTR_MUL_V,
528     INSTR_MUL_FV, /* NOTE: the float operands must NOT be at the same locations: A != C */
529     INSTR_MUL_VF, /* and here: B != C */
530     INSTR_DIV_F,
531     INSTR_ADD_F,
532     INSTR_ADD_V,
533     INSTR_SUB_F,
534     INSTR_SUB_V,
535     INSTR_EQ_F,
536     INSTR_EQ_V,
537     INSTR_EQ_S,
538     INSTR_EQ_E,
539     INSTR_EQ_FNC,
540     INSTR_NE_F,
541     INSTR_NE_V,
542     INSTR_NE_S,
543     INSTR_NE_E,
544     INSTR_NE_FNC,
545     INSTR_LE,
546     INSTR_GE,
547     INSTR_LT,
548     INSTR_GT,
549     INSTR_LOAD_F,
550     INSTR_LOAD_V,
551     INSTR_LOAD_S,
552     INSTR_LOAD_ENT,
553     INSTR_LOAD_FLD,
554     INSTR_LOAD_FNC,
555     INSTR_ADDRESS,
556     INSTR_STORE_F,
557     INSTR_STORE_V,
558     INSTR_STORE_S,
559     INSTR_STORE_ENT,
560     INSTR_STORE_FLD,
561     INSTR_STORE_FNC,
562     INSTR_STOREP_F,
563     INSTR_STOREP_V,
564     INSTR_STOREP_S,
565     INSTR_STOREP_ENT,
566     INSTR_STOREP_FLD,
567     INSTR_STOREP_FNC,
568     INSTR_RETURN,
569     INSTR_NOT_F,
570     INSTR_NOT_V,
571     INSTR_NOT_S,
572     INSTR_NOT_ENT,
573     INSTR_NOT_FNC,
574     INSTR_IF,
575     INSTR_IFNOT,
576     INSTR_CALL0,
577     INSTR_CALL1,
578     INSTR_CALL2,
579     INSTR_CALL3,
580     INSTR_CALL4,
581     INSTR_CALL5,
582     INSTR_CALL6,
583     INSTR_CALL7,
584     INSTR_CALL8,
585     INSTR_STATE,
586     INSTR_GOTO,
587     INSTR_AND,
588     INSTR_OR,
589     INSTR_BITAND,
590     INSTR_BITOR,
591
592     /*
593      * Virtual instructions used by the IR
594      * Keep at the end!
595      */
596     VINSTR_END,
597     VINSTR_PHI,
598     VINSTR_JUMP,
599     VINSTR_COND,
600
601     /* A never returning CALL.
602      * Creating this causes IR blocks to be marked as 'final'.
603      * No-Return-Call
604      */
605     VINSTR_NRCALL,
606
607     /* Emulated instructions. */
608     VINSTR_BITAND_V, /* BITAND_V must be the first emulated bitop */
609     VINSTR_BITAND_VF,
610     VINSTR_BITOR_V,
611     VINSTR_BITOR_VF,
612     VINSTR_BITXOR,
613     VINSTR_BITXOR_V,
614     VINSTR_BITXOR_VF,
615     VINSTR_CROSS,
616     VINSTR_NEG_F,
617     VINSTR_NEG_V
618 };
619
620 /* TODO: elide */
621 extern const char *util_instr_str[VINSTR_END];
622
623
624 typedef float    qcfloat_t;
625 typedef int32_t  qcint_t;
626 typedef uint32_t qcuint_t;
627
628 typedef struct {
629     prog_section_statement_t *statements;
630     int                      *linenums;
631     int                      *columnnums;
632     prog_section_def_t       *defs;
633     prog_section_field_t     *fields;
634     prog_section_function_t  *functions;
635     int                      *globals;
636     char                     *chars;
637     uint16_t                  crc;
638     uint32_t                  entfields;
639     ht                        string_cache;
640     qcint_t                   string_cached_empty;
641 } code_t;
642
643 /*
644  * A shallow copy of a lex_file to remember where which ast node
645  * came from.
646  */
647 typedef struct {
648     const char *file;
649     size_t      line;
650     size_t      column;
651 } lex_ctx_t;
652
653 /*
654  * code_write          -- writes out the compiled file
655  * code_init           -- prepares the code file
656  * code_genstrin       -- generates string for code
657  * code_alloc_field    -- allocated a field
658  * code_push_statement -- keeps statements and linenumbers together
659  * code_pop_statement  -- keeps statements and linenumbers together
660  */
661 bool      code_write         (code_t *, const char *filename, const char *lno);
662 GMQCC_WARN
663 code_t   *code_init          (void);
664 void      code_cleanup       (code_t *);
665 uint32_t  code_genstring     (code_t *, const char *string);
666 qcint_t   code_alloc_field   (code_t *, size_t qcsize);
667 void      code_push_statement(code_t *, prog_section_statement_t *stmt, lex_ctx_t ctx);
668 void      code_pop_statement (code_t *);
669
670
671 /* conout.c */
672 enum {
673     CON_BLACK   = 30,
674     CON_RED,
675     CON_GREEN,
676     CON_BROWN,
677     CON_BLUE,
678     CON_MAGENTA,
679     CON_CYAN ,
680     CON_WHITE
681 };
682
683 /* message level */
684 enum {
685     LVL_MSG,
686     LVL_WARNING,
687     LVL_ERROR
688 };
689
690 fs_file_t *con_default_out(void);
691 fs_file_t *con_default_err(void);
692
693 void con_vprintmsg (int level, const char *name, size_t line, size_t column, const char *msgtype, const char *msg, va_list ap);
694 void con_printmsg  (int level, const char *name, size_t line, size_t column, const char *msgtype, const char *msg, ...);
695 void con_cvprintmsg(lex_ctx_t ctx, int lvl, const char *msgtype, const char *msg, va_list ap);
696 void con_cprintmsg (lex_ctx_t ctx, int lvl, const char *msgtype, const char *msg, ...);
697
698 void con_close (void);
699 void con_init  (void);
700 void con_reset (void);
701 void con_color (int);
702 int  con_change(const char *, const char *);
703 int  con_verr  (const char *, va_list);
704 int  con_vout  (const char *, va_list);
705 int  con_err   (const char *, ...);
706 int  con_out   (const char *, ...);
707
708 /* error/warning interface */
709 extern size_t compile_errors;
710 extern size_t compile_Werrors;
711 extern size_t compile_warnings;
712
713 void /********/ compile_error   (lex_ctx_t ctx, /*LVL_ERROR*/ const char *msg, ...);
714 void /********/ vcompile_error  (lex_ctx_t ctx, /*LVL_ERROR*/ const char *msg, va_list ap);
715 bool GMQCC_WARN compile_warning (lex_ctx_t ctx, int warntype, const char *fmt, ...);
716 bool GMQCC_WARN vcompile_warning(lex_ctx_t ctx, int warntype, const char *fmt, va_list ap);
717 void            compile_show_werrors(void);
718
719 /* ir.c */
720 /* TODO: cleanup */
721 enum store_types {
722     store_global,
723     store_local,  /* local, assignable for now, should get promoted later */
724     store_param,  /* parameters, they are locals with a fixed position */
725     store_value,  /* unassignable */
726     store_return  /* unassignable, at OFS_RETURN */
727 };
728
729 typedef struct {
730     qcfloat_t x, y, z;
731 } vec3_t;
732
733 /* exec.c */
734
735 /* TODO: cleanup */
736 /*
737  * Darkplaces has (or will have) a 64 bit prog loader
738  * where the 32 bit qc program is autoconverted on load.
739  * Since we may want to support that as well, let's redefine
740  * float and int here.
741  */
742 typedef union {
743     qcint_t   _int;
744     qcint_t    string;
745     qcint_t    function;
746     qcint_t    edict;
747     qcfloat_t _float;
748     qcfloat_t vector[3];
749     qcint_t   ivector[3];
750 } qcany_t;
751
752 typedef char qcfloat_t_size_is_correct [sizeof(qcfloat_t) == 4 ?1:-1];
753 typedef char qcint_t_size_is_correct   [sizeof(qcint_t)   == 4 ?1:-1];
754
755 enum {
756     VMERR_OK,
757     VMERR_TEMPSTRING_ALLOC,
758     VMERR_END
759 };
760
761 #define VM_JUMPS_DEFAULT 1000000
762
763 /* execute-flags */
764 #define VMXF_DEFAULT 0x0000     /* default flags - nothing */
765 #define VMXF_TRACE   0x0001     /* trace: print statements before executing */
766 #define VMXF_PROFILE 0x0002     /* profile: increment the profile counters */
767
768 struct qc_program_s;
769 typedef int (*prog_builtin_t)(struct qc_program_s *prog);
770
771 typedef struct {
772     qcint_t                    stmt;
773     size_t                   localsp;
774     prog_section_function_t *function;
775 } qc_exec_stack_t;
776
777 typedef struct qc_program_s {
778     char                    *filename;
779     prog_section_statement_t *code;
780     prog_section_def_t       *defs;
781     prog_section_def_t       *fields;
782     prog_section_function_t  *functions;
783     char                    *strings;
784     qcint_t                   *globals;
785     qcint_t                   *entitydata;
786     bool                    *entitypool;
787
788     const char*             *function_stack;
789
790     uint16_t crc16;
791
792     size_t tempstring_start;
793     size_t tempstring_at;
794
795     qcint_t  vmerror;
796
797     size_t *profile;
798
799     prog_builtin_t *builtins;
800     size_t          builtins_count;
801
802     /* size_t ip; */
803     qcint_t  entities;
804     size_t entityfields;
805     bool   allowworldwrites;
806
807     qcint_t         *localstack;
808     qc_exec_stack_t *stack;
809     size_t statement;
810
811     size_t xflags;
812
813     int    argc; /* current arg count for debugging */
814 } qc_program_t;
815
816 qc_program_t*       prog_load      (const char *filename, bool ignoreversion);
817 void                prog_delete    (qc_program_t *prog);
818 bool                prog_exec      (qc_program_t *prog, prog_section_function_t *func, size_t flags, long maxjumps);
819 const char*         prog_getstring (qc_program_t *prog, qcint_t str);
820 prog_section_def_t* prog_entfield  (qc_program_t *prog, qcint_t off);
821 prog_section_def_t* prog_getdef    (qc_program_t *prog, qcint_t off);
822 qcany_t*            prog_getedict  (qc_program_t *prog, qcint_t e);
823 qcint_t               prog_tempstring(qc_program_t *prog, const char *_str);
824
825
826 /* parser.c */
827 struct parser_s;
828 struct parser_s *parser_create        (void);
829 bool             parser_compile_file  (struct parser_s *parser, const char *);
830 bool             parser_compile_string(struct parser_s *parser, const char *, const char *, size_t);
831 bool             parser_finish        (struct parser_s *parser, const char *);
832 void             parser_cleanup       (struct parser_s *parser);
833
834 /* ftepp.c */
835 struct ftepp_s;
836 struct ftepp_s *ftepp_create           (void);
837 bool            ftepp_preprocess_file  (struct ftepp_s *ftepp, const char *filename);
838 bool            ftepp_preprocess_string(struct ftepp_s *ftepp, const char *name, const char *str);
839 void            ftepp_finish           (struct ftepp_s *ftepp);
840 const char     *ftepp_get              (struct ftepp_s *ftepp);
841 void            ftepp_flush            (struct ftepp_s *ftepp);
842 void            ftepp_add_define       (struct ftepp_s *ftepp, const char *source, const char *name);
843 void            ftepp_add_macro        (struct ftepp_s *ftepp, const char *name,   const char *value);
844
845 /* main.c */
846
847 #if 1
848 /* Helpers to allow for a whole lot of flags. Otherwise we'd limit
849  * to 32 or 64 -f options...
850  */
851 typedef struct {
852     size_t  idx; /* index into an array of 32 bit words */
853     uint8_t bit; /* bit index for the 8 bit group idx points to */
854 } longbit;
855 #define LONGBIT(bit) { ((bit)/32), ((bit)%32) }
856 #define LONGBIT_SET(B, I) ((B).idx = (I)/32, (B).bit = ((I)%32))
857 #else
858 typedef uint32_t longbit;
859 #define LONGBIT(bit) (bit)
860 #define LONGBIT_SET(B, I) ((B) = (I))
861 #endif
862
863 /* utf.8 */
864 typedef long utf8ch_t;
865 int utf8_from(char *, utf8ch_t);
866 int utf8_to(utf8ch_t *, const unsigned char *, size_t);
867
868 /* opts.c */
869 typedef struct {
870     const char *name;
871     longbit     bit;
872 } opts_flag_def_t;
873
874 bool opts_setflag  (const char *, bool);
875 bool opts_setwarn  (const char *, bool);
876 bool opts_setwerror(const char *, bool);
877 bool opts_setoptim (const char *, bool);
878
879 void opts_init         (const char *, int, size_t);
880 void opts_set          (uint32_t   *, size_t, bool);
881 void opts_setoptimlevel(unsigned int);
882 void opts_ini_init     (const char *);
883
884 /* Saner flag handling */
885 void opts_backup_non_Wall(void);
886 void opts_restore_non_Wall(void);
887 void opts_backup_non_Werror_all(void);
888 void opts_restore_non_Werror_all(void);
889
890
891 enum {
892 # define GMQCC_TYPE_FLAGS
893 # define GMQCC_DEFINE_FLAG(X) X,
894 #  include "opts.def"
895     COUNT_FLAGS
896 };
897
898 enum {
899 # define GMQCC_TYPE_WARNS
900 # define GMQCC_DEFINE_FLAG(X) WARN_##X,
901 #  include "opts.def"
902     COUNT_WARNINGS
903 };
904
905 enum {
906 # define GMQCC_TYPE_OPTIMIZATIONS
907 # define GMQCC_DEFINE_FLAG(NAME, MIN_O) OPTIM_##NAME,
908 #  include "opts.def"
909     COUNT_OPTIMIZATIONS
910 };
911
912 enum {
913 #   define GMQCC_TYPE_OPTIONS
914 #   define GMQCC_DEFINE_FLAG(X) OPTION_##X,
915 #   include "opts.def"
916     OPTION_COUNT
917 };
918
919 extern const opts_flag_def_t opts_flag_list[COUNT_FLAGS+1];
920 extern const opts_flag_def_t opts_warn_list[COUNT_WARNINGS+1];
921 extern const opts_flag_def_t opts_opt_list[COUNT_OPTIMIZATIONS+1];
922 extern const unsigned int    opts_opt_oflag[COUNT_OPTIMIZATIONS+1];
923 extern unsigned int          opts_optimizationcount[COUNT_OPTIMIZATIONS];
924
925 /* other options: */
926 typedef enum {
927     COMPILER_QCC,     /* circa  QuakeC */
928     COMPILER_FTEQCC,  /* fteqcc QuakeC */
929     COMPILER_QCCX,    /* qccx   QuakeC */
930     COMPILER_GMQCC    /* this   QuakeC */
931 } opts_std_t;
932
933 typedef struct {
934     union {
935         bool     b;
936         uint16_t u16;
937         uint32_t u32;
938
939         union {
940             char       *p;
941             const char *c;
942         } str;
943     } data;
944
945     bool allocated;
946 } opt_value_t;
947
948
949 typedef struct {
950     opt_value_t  options      [OPTION_COUNT];
951     uint32_t     flags        [1 + (COUNT_FLAGS         / 32)];
952     uint32_t     warn         [1 + (COUNT_WARNINGS      / 32)];
953     uint32_t     werror       [1 + (COUNT_WARNINGS      / 32)];
954     uint32_t     warn_backup  [1 + (COUNT_WARNINGS      / 32)];
955     uint32_t     werror_backup[1 + (COUNT_WARNINGS      / 32)];
956     uint32_t     optimization [1 + (COUNT_OPTIMIZATIONS / 32)];
957     bool         optimizeoff; /* True when -O0 */
958 } opts_cmd_t;
959
960 extern opts_cmd_t opts;
961
962 #define OPTS_GENERIC(f,i)    (!! (((f)[(i)/32]) & (1<< (unsigned)((i)%32))))
963 #define OPTS_FLAG(i)         OPTS_GENERIC(opts.flags,        (i))
964 #define OPTS_WARN(i)         OPTS_GENERIC(opts.warn,         (i))
965 #define OPTS_WERROR(i)       OPTS_GENERIC(opts.werror,       (i))
966 #define OPTS_OPTIMIZATION(i) OPTS_GENERIC(opts.optimization, (i))
967 #define OPTS_OPTION_DUPED(X) (opts.options[X].allocated)
968 #define OPTS_OPTION_BOOL(X) (opts.options[X].data.b)
969 #define OPTS_OPTION_U16(X)  (opts.options[X].data.u16)
970 #define OPTS_OPTION_U32(X)  (opts.options[X].data.u32)
971 #define OPTS_OPTION_DUP(X) *(OPTS_OPTION_DUPED(X)=true, &(opts.options[X].data.str.p))
972 #define OPTS_OPTION_STR(X)  (opts.options[X].data.str.c)
973
974 #endif /*! GMQCC_HDR */