]> git.xonotic.org Git - xonotic/gmqcc.git/blobdiff - exec.c
-ffalse-empty-strings in && and ||
[xonotic/gmqcc.git] / exec.c
diff --git a/exec.c b/exec.c
index 3955371d5c5fa5f44a5129c87036bb159f7d0600..f4a986ed8e6cb2e2def9b3ac73086070e8c5cc9f 100644 (file)
--- a/exec.c
+++ b/exec.c
 
 #include "gmqcc.h"
 
-/*
-(prog_section_statement, code)
-(prog_section_def,       defs)
-(prog_section_def,       fields)
-(prog_section_function,  functions)
-(char,                   strings)
-(qcint,                  globals)
-(qcint,                  entitydata)
-(bool,                   entitypool)
-(qcint,         localstack)
-(qc_exec_stack, stack)
-(size_t, profile)
-(prog_builtin, builtins)
-(const char*, function_stack)
-*/
-
 static void loaderror(const char *fmt, ...)
 {
     int     err = errno;
@@ -576,28 +560,24 @@ bool prog_exec(qc_program *prog, prog_section_function *func, size_t flags, long
 #define QCVM_PROFILE 0
 #define QCVM_TRACE   0
 #           include __FILE__
-            break;
         }
         case (VMXF_TRACE):
         {
 #define QCVM_PROFILE 0
 #define QCVM_TRACE   1
 #           include __FILE__
-            break;
         }
         case (VMXF_PROFILE):
         {
 #define QCVM_PROFILE 1
 #define QCVM_TRACE   0
 #           include __FILE__
-            break;
         }
         case (VMXF_TRACE|VMXF_PROFILE):
         {
 #define QCVM_PROFILE 1
 #define QCVM_TRACE   1
 #           include __FILE__
-            break;
         }
     };
 
@@ -617,7 +597,7 @@ cleanup:
 #if defined(QCVM_EXECUTOR)
 #include <math.h>
 
-cmd_options opts;
+opts_cmd_t opts;
 
 const char *type_name[TYPE_COUNT] = {
     "void",
@@ -660,7 +640,8 @@ static int qc_print(qc_program *prog)
     const char *laststr = NULL;
     for (i = 0; i < (size_t)prog->argc; ++i) {
         qcany *str = (qcany*)(prog->globals + OFS_PARM0 + 3*i);
-        printf("%s", (laststr = prog_getstring(prog, str->string)));
+        laststr = prog_getstring(prog, str->string);
+        printf("%s", laststr);
     }
     if (laststr && (prog->xflags & VMXF_TRACE)) {
         size_t len = strlen(laststr);
@@ -774,10 +755,32 @@ static size_t qc_builtins_count = sizeof(qc_builtins) / sizeof(qc_builtins[0]);
 
 static const char *arg0 = NULL;
 
-void usage()
+static void version() {
+    printf("GMQCC-QCVM %d.%d.%d Built %s %s\n",
+           GMQCC_VERSION_MAJOR,
+           GMQCC_VERSION_MINOR,
+           GMQCC_VERSION_PATCH,
+           __DATE__,
+           __TIME__
+    );
+}
+
+static void usage()
 {
-    printf("usage: [-debug] %s file\n", arg0);
-    exit(1);
+    printf("usage: %s [options] [parameters] file\n", arg0);
+    printf("options:\n");
+    printf("  -h, --help    print this message\n"
+           "  -trace        trace the execution\n"
+           "  -profile      perform profiling during execution\n"
+           "  -info         print information from the prog's header\n"
+           "  -disasm       disassemble and exit\n"
+           "  -printdefs    list the defs section\n"
+           "  -printfields  list the field section\n"
+           "  -printfuns    list functions information\n");
+    printf("parameters:\n");
+    printf("  -vector <V>   pass a vector parameter to main()\n"
+           "  -float  <f>   pass a float parameter to main()\n"
+           "  -string <s>   pass a string parameter to main() \n");
 }
 
 static void prog_main_setparams(qc_program *prog)
@@ -792,7 +795,7 @@ static void prog_main_setparams(qc_program *prog)
         arg->vector[2] = 0;
         switch (main_params[i].vtype) {
             case TYPE_VECTOR:
-#ifdef WIN32
+#ifdef _MSC_VER
                 (void)sscanf_s(main_params[i].value, " %f %f %f ",
                                &arg->vector[0],
                                &arg->vector[1],
@@ -828,15 +831,33 @@ int main(int argc, char **argv)
     bool        opts_printdefs   = false;
     bool        opts_printfuns   = false;
     bool        opts_disasm      = false;
-    bool        opts_info  = false;
+    bool        opts_info        = false;
+    bool        noexec           = false;
+    const char *progsfile        = NULL;
 
     arg0 = argv[0];
 
-    if (argc < 2)
+    if (argc < 2) {
         usage();
+        exit(1);
+    }
 
-    while (argc > 2) {
-        if (!strcmp(argv[1], "-trace")) {
+    while (argc > 1) {
+        if (!strcmp(argv[1], "-h") ||
+            !strcmp(argv[1], "-help") ||
+            !strcmp(argv[1], "--help"))
+        {
+            usage();
+            exit(0);
+        }
+        else if (!strcmp(argv[1], "-v") ||
+                 !strcmp(argv[1], "-version") ||
+                 !strcmp(argv[1], "--version"))
+        {
+            version();
+            exit(0);
+        }
+        else if (!strcmp(argv[1], "-trace")) {
             --argc;
             ++argv;
             xflags |= VMXF_TRACE;
@@ -850,26 +871,31 @@ int main(int argc, char **argv)
             --argc;
             ++argv;
             opts_info = true;
+            noexec = true;
         }
         else if (!strcmp(argv[1], "-disasm")) {
             --argc;
             ++argv;
             opts_disasm = true;
+            noexec = true;
         }
         else if (!strcmp(argv[1], "-printdefs")) {
             --argc;
             ++argv;
             opts_printdefs = true;
+            noexec = true;
         }
         else if (!strcmp(argv[1], "-printfuns")) {
             --argc;
             ++argv;
             opts_printfuns = true;
+            noexec = true;
         }
         else if (!strcmp(argv[1], "-printfields")) {
             --argc;
             ++argv;
             opts_printfields = true;
+            noexec = true;
         }
         else if (!strcmp(argv[1], "-vector") ||
                  !strcmp(argv[1], "-string") ||
@@ -885,22 +911,61 @@ int main(int argc, char **argv)
 
             --argc;
             ++argv;
-            if (argc < 3)
+            if (argc < 3) {
                 usage();
+                exit(1);
+            }
             p.value = argv[1];
 
             vec_push(main_params, p);
             --argc;
             ++argv;
         }
+        else if (!strcmp(argv[1], "--")) {
+            --argc;
+            ++argv;
+            break;
+        }
+        else if (argv[1][0] != '-') {
+            if (progsfile) {
+                printf("only 1 program file may be specified\n");
+                usage();
+                exit(1);
+            }
+            progsfile = argv[1];
+            --argc;
+            ++argv;
+        }
         else
+        {
+            usage();
+            exit(1);
+        }
+    }
+
+    if (argc > 2) {
+        usage();
+        exit(1);
+    }
+    if (argc > 1) {
+        if (progsfile) {
+            printf("only 1 program file may be specified\n");
             usage();
+            exit(1);
+        }
+        progsfile = argv[1];
+        --argc;
+        ++argv;
     }
 
+    if (!progsfile) {
+        usage();
+        exit(1);
+    }
 
-    prog = prog_load(argv[1]);
+    prog = prog_load(progsfile);
     if (!prog) {
-        printf("failed to load program '%s'\n", argv[1]);
+        printf("failed to load program '%s'\n", progsfile);
         exit(1);
     }
 
@@ -913,12 +978,6 @@ int main(int argc, char **argv)
         printf("Globals: %u\n", (unsigned int)vec_size(prog->globals));
     }
 
-    for (i = 1; i < vec_size(prog->functions); ++i) {
-        const char *name = prog_getstring(prog, prog->functions[i].name);
-        /* printf("Found function: %s\n", name); */
-        if (!strcmp(name, "main"))
-            fnmain = (qcint)i;
-    }
     if (opts_info) {
         prog_delete(prog);
         return 0;
@@ -930,21 +989,23 @@ int main(int argc, char **argv)
     }
     if (opts_printdefs) {
         for (i = 0; i < vec_size(prog->defs); ++i) {
-            printf("Global: %8s %-16s at %u\n",
+            printf("Global: %8s %-16s at %u%s\n",
                    type_name[prog->defs[i].type & DEF_TYPEMASK],
                    prog_getstring(prog, prog->defs[i].name),
-                   (unsigned int)prog->defs[i].offset);
+                   (unsigned int)prog->defs[i].offset,
+                   ((prog->defs[i].type & DEF_SAVEGLOBAL) ? " [SAVE]" : ""));
         }
     }
-    else if (opts_printfields) {
+    if (opts_printfields) {
         for (i = 0; i < vec_size(prog->fields); ++i) {
-            printf("Field: %8s %-16s at %u\n",
+            printf("Field: %8s %-16s at %u%s\n",
                    type_name[prog->fields[i].type],
                    prog_getstring(prog, prog->fields[i].name),
-                   (unsigned int)prog->fields[i].offset);
+                   (unsigned int)prog->fields[i].offset,
+                   ((prog->fields[i].type & DEF_SAVEGLOBAL) ? " [SAVE]" : ""));
         }
     }
-    else if (opts_printfuns) {
+    if (opts_printfuns) {
         for (i = 0; i < vec_size(prog->functions); ++i) {
             int32_t a;
             printf("Function: %-16s taking %i parameters:(",
@@ -958,8 +1019,12 @@ int main(int argc, char **argv)
                    prog->functions[i].locals);
         }
     }
-    else
-    {
+    if (!noexec) {
+        for (i = 1; i < vec_size(prog->functions); ++i) {
+            const char *name = prog_getstring(prog, prog->functions[i].name);
+            if (!strcmp(name, "main"))
+                fnmain = (qcint)i;
+        }
         if (fnmain > 0)
         {
             prog_main_setparams(prog);
@@ -986,7 +1051,7 @@ void prog_disasm_function(qc_program *prog, size_t id)
         printf("FUNCTION \"%s\"\n", prog_getstring(prog, fdef->name));
 
     st = prog->code + fdef->entry;
-    while (st->opcode != AINSTR_END) {
+    while (st->opcode != INSTR_DONE) {
         prog_print_statement(prog, st);
         ++st;
     }