X-Git-Url: https://git.xonotic.org/?a=blobdiff_plain;f=exec.c;h=bb35ee9e3ac1fc30a375ec6539523ac099efe335;hb=b2cb612c703a8135b50fbcbfcab4f9ce7df0c4ce;hp=75202575dc0b6f03342fc0488f5f722d5ee5442f;hpb=9433f66a00c61f5f20edf05d8b8c50cc8a44b205;p=xonotic%2Fgmqcc.git diff --git a/exec.c b/exec.c index 7520257..bb35ee9 100644 --- a/exec.c +++ b/exec.c @@ -218,11 +218,12 @@ qcany* prog_getedict(qc_program *prog, qcint e) qcint prog_spawn_entity(qc_program *prog) { + char *data; size_t i; qcint e; for (e = 0; e < (qcint)prog->entitypool_count; ++e) { if (!prog->entitypool[e]) { - char *data = (char*)(prog->entitydata + (prog->entityfields * e)); + data = (char*)(prog->entitydata + (prog->entityfields * e)); memset(data, 0, prog->entityfields * sizeof(qcint)); return e; } @@ -239,6 +240,8 @@ qcint prog_spawn_entity(qc_program *prog) return 0; } } + data = (char*)(prog->entitydata + (prog->entityfields * e)); + memset(data, 0, prog->entityfields * sizeof(qcint)); return e; } @@ -293,11 +296,19 @@ qcint prog_tempstring(qc_program *prog, const char *_str) return at; } -static int print_escaped_string(const char *str) +static int print_escaped_string(const char *str, size_t maxlen) { int len = 2; putchar('"'); + --maxlen; /* because we're lazy and have escape sequences */ while (*str) { + if (len >= maxlen) { + putchar('.'); + putchar('.'); + putchar('.'); + len += 3; + break; + } switch (*str) { case '\a': len += 2; putchar('\\'); putchar('a'); break; case '\b': len += 2; putchar('\\'); putchar('b'); break; @@ -321,7 +332,7 @@ static int print_escaped_string(const char *str) static void trace_print_global(qc_program *prog, unsigned int glob, int vtype) { - static char spaces[40+1] = " "; + static char spaces[28+1] = " "; prog_section_def *def; qcany *value; int len; @@ -335,7 +346,11 @@ static void trace_print_global(qc_program *prog, unsigned int glob, int vtype) value = (qcany*)(&prog->globals[glob]); if (def) { - len = printf("[%s] ", prog_getstring(prog, def->name)); + const char *name = prog_getstring(prog, def->name); + if (name[0] == '#') + len = printf("$"); + else + len = printf("%s ", name); vtype = def->type; } else @@ -347,7 +362,7 @@ static void trace_print_global(qc_program *prog, unsigned int glob, int vtype) case TYPE_FIELD: case TYPE_FUNCTION: case TYPE_POINTER: - len += printf("%i,", value->_int); + len += printf("(%i),", value->_int); break; case TYPE_VECTOR: len += printf("'%g %g %g',", value->vector[0], @@ -355,7 +370,7 @@ static void trace_print_global(qc_program *prog, unsigned int glob, int vtype) value->vector[2]); break; case TYPE_STRING: - len += print_escaped_string(prog_getstring(prog, value->string)); + len += print_escaped_string(prog_getstring(prog, value->string), sizeof(spaces)-len-5); len += printf(","); /* len += printf("\"%s\",", prog_getstring(prog, value->string)); */ break; @@ -555,9 +570,11 @@ static qcint prog_leavefunction(qc_program *prog) 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; prog->vmerror = 0; + prog->xflags = flags; st = prog->code + prog_enterfunction(prog, func); --st; @@ -595,6 +612,7 @@ bool prog_exec(qc_program *prog, prog_section_function *func, size_t flags, long }; cleanup: + prog->xflags = oldxflags; prog->localstack_count = 0; prog->stack_count = 0; if (prog->vmerror) @@ -607,6 +625,8 @@ cleanup: */ #if defined(QCVM_EXECUTOR) +#include + const char *type_name[TYPE_COUNT] = { "void", "string", @@ -625,6 +645,13 @@ const char *type_name[TYPE_COUNT] = { bool opts_debug = false; bool opts_memchk = false; +typedef struct { + int vtype; + const char *value; +} qcvm_parameter; + +VECTOR_MAKE(qcvm_parameter, main_params); + #define CheckArgs(num) do { \ if (prog->argc != (num)) { \ prog->vmerror++; \ @@ -641,13 +668,27 @@ bool opts_memchk = false; static int qc_print(qc_program *prog) { size_t i; + const char *laststr = NULL; for (i = 0; i < prog->argc; ++i) { qcany *str = (qcany*)(prog->globals + OFS_PARM0 + 3*i); - printf("%s", prog_getstring(prog, str->string)); + printf("%s", (laststr = prog_getstring(prog, str->string))); + } + if (laststr && (prog->xflags & VMXF_TRACE)) { + size_t len = strlen(laststr); + if (!len || laststr[len-1] != '\n') + printf("\n"); } return 0; } +static int qc_error(qc_program *prog) +{ + printf("*** VM raised an error:\n"); + qc_print(prog); + prog->vmerror++; + return -1; +} + static int qc_ftos(qc_program *prog) { char buffer[512]; @@ -668,7 +709,7 @@ static int qc_vtos(qc_program *prog) qcany str; CheckArgs(1); num = GetArg(0); - snprintf(buffer, sizeof(buffer), "%g %g %g", num->vector[0], num->vector[1], num->vector[2]); + 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; @@ -692,13 +733,27 @@ static int qc_kill(qc_program *prog) return 0; } +static int qc_vlen(qc_program *prog) +{ + qcany *vec, len; + CheckArgs(1); + vec = GetArg(0); + len._float = sqrt(vec->vector[0] * vec->vector[0] + + vec->vector[1] * vec->vector[1] + + vec->vector[2] * vec->vector[2]); + Return(len); + return 0; +} + static prog_builtin qc_builtins[] = { NULL, - &qc_print, - &qc_ftos, - &qc_spawn, - &qc_kill, - &qc_vtos, + &qc_print, /* 1 */ + &qc_ftos, /* 2 */ + &qc_spawn, /* 3 */ + &qc_kill, /* 4 */ + &qc_vtos, /* 5 */ + &qc_error, /* 6 */ + &qc_vlen /* 7 */ }; static size_t qc_builtins_count = sizeof(qc_builtins) / sizeof(qc_builtins[0]); @@ -710,6 +765,43 @@ void usage() exit(1); } +static void prog_main_setparams(qc_program *prog) +{ + size_t i; + qcany *arg; + + for (i = 0; i < main_params_elements; ++i) { + arg = GetGlobal(OFS_PARM0 + 3*i); + arg->vector[0] = 0; + arg->vector[1] = 0; + arg->vector[2] = 0; + switch (main_params_data[i].vtype) { + case TYPE_VECTOR: +#ifdef WIN32 + (void)sscanf_s(main_params_data[i].value, " %f %f %f ", + &arg->vector[0], + &arg->vector[1], + &arg->vector[2]); +#else + (void)sscanf(main_params_data[i].value, " %f %f %f ", + &arg->vector[0], + &arg->vector[1], + &arg->vector[2]); +#endif + break; + case TYPE_FLOAT: + arg->_float = atof(main_params_data[i].value); + break; + case TYPE_STRING: + arg->string = prog_tempstring(prog, main_params_data[i].value); + break; + default: + printf("error: unhandled parameter type: %i\n", main_params_data[i].vtype); + break; + } + } +} + int main(int argc, char **argv) { size_t i; @@ -751,6 +843,33 @@ int main(int argc, char **argv) ++argv; opts_printfields = true; } + else if (!strcmp(argv[1], "-vector") || + !strcmp(argv[1], "-string") || + !strcmp(argv[1], "-float") ) + { + qcvm_parameter p; + if (argv[1][1] == 'f') + p.vtype = TYPE_FLOAT; + else if (argv[1][1] == 's') + p.vtype = TYPE_STRING; + else if (argv[1][1] == 'v') + p.vtype = TYPE_VECTOR; + + --argc; + ++argv; + if (argc < 3) + usage(); + p.value = argv[1]; + + if (main_params_add(p) < 0) { + if (main_params_data) + mem_d(main_params_data); + printf("cannot add parameter\n"); + exit(1); + } + --argc; + ++argv; + } else usage(); } @@ -766,7 +885,10 @@ int main(int argc, char **argv) prog->builtins_count = qc_builtins_count; prog->builtins_alloc = 0; - printf("Program's system-checksum = 0x%04x\n", (int)prog->crc16); + if (opts_info) { + printf("Program's system-checksum = 0x%04x\n", (int)prog->crc16); + printf("Entity field space: %i\n", (int)prog->entityfields); + } for (i = 1; i < prog->functions_count; ++i) { const char *name = prog_getstring(prog, prog->functions[i].name); @@ -774,7 +896,6 @@ int main(int argc, char **argv) if (!strcmp(name, "main")) fnmain = (qcint)i; } - printf("Entity field space: %i\n", (int)prog->entityfields); if (opts_info) { prog_delete(prog); return 0; @@ -782,7 +903,7 @@ int main(int argc, char **argv) if (opts_printdefs) { for (i = 0; i < prog->defs_count; ++i) { printf("Global: %8s %-16s at %u\n", - type_name[prog->defs[i].type], + type_name[prog->defs[i].type & DEF_TYPEMASK], prog_getstring(prog, prog->defs[i].name), (unsigned int)prog->defs[i].offset); } @@ -799,6 +920,7 @@ int main(int argc, char **argv) { if (fnmain > 0) { + prog_main_setparams(prog); prog_exec(prog, &prog->functions[fnmain], xflags, VM_JUMPS_DEFAULT); } else