#include <errno.h>
+#include <stdio.h>
#include <string.h>
#include <stdarg.h>
printf(": %s\n", strerror(err));
}
-static void printvmerr(const char *fmt, ...)
+static void qcvmerror(qc_program *prog, const char *fmt, ...)
{
va_list ap;
+
+ prog->vmerror++;
+
va_start(ap, fmt);
vprintf(fmt, ap);
va_end(ap);
size_t i;
FILE *file;
- file = fopen(filename, "rb");
+ file = util_fopen(filename, "rb");
if (!file)
return NULL;
memset(prog, 0, sizeof(*prog));
prog->entityfields = header.entfield;
+ prog->crc16 = header.crc16;
prog->filename = util_strdup(filename);
if (!prog->filename) {
static void trace_print_global(qc_program *prog, unsigned int glob, int vtype)
{
- static char spaces[16+1] = " ";
+ static char spaces[40+1] = " ";
prog_section_def *def;
qcany *value;
int len;
- if (!glob)
- return;
+ if (!glob) {
+ len = printf("<null>,");
+ goto done;
+ }
def = prog_getdef(prog, glob);
value = (qcany*)(&prog->globals[glob]);
break;
case TYPE_STRING:
len += print_escaped_string(prog_getstring(prog, value->string));
+ len += printf(",");
/* len += printf("\"%s\",", prog_getstring(prog, value->string)); */
break;
case TYPE_FLOAT:
len += printf("%g,", value->_float);
break;
}
- if (len < 16) {
- spaces[16-len] = 0;
+done:
+ if (len < sizeof(spaces)-1) {
+ spaces[sizeof(spaces)-1-len] = 0;
printf(spaces);
- spaces[16-len] = ' ';
+ spaces[sizeof(spaces)-1-len] = ' ';
}
}
case INSTR_NE_S:
t[0] = t[1] = TYPE_STRING;
break;
+ case INSTR_STORE_F:
+ case INSTR_STOREP_F:
+ t[2] = -1;
+ break;
case INSTR_STORE_V:
t[0] = t[1] = TYPE_VECTOR; t[2] = -1;
break;
case INSTR_STORE_S:
t[0] = t[1] = TYPE_STRING; t[2] = -1;
break;
+ case INSTR_STORE_ENT:
+ t[0] = t[1] = TYPE_ENTITY; t[2] = -1;
+ break;
+ case INSTR_STORE_FLD:
+ t[0] = t[1] = TYPE_FIELD; t[2] = -1;
+ break;
+ case INSTR_STORE_FNC:
+ t[0] = t[1] = TYPE_FUNCTION; t[2] = -1;
+ break;
+ case INSTR_STOREP_V:
+ t[0] = TYPE_VECTOR; t[1] = TYPE_ENTITY; t[2] = -1;
+ break;
+ case INSTR_STOREP_S:
+ t[0] = TYPE_STRING; t[1] = TYPE_ENTITY; t[2] = -1;
+ break;
+ case INSTR_STOREP_ENT:
+ t[0] = TYPE_ENTITY; t[1] = TYPE_ENTITY; t[2] = -1;
+ break;
+ case INSTR_STOREP_FLD:
+ t[0] = TYPE_FIELD; t[1] = TYPE_ENTITY; t[2] = -1;
+ break;
+ case INSTR_STOREP_FNC:
+ t[0] = TYPE_FUNCTION; t[1] = TYPE_ENTITY; t[2] = -1;
+ break;
}
if (t[0] >= 0) trace_print_global(prog, st->o1.u1, t[0]);
+ else printf("(none), ");
if (t[1] >= 0) trace_print_global(prog, st->o2.u1, t[1]);
+ else printf("(none), ");
if (t[2] >= 0) trace_print_global(prog, st->o3.u1, t[2]);
+ else printf("(none)");
printf("\n");
}
+ fflush(stdout);
}
static qcint prog_enterfunction(qc_program *prog, prog_section_function *func)
exit(1);
}
- return st.stmt;
+ return st.stmt - 1; /* offset the ++st */
}
bool prog_exec(qc_program *prog, prog_section_function *func, size_t flags, long maxjumps)
*/
#if defined(QCVM_EXECUTOR)
+const char *type_name[TYPE_COUNT] = {
+ "void",
+ "string",
+ "float",
+ "vector",
+ "entity",
+ "field",
+ "function",
+ "pointer",
+#if 0
+ "integer",
+#endif
+ "variant"
+};
+
bool opts_debug = false;
bool opts_memchk = false;
return 0;
}
+static int qc_vtos(qc_program *prog)
+{
+ char buffer[512];
+ qcany *num;
+ qcany str;
+ CheckArgs(1);
+ num = GetArg(0);
+ snprintf(buffer, sizeof(buffer), "`%g %g %g`", num->vector[0], num->vector[1], num->vector[2]);
+ str.string = prog_tempstring(prog, buffer);
+ Return(str);
+ return 0;
+}
+
static int qc_spawn(qc_program *prog)
{
qcany ent;
&qc_print,
&qc_ftos,
&qc_spawn,
- &qc_kill
+ &qc_kill,
+ &qc_vtos,
};
static size_t qc_builtins_count = sizeof(qc_builtins) / sizeof(qc_builtins[0]);
+static const char *arg0 = NULL;
+
+void usage()
+{
+ printf("usage: [-debug] %s file\n", arg0);
+ exit(1);
+}
+
int main(int argc, char **argv)
{
size_t i;
qcint fnmain = -1;
qc_program *prog;
+ size_t xflags = VMXF_DEFAULT;
+ bool opts_printfields = false;
+ bool opts_printdefs = false;
+ bool opts_info = false;
- if (argc != 2) {
- printf("usage: %s file\n", argv[0]);
- exit(1);
+ arg0 = argv[0];
+
+ if (argc < 2)
+ usage();
+
+ while (argc > 2) {
+ if (!strcmp(argv[1], "-trace")) {
+ --argc;
+ ++argv;
+ xflags |= VMXF_TRACE;
+ }
+ else if (!strcmp(argv[1], "-profile")) {
+ --argc;
+ ++argv;
+ xflags |= VMXF_PROFILE;
+ }
+ else if (!strcmp(argv[1], "-info")) {
+ --argc;
+ ++argv;
+ opts_info = true;
+ }
+ else if (!strcmp(argv[1], "-printdefs")) {
+ --argc;
+ ++argv;
+ opts_printdefs = true;
+ }
+ else if (!strcmp(argv[1], "-printfields")) {
+ --argc;
+ ++argv;
+ opts_printfields = true;
+ }
+ else
+ usage();
}
+
prog = prog_load(argv[1]);
if (!prog) {
printf("failed to load program '%s'\n", argv[1]);
prog->builtins_count = qc_builtins_count;
prog->builtins_alloc = 0;
+ printf("Program's system-checksum = 0x%04x\n", (int)prog->crc16);
+
for (i = 1; i < prog->functions_count; ++i) {
const char *name = prog_getstring(prog, prog->functions[i].name);
- printf("Found function: %s\n", name);
+ /* printf("Found function: %s\n", name); */
if (!strcmp(name, "main"))
fnmain = (qcint)i;
}
printf("Entity field space: %i\n", (int)prog->entityfields);
- if (fnmain > 0)
- {
- prog_exec(prog, &prog->functions[fnmain], VMXF_TRACE, VM_JUMPS_DEFAULT);
+ if (opts_info) {
+ prog_delete(prog);
+ return 0;
+ }
+ if (opts_printdefs) {
+ for (i = 0; i < prog->defs_count; ++i) {
+ printf("Global: %8s %-16s at %u\n",
+ type_name[prog->defs[i].type],
+ prog_getstring(prog, prog->defs[i].name),
+ (unsigned int)prog->defs[i].offset);
+ }
+ }
+ else if (opts_printfields) {
+ for (i = 0; i < prog->fields_count; ++i) {
+ printf("Field: %8s %-16s at %u\n",
+ type_name[prog->fields[i].type],
+ prog_getstring(prog, prog->fields[i].name),
+ (unsigned int)prog->fields[i].offset);
+ }
}
else
- printf("No main function found\n");
+ {
+ if (fnmain > 0)
+ {
+ prog_exec(prog, &prog->functions[fnmain], xflags, VM_JUMPS_DEFAULT);
+ }
+ else
+ printf("No main function found\n");
+ }
prog_delete(prog);
return 0;