X-Git-Url: https://git.xonotic.org/?p=xonotic%2Fgmqcc.git;a=blobdiff_plain;f=gmqcc.h;h=1285072a1790a623899b79b6d24bcc1849626539;hp=576057ac8c71e61f48d59a5d303768cbb2edc88f;hb=892746056e1082aad991c5287b511d72534542c9;hpb=1201f06a55585b927f340687095160c473642d25 diff --git a/gmqcc.h b/gmqcc.h index 576057a..1285072 100644 --- a/gmqcc.h +++ b/gmqcc.h @@ -24,7 +24,8 @@ #ifndef GMQCC_HDR #define GMQCC_HDR #include -#include /* TODO: remove this */ +#include +#include /* TODO: remove?*/ /* * Disable some over protective warnings in visual studio because fixing them is a waste @@ -36,7 +37,7 @@ #define GMQCC_VERSION_MAJOR 0 #define GMQCC_VERSION_MINOR 3 -#define GMQCC_VERSION_PATCH 0 +#define GMQCC_VERSION_PATCH 6 #define GMQCC_VERSION_BUILD(J,N,P) (((J)<<16)|((N)<<8)|(P)) #define GMQCC_VERSION \ GMQCC_VERSION_BUILD(GMQCC_VERSION_MAJOR, GMQCC_VERSION_MINOR, GMQCC_VERSION_PATCH) @@ -149,6 +150,16 @@ GMQCC_IND_STRING(GMQCC_VERSION_PATCH) \ # define GMQCC_NORETURN #endif /*! (defined(__GNUC__) && __GNUC__ >= 2) || defined (__CLANG__) */ +#if (defined(__GNUC__)) || defined(__CLANG__) +# define GMQCC_LIKELY(X) __builtin_expect((X), 1) +# define GMQCC_UNLIKELY(X) __builtin_expect((X), 0) +#else +# define GMQCC_LIKELY(X) (X) +# define GMQCC_UNLIKELY(X) (X) +#endif + +#define GMQCC_ARRAY_COUNT(X) (sizeof(X) / sizeof((X)[0])) + #ifndef _MSC_VER # include #else @@ -242,64 +253,23 @@ GMQCC_IND_STRING(GMQCC_VERSION_PATCH) \ # endif #endif /*! !defined (PLATFORM_BYTE_ORDER) */ -/* - * On windows systems where we're not compiling with MING32 we need a - * little extra help on dependinces for implementing our own dirent.h - * in fs.c. - */ -#if defined(_WIN32) && !defined(__MINGW32__) -# define _WIN32_LEAN_AND_MEAN -# include -# include -# include - - struct dirent { - long d_ino; - unsigned short d_reclen; - unsigned short d_namlen; - char d_name[FILENAME_MAX]; - }; - - typedef struct { - struct _finddata_t dd_dta; - struct dirent dd_dir; - long dd_handle; - int dd_stat; - char dd_name[1]; - } DIR; - /* - * Visual studio also lacks S_ISDIR for sys/stat.h, so we emulate this as well - * which is not hard at all. - */ -# ifdef S_ISDIR -# undef S_ISDIR -# endif /*! S_ISDIR */ -# define S_ISDIR(X) ((X)&_S_IFDIR) -#else -# include -#endif /*! _WIN32 && !defined(__MINGW32__) */ - -/*===================================================================*/ -/*=========================== stat.c ================================*/ -/*===================================================================*/ +/* stat.c */ void stat_info (void); char *stat_mem_strdup (const char *, size_t, const char *, bool); -void *stat_mem_reallocate(void *, size_t, size_t, const char *); +void *stat_mem_reallocate(void *, size_t, size_t, const char *, const char *); void stat_mem_deallocate(void *); -void *stat_mem_allocate (size_t, size_t, const char *); +void *stat_mem_allocate (size_t, size_t, const char *, const char *); -#define mem_a(SIZE) stat_mem_allocate ((SIZE), __LINE__, __FILE__) +#define mem_a(SIZE) stat_mem_allocate ((SIZE), __LINE__, __FILE__, #SIZE) #define mem_d(PTRN) stat_mem_deallocate((void*)(PTRN)) -#define mem_r(PTRN, SIZE) stat_mem_reallocate((void*)(PTRN), (SIZE), __LINE__, __FILE__) -#define mem_af(SIZE, FILE, LINE) stat_mem_allocate ((SIZE), (LINE), (FILE)) +#define mem_r(PTRN, SIZE) stat_mem_reallocate((void*)(PTRN), (SIZE), __LINE__, __FILE__, #SIZE) +#define mem_af(SIZE, FILE, LINE) stat_mem_allocate ((SIZE), (LINE), (FILE), #SIZE) /* TODO: rename to mem variations */ #define util_strdup(SRC) stat_mem_strdup((char*)(SRC), __LINE__, __FILE__, false) #define util_strdupe(SRC) stat_mem_strdup((char*)(SRC), __LINE__, __FILE__, true) -/*===================================================================*/ -/*=========================== util.c ================================*/ -/*===================================================================*/ +/* util.c */ /* * Microsoft implements against the spec versions of ctype.h. Which @@ -319,11 +289,9 @@ void *stat_mem_allocate (size_t, size_t, const char *); #define util_isprint(a) (((unsigned)(a)-0x20) < 0x5F) #define util_isspace(a) (((a) >= 9 && (a) <= 13) || (a) == ' ') -bool util_filexists (const char *); bool util_strupper (const char *); bool util_strdigit (const char *); -void util_debug (const char *, const char *, ...); -void util_endianswap (void *, size_t, unsigned int); +void util_endianswap (void *, size_t, unsigned int); size_t util_strtocmd (const char *, char *, size_t); size_t util_strtononcmd (const char *, char *, size_t); @@ -334,18 +302,19 @@ uint16_t util_crc16(uint16_t crc, const char *data, size_t len); void util_seed(uint32_t); uint32_t util_rand(void); -/* - * String functions (formatting, copying, concatenating, errors). These are wrapped - * to use the MSVC _safe_ versions when using MSVC, plus some implementations of - * these are non-conformant or don't exist such as asprintf and snprintf, which are - * not supported in C90, but do exist in C99. - */ -int util_vasprintf(char **ret, const char *fmt, va_list); -int util_asprintf (char **ret, const char *fmt, ...); -int util_snprintf (char *src, size_t bytes, const char *format, ...); -char *util_strcat (char *dest, const char *src); -char *util_strncpy (char *dest, const char *src, size_t num); -const char *util_strerror (int num); +int util_asprintf (char **ret, const char *fmt, ...); +int util_sscanf (const char *str, const char *format, ...); +char *util_strncpy (char *dest, const char *src, size_t n); +char *util_strncat (char *dest, const char *src, size_t n); +char *util_strcat (char *dest, const char *src); +const char *util_strerror(int err); + +const struct tm *util_localtime(const time_t *timer); +const char *util_ctime (const time_t *timer); + +typedef struct fs_file_s fs_file_t; + +bool util_isatty(fs_file_t *); /* * A flexible vector implementation: all vector pointers contain some @@ -382,13 +351,6 @@ void _util_vec_grow(void **a, size_t i, size_t s); #define vec_append(A,N,S) ((void)(memcpy(vec_add((A), (N)), (S), (N) * sizeof(*(S))))) #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))) -typedef struct correct_trie_s { - void *value; - struct correct_trie_s *entries; -} correct_trie_t; - -correct_trie_t* correct_trie_new(void); - typedef struct hash_table_s { size_t size; struct hash_node_t **table; @@ -436,34 +398,48 @@ void util_htrm (hash_table_t *ht, const char *key, void (*cb)(void*)); void *util_htget (hash_table_t *ht, const char *key); void *util_htgeth(hash_table_t *ht, const char *key, size_t hash); -/*===================================================================*/ -/*============================ file.c ===============================*/ -/*===================================================================*/ -/* file handling */ -void fs_file_close (FILE *); -int fs_file_error (FILE *); -int fs_file_getc (FILE *); -int fs_file_printf (FILE *, const char *, ...); -int fs_file_puts (FILE *, const char *); -int fs_file_seek (FILE *, long int, int); -long int fs_file_tell (FILE *); - -size_t fs_file_read (void *, size_t, size_t, FILE *); -size_t fs_file_write (const void *, size_t, size_t, FILE *); - -FILE *fs_file_open (const char *, const char *); -int fs_file_getline(char **, size_t *, FILE *); - -/* directory handling */ +int util_snprintf(char *str, size_t, const char *fmt, ...); + + +/* fs.c */ +#define FS_FILE_SEEK_SET 0 +#define FS_FILE_SEEK_CUR 1 +#define FS_FILE_SEEK_END 2 +#define FS_FILE_EOF -1 + +typedef struct fs_dir_s fs_dir_t; +/*typedef struct fs_file_s fs_file_t;*/ +typedef struct dirent fs_dirent_t; + +void fs_file_close (fs_file_t *); +int fs_file_error (fs_file_t *); +int fs_file_getc (fs_file_t *); +int fs_file_printf (fs_file_t *, const char *, ...); +int fs_file_puts (fs_file_t *, const char *); +int fs_file_seek (fs_file_t *, long int, int); +long fs_file_tell (fs_file_t *); +int fs_file_flush (fs_file_t *); + +size_t fs_file_read (void *, size_t, size_t, fs_file_t *); +size_t fs_file_write (const void *, size_t, size_t, fs_file_t *); + +fs_file_t *fs_file_open (const char *, const char *); +int fs_file_getline(char **, size_t *, fs_file_t *); + int fs_dir_make (const char *); -DIR *fs_dir_open (const char *); -int fs_dir_close (DIR *); -struct dirent *fs_dir_read (DIR *); +fs_dir_t *fs_dir_open (const char *); +int fs_dir_close (fs_dir_t *); +fs_dirent_t *fs_dir_read (fs_dir_t *); -/*===================================================================*/ -/*=========================== correct.c =============================*/ -/*===================================================================*/ +/* correct.c */ +typedef struct correct_trie_s { + void *value; + struct correct_trie_s *entries; +} correct_trie_t; + +correct_trie_t* correct_trie_new(void); + typedef struct { char ***edits; size_t **lens; @@ -475,9 +451,8 @@ char *correct_str (correction_t *, correct_trie_t*, const char *); void correct_init(correction_t *); void correct_free(correction_t *); -/*===================================================================*/ -/*=========================== code.c ================================*/ -/*===================================================================*/ + +/* code.c */ /* Note: if you change the order, fix type_sizeof in ir.c */ enum { @@ -703,11 +678,24 @@ enum { VINSTR_PHI, VINSTR_JUMP, VINSTR_COND, + /* A never returning CALL. * Creating this causes IR blocks to be marked as 'final'. * No-Return-Call */ - VINSTR_NRCALL + VINSTR_NRCALL, + + /* Emulated instructions. */ + VINSTR_BITAND_V, /* BITAND_V must be the first emulated bitop */ + VINSTR_BITAND_VF, + VINSTR_BITOR_V, + VINSTR_BITOR_VF, + VINSTR_BITXOR, + VINSTR_BITXOR_V, + VINSTR_BITXOR_VF, + VINSTR_CROSS, + VINSTR_NEG_F, + VINSTR_NEG_V }; /* TODO: elide */ @@ -721,6 +709,7 @@ typedef uint32_t qcuint_t; typedef struct { prog_section_statement_t *statements; int *linenums; + int *columnnums; prog_section_def_t *defs; prog_section_field_t *fields; prog_section_function_t *functions; @@ -732,6 +721,16 @@ typedef struct { qcint_t string_cached_empty; } code_t; +/* + * A shallow copy of a lex_file to remember where which ast node + * came from. + */ +typedef struct { + const char *file; + size_t line; + size_t column; +} lex_ctx_t; + /* * code_write -- writes out the compiled file * code_init -- prepares the code file @@ -746,22 +745,11 @@ code_t *code_init (void); void code_cleanup (code_t *); uint32_t code_genstring (code_t *, const char *string); qcint_t code_alloc_field (code_t *, size_t qcsize); -void code_push_statement(code_t *, prog_section_statement_t *stmt, int linenum); +void code_push_statement(code_t *, prog_section_statement_t *stmt, lex_ctx_t ctx); void code_pop_statement (code_t *); -/* - * A shallow copy of a lex_file to remember where which ast node - * came from. - */ -typedef struct { - const char *file; - size_t line; - size_t column; -} lex_ctx_t; -/*===================================================================*/ -/*============================ con.c ================================*/ -/*===================================================================*/ +/* conout.c */ enum { CON_BLACK = 30, CON_RED, @@ -780,8 +768,8 @@ enum { LVL_ERROR }; -FILE *con_default_out(void); -FILE *con_default_err(void); +fs_file_t *con_default_out(void); +fs_file_t *con_default_err(void); void con_vprintmsg (int level, const char *name, size_t line, size_t column, const char *msgtype, const char *msg, va_list ap); void con_printmsg (int level, const char *name, size_t line, size_t column, const char *msgtype, const char *msg, ...); @@ -809,10 +797,8 @@ bool GMQCC_WARN compile_warning (lex_ctx_t ctx, int warntype, const char *fmt, . bool GMQCC_WARN vcompile_warning(lex_ctx_t ctx, int warntype, const char *fmt, va_list ap); void compile_show_werrors(void); -/*===================================================================*/ -/*============================= ir.c ================================*/ -/*===================================================================*/ - +/* ir.c */ +/* TODO: cleanup */ enum store_types { store_global, store_local, /* local, assignable for now, should get promoted later */ @@ -825,9 +811,7 @@ typedef struct { qcfloat_t x, y, z; } vec3_t; -/*===================================================================*/ -/*============================= exec.c ==============================*/ -/*===================================================================*/ +/* exec.c */ /* TODO: cleanup */ /* @@ -920,9 +904,7 @@ qcany_t* prog_getedict (qc_program_t *prog, qcint_t e); qcint_t prog_tempstring(qc_program_t *prog, const char *_str); -/*===================================================================*/ -/*===================== parser.c commandline ========================*/ -/*===================================================================*/ +/* parser.c */ struct parser_s; struct parser_s *parser_create (void); bool parser_compile_file (struct parser_s *parser, const char *); @@ -930,9 +912,7 @@ bool parser_compile_string(struct parser_s *parser, const char *, co bool parser_finish (struct parser_s *parser, const char *); void parser_cleanup (struct parser_s *parser); -/*===================================================================*/ -/*====================== ftepp.c commandline ========================*/ -/*===================================================================*/ +/* ftepp.c */ struct ftepp_s; struct ftepp_s *ftepp_create (void); bool ftepp_preprocess_file (struct ftepp_s *ftepp, const char *filename); @@ -943,9 +923,7 @@ void ftepp_flush (struct ftepp_s *ftepp); void ftepp_add_define (struct ftepp_s *ftepp, const char *source, const char *name); void ftepp_add_macro (struct ftepp_s *ftepp, const char *name, const char *value); -/*===================================================================*/ -/*======================= main.c commandline ========================*/ -/*===================================================================*/ +/* main.c */ #if 1 /* Helpers to allow for a whole lot of flags. Otherwise we'd limit @@ -963,21 +941,12 @@ typedef uint32_t longbit; #define LONGBIT_SET(B, I) ((B) = (I)) #endif -/*===================================================================*/ -/*=========================== utf8lib.c =============================*/ -/*===================================================================*/ -typedef uint32_t uchar_t; - -bool u8_analyze (const char *_s, size_t *_start, size_t *_len, uchar_t *_ch, size_t _maxlen); -size_t u8_strlen (const char*); -size_t u8_strnlen (const char*, size_t); -uchar_t u8_getchar (const char*, const char**); -uchar_t u8_getnchar(const char*, const char**, size_t); -int u8_fromchar(uchar_t w, char *to, size_t maxlen); - -/*===================================================================*/ -/*============================= opts.c ==============================*/ -/*===================================================================*/ +/* utf.8 */ +typedef long utf8ch_t; +int utf8_from(char *, utf8ch_t); +int utf8_to(utf8ch_t *, const unsigned char *, size_t); + +/* opts.c */ typedef struct { const char *name; longbit bit; @@ -1042,11 +1011,19 @@ typedef enum { COMPILER_GMQCC /* this QuakeC */ } opts_std_t; -typedef union { - bool B; - uint16_t U16; - uint32_t U32; - char *STR; +typedef struct { + union { + bool b; + uint16_t u16; + uint32_t u32; + + union { + char *p; + const char *c; + } str; + } data; + + bool allocated; } opt_value_t; @@ -1068,9 +1045,11 @@ extern opts_cmd_t opts; #define OPTS_WARN(i) OPTS_GENERIC(opts.warn, (i)) #define OPTS_WERROR(i) OPTS_GENERIC(opts.werror, (i)) #define OPTS_OPTIMIZATION(i) OPTS_GENERIC(opts.optimization, (i)) -#define OPTS_OPTION_BOOL(X) (opts.options[X].B) -#define OPTS_OPTION_U16(X) (opts.options[X].U16) -#define OPTS_OPTION_U32(X) (opts.options[X].U32) -#define OPTS_OPTION_STR(X) (opts.options[X].STR) +#define OPTS_OPTION_DUPED(X) (opts.options[X].allocated) +#define OPTS_OPTION_BOOL(X) (opts.options[X].data.b) +#define OPTS_OPTION_U16(X) (opts.options[X].data.u16) +#define OPTS_OPTION_U32(X) (opts.options[X].data.u32) +#define OPTS_OPTION_DUP(X) *(OPTS_OPTION_DUPED(X)=true, &(opts.options[X].data.str.p)) +#define OPTS_OPTION_STR(X) (opts.options[X].data.str.c) #endif /*! GMQCC_HDR */