Cleanups and fixes
authorDale Weiler <killfieldengine@gmail.com>
Wed, 29 May 2013 02:16:50 +0000 (02:16 +0000)
committerDale Weiler <killfieldengine@gmail.com>
Wed, 29 May 2013 02:16:50 +0000 (02:16 +0000)
Makefile
code.c
exec.c
gmqcc.h
main.c
pak.c

index f713417be1d47a4adb405b073190b9b66302ef0a..01a5dac15054b4facb70bda399283f5732240e10 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -163,7 +163,6 @@ SPLINTFLAGS =            \
     -realcompare         \
     -observertrans       \
     -shiftnegative       \
-    -freshtrans          \
     -abstract            \
     -statictrans         \
     -castfcnptr
diff --git a/code.c b/code.c
index 80154d0b03ae9be28ed57d71146d08f30d0f1532..35f758a22526f966cc00c7a28c45c74c0ee0d43a 100644 (file)
--- a/code.c
+++ b/code.c
  */
 #include "gmqcc.h"
 
-/* This is outrageous! */
-#define QCINT_ENTRY void*
-#define QCINT_TO_HASH_ENTRY(q) ((void*)(uintptr_t)(q))
-#define HASH_ENTRY_TO_QCINT(h) ((qcint)(uintptr_t)(h))
+/*
+ * We could use the old method of casting to uintptr_t then to void*
+ * or qcint; however, it's incredibly unsafe for two reasons.
+ * 1) The compilers aliasing optimization can legally make it unstable
+ *    (it's undefined behaviour).
+ * 
+ * 2) The cast itself depends on fresh storage (newly allocated in which
+ *    ever function is using the cast macros), the contents of which are
+ *    transferred in a way that the obligation to release storage is not
+ *    propagated.
+ */
+typedef union {
+    void   *enter;
+    qcint   leave;
+} code_hash_entry_t;
+
+/* Some sanity macros */
+#define CODE_HASH_ENTER(ENTRY) ((ENTRY).enter)
+#define CODE_HASH_LEAVE(ENTRY) ((ENTRY).leave)
 
 void code_push_statement(code_t *code, prog_section_statement *stmt, int linenum)
 {
@@ -72,11 +87,9 @@ code_t *code_init() {
 
 void *code_util_str_htgeth(hash_table_t *ht, const char *key, size_t bin);
 
-uint32_t code_genstring(code_t *code, const char *str)
-{
-    uint32_t off;
-    size_t   hash;
-    QCINT_ENTRY existing;
+uint32_t code_genstring(code_t *code, const char *str) {
+    size_t            hash;
+    code_hash_entry_t existing;
 
     if (!str)
         return 0;
@@ -90,21 +103,21 @@ uint32_t code_genstring(code_t *code, const char *str)
     }
 
     if (OPTS_OPTIMIZATION(OPTIM_OVERLAP_STRINGS)) {
-        hash     = ((unsigned char*)str)[strlen(str)-1];
-        existing = code_util_str_htgeth(code->string_cache, str, hash);
+        hash                      = ((unsigned char*)str)[strlen(str)-1];
+        CODE_HASH_ENTER(existing) = code_util_str_htgeth(code->string_cache, str, hash);
     } else {
-        hash     = util_hthash(code->string_cache, str);
-        existing = util_htgeth(code->string_cache, str, hash);
+        hash                      = util_hthash(code->string_cache, str);
+        CODE_HASH_ENTER(existing) = util_htgeth(code->string_cache, str, hash);
     }
 
-    if (existing)
-        return HASH_ENTRY_TO_QCINT(existing);
+    if (CODE_HASH_ENTER(existing))
+        return CODE_HASH_LEAVE(existing);
 
-    off = vec_size(code->chars);
+    CODE_HASH_LEAVE(existing) = vec_size(code->chars);
     vec_upload(code->chars, str, strlen(str)+1);
 
-    util_htseth(code->string_cache, str, hash, QCINT_TO_HASH_ENTRY(off));
-    return off;
+    util_htseth(code->string_cache, str, hash, CODE_HASH_ENTER(existing));
+    return CODE_HASH_LEAVE(existing);
 }
 
 qcint code_alloc_field (code_t *code, size_t qcsize)
diff --git a/exec.c b/exec.c
index 9bb353915831433a297853b1d5e3b240036493c7..49cff447a223df7b8f24b55ad9c7ba1103f3f90e 100644 (file)
--- a/exec.c
+++ b/exec.c
@@ -167,16 +167,15 @@ void prog_delete(qc_program *prog)
  * VM code
  */
 
-char* prog_getstring(qc_program *prog, qcint str)
-{
+const char* prog_getstring(qc_program *prog, qcint str) {
     /* cast for return required for C++ */
     if (str < 0 || str >= (qcint)vec_size(prog->strings))
-        return (char*)"<<<invalid string>>>";
+        return  "<<<invalid string>>>";
+        
     return prog->strings + str;
 }
 
-prog_section_def* prog_entfield(qc_program *prog, qcint off)
-{
+prog_section_def* prog_entfield(qc_program *prog, qcint off) {
     size_t i;
     for (i = 0; i < vec_size(prog->fields); ++i) {
         if (prog->fields[i].offset == off)
@@ -195,8 +194,7 @@ prog_section_def* prog_getdef(qc_program *prog, qcint off)
     return NULL;
 }
 
-qcany* prog_getedict(qc_program *prog, qcint e)
-{
+qcany* prog_getedict(qc_program *prog, qcint e) {
     if (e >= (qcint)vec_size(prog->entitypool)) {
         prog->vmerror++;
         fprintf(stderr, "Accessing out of bounds edict %i\n", (int)e);
@@ -205,8 +203,7 @@ qcany* prog_getedict(qc_program *prog, qcint e)
     return (qcany*)(prog->entitydata + (prog->entityfields * e));
 }
 
-qcint prog_spawn_entity(qc_program *prog)
-{
+qcint prog_spawn_entity(qc_program *prog) {
     char  *data;
     qcint  e;
     for (e = 0; e < (qcint)vec_size(prog->entitypool); ++e) {
@@ -223,8 +220,7 @@ qcint prog_spawn_entity(qc_program *prog)
     return e;
 }
 
-void prog_free_entity(qc_program *prog, qcint e)
-{
+void prog_free_entity(qc_program *prog, qcint e) {
     if (!e) {
         prog->vmerror++;
         fprintf(stderr, "Trying to free world entity\n");
@@ -243,8 +239,7 @@ void prog_free_entity(qc_program *prog, qcint e)
     prog->entitypool[e] = false;
 }
 
-qcint prog_tempstring(qc_program *prog, const char *str)
-{
+qcint prog_tempstring(qc_program *prog, const char *str) {
     size_t len = strlen(str);
     size_t at = prog->tempstring_at;
 
@@ -266,8 +261,7 @@ qcint prog_tempstring(qc_program *prog, const char *str)
     return at;
 }
 
-static size_t print_escaped_string(const char *str, size_t maxlen)
-{
+static size_t print_escaped_string(const char *str, size_t maxlen) {
     size_t len = 2;
     putchar('"');
     --maxlen; /* because we're lazy and have escape sequences */
@@ -300,8 +294,7 @@ static size_t print_escaped_string(const char *str, size_t maxlen)
     return len;
 }
 
-static void trace_print_global(qc_program *prog, unsigned int glob, int vtype)
-{
+static void trace_print_global(qc_program *prog, unsigned int glob, int vtype) {
     static char spaces[28+1] = "                            ";
     prog_section_def *def;
     qcany    *value;
@@ -359,8 +352,7 @@ done:
     }
 }
 
-static void prog_print_statement(qc_program *prog, prog_section_statement *st)
-{
+static void prog_print_statement(qc_program *prog, prog_section_statement *st) {
     if (st->opcode >= (sizeof(asm_instr)/sizeof(asm_instr[0]))) {
         printf("<illegal instruction %d>\n", st->opcode);
         return;
@@ -457,8 +449,7 @@ static void prog_print_statement(qc_program *prog, prog_section_statement *st)
     }
 }
 
-static qcint prog_enterfunction(qc_program *prog, prog_section_function *func)
-{
+static qcint prog_enterfunction(qc_program *prog, prog_section_function *func) {
     qc_exec_stack st;
     size_t  parampos;
     int32_t p;
@@ -507,8 +498,7 @@ static qcint prog_enterfunction(qc_program *prog, prog_section_function *func)
     return func->entry;
 }
 
-static qcint prog_leavefunction(qc_program *prog)
-{
+static qcint prog_leavefunction(qc_program *prog) {
     prog_section_function *prev = NULL;
     size_t oldsp;
 
@@ -540,8 +530,7 @@ static qcint prog_leavefunction(qc_program *prog)
     return st.stmt - 1; /* offset the ++st */
 }
 
-bool prog_exec(qc_program *prog, prog_section_function *func, size_t flags, long maxjumps)
-{
+bool prog_exec(qc_program *prog, prog_section_function *func, size_t flags, long maxjumps) {
     long jumpcount = 0;
     size_t oldxflags = prog->xflags;
     prog_section_statement *st;
@@ -640,8 +629,7 @@ static qcvm_parameter *main_params = NULL;
 #define GetArg(num) GetGlobal(OFS_PARM0 + 3*(num))
 #define Return(any) *(GetGlobal(OFS_RETURN)) = (any)
 
-static int qc_print(qc_program *prog)
-{
+static int qc_print(qc_program *prog) {
     size_t i;
     const char *laststr = NULL;
     for (i = 0; i < (size_t)prog->argc; ++i) {
@@ -657,16 +645,14 @@ static int qc_print(qc_program *prog)
     return 0;
 }
 
-static int qc_error(qc_program *prog)
-{
+static int qc_error(qc_program *prog) {
     fprintf(stderr, "*** VM raised an error:\n");
     qc_print(prog);
     prog->vmerror++;
     return -1;
 }
 
-static int qc_ftos(qc_program *prog)
-{
+static int qc_ftos(qc_program *prog) {
     char buffer[512];
     qcany *num;
     qcany str;
@@ -678,8 +664,7 @@ static int qc_ftos(qc_program *prog)
     return 0;
 }
 
-static int qc_stof(qc_program *prog)
-{
+static int qc_stof(qc_program *prog) {
     qcany *str;
     qcany num;
     CheckArgs(1);
@@ -689,8 +674,7 @@ static int qc_stof(qc_program *prog)
     return 0;
 }
 
-static int qc_vtos(qc_program *prog)
-{
+static int qc_vtos(qc_program *prog) {
     char buffer[512];
     qcany *num;
     qcany str;
@@ -702,8 +686,7 @@ static int qc_vtos(qc_program *prog)
     return 0;
 }
 
-static int qc_etos(qc_program *prog)
-{
+static int qc_etos(qc_program *prog) {
     char buffer[512];
     qcany *num;
     qcany str;
@@ -715,8 +698,7 @@ static int qc_etos(qc_program *prog)
     return 0;
 }
 
-static int qc_spawn(qc_program *prog)
-{
+static int qc_spawn(qc_program *prog) {
     qcany ent;
     CheckArgs(0);
     ent.edict = prog_spawn_entity(prog);
@@ -724,8 +706,7 @@ static int qc_spawn(qc_program *prog)
     return (ent.edict ? 0 : -1);
 }
 
-static int qc_kill(qc_program *prog)
-{
+static int qc_kill(qc_program *prog) {
     qcany *ent;
     CheckArgs(1);
     ent = GetArg(0);
@@ -733,8 +714,7 @@ static int qc_kill(qc_program *prog)
     return 0;
 }
 
-static int qc_sqrt(qc_program *prog)
-{
+static int qc_sqrt(qc_program *prog) {
     qcany *num, out;
     CheckArgs(1);
     num = GetArg(0);
@@ -743,8 +723,7 @@ static int qc_sqrt(qc_program *prog)
     return 0;
 }
 
-static int qc_vlen(qc_program *prog)
-{
+static int qc_vlen(qc_program *prog) {
     qcany *vec, len;
     CheckArgs(1);
     vec = GetArg(0);
@@ -755,8 +734,7 @@ static int qc_vlen(qc_program *prog)
     return 0;
 }
 
-static int qc_normalize(qc_program *prog)
-{
+static int qc_normalize(qc_program *prog) {
     double len;
     qcany *vec;
     qcany out;
@@ -776,13 +754,14 @@ static int qc_normalize(qc_program *prog)
     return 0;
 }
 
-static int qc_strcat(qc_program *prog)
-{
+static int qc_strcat(qc_program *prog) {
     char  *buffer;
     size_t len1,   len2;
-    char  *cstr1, *cstr2;
     qcany *str1,  *str2;
     qcany  out;
+    
+    const char *cstr1;
+    const char *cstr2;
 
     CheckArgs(2);
     str1 = GetArg(0);
@@ -800,12 +779,13 @@ static int qc_strcat(qc_program *prog)
     return 0;
 }
 
-static int qc_strcmp(qc_program *prog)
-{
-    char  *cstr1, *cstr2;
+static int qc_strcmp(qc_program *prog) {
     qcany *str1,  *str2;
     qcany out;
 
+    const char *cstr1;
+    const char *cstr2;
+    
     if (prog->argc != 2 && prog->argc != 3) {
         fprintf(stderr, "ERROR: invalid number of arguments for strcmp/strncmp: %i, expected 2 or 3\n",
                prog->argc);
@@ -824,8 +804,7 @@ static int qc_strcmp(qc_program *prog)
     return 0;
 }
 
-static int qc_floor(qc_program *prog)
-{
+static int qc_floor(qc_program *prog) {
     qcany *num, out;
     CheckArgs(1);
     num = GetArg(0);
@@ -865,8 +844,7 @@ static void version() {
     );
 }
 
-static void usage()
-{
+static void usage() {
     printf("usage: %s [options] [parameters] file\n", arg0);
     printf("options:\n");
     printf("  -h, --help         print this message\n"
@@ -886,8 +864,7 @@ static void usage()
            "  -string <s>   pass a string parameter to main() \n");
 }
 
-static void prog_main_setparams(qc_program *prog)
-{
+static void prog_main_setparams(qc_program *prog) {
     size_t i;
     qcany *arg;
 
@@ -950,8 +927,8 @@ void escapestring(char* dest, const char* src)  {
 }
 
 void prog_disasm_function(qc_program *prog, size_t id);
-int main(int argc, char **argv)
-{
+
+int main(int argc, char **argv) {
     size_t      i;
     qcint       fnmain = -1;
     qc_program *prog;
@@ -1266,8 +1243,7 @@ int main(int argc, char **argv)
     return 0;
 }
 
-void prog_disasm_function(qc_program *prog, size_t id)
-{
+void prog_disasm_function(qc_program *prog, size_t id) {
     prog_section_function *fdef = prog->functions + id;
     prog_section_statement *st;
 
diff --git a/gmqcc.h b/gmqcc.h
index fc93d92b002857e7476d187679194156891bd460..2e019a561138ee990b0f256b5f59422940cdbe33 100644 (file)
--- a/gmqcc.h
+++ b/gmqcc.h
@@ -993,7 +993,7 @@ void        prog_delete(qc_program *prog);
 
 bool prog_exec(qc_program *prog, prog_section_function *func, size_t flags, long maxjumps);
 
-char*             prog_getstring (qc_program *prog, qcint str);
+const char*       prog_getstring (qc_program *prog, qcint str);
 prog_section_def* prog_entfield  (qc_program *prog, qcint off);
 prog_section_def* prog_getdef    (qc_program *prog, qcint off);
 qcany*            prog_getedict  (qc_program *prog, qcint e);
diff --git a/main.c b/main.c
index bbc685a05fdb69bb2b8e7d31071e7d620468df58..840a6a730fe83065b663ef92875cdb1948ba8fc9 100644 (file)
--- a/main.c
+++ b/main.c
@@ -41,6 +41,7 @@ static ppitem  *ppems = NULL;
 #define TYPE_ASM 1
 #define TYPE_SRC 2
 
+
 static const char *app_name;
 
 static void version() {
diff --git a/pak.c b/pak.c
index 653a4630a133905d62c99845c9902e15dddf3566..0f90d675133dbca860bf9aa709f89d0a3cb7f411 100644 (file)
--- a/pak.c
+++ b/pak.c
@@ -575,7 +575,6 @@ int main(int argc, char **argv) {
     pak_close(pak);
     vec_free(files);
 
-
     util_meminfo();
     return EXIT_SUCCESS;
 }