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;
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;
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;
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;
};
cleanup:
+ prog->xflags = oldxflags;
prog->localstack_count = 0;
prog->stack_count = 0;
if (prog->vmerror)
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++; \
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;
}
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;
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;
++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();
}
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);
if (!strcmp(name, "main"))
fnmain = (qcint)i;
}
- printf("Entity field space: %i\n", (int)prog->entityfields);
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],
+ type_name[prog->defs[i].type & DEF_TYPEMASK],
prog_getstring(prog, prog->defs[i].name),
(unsigned int)prog->defs[i].offset);
}
{
if (fnmain > 0)
{
+ prog_main_setparams(prog);
prog_exec(prog, &prog->functions[fnmain], xflags, VM_JUMPS_DEFAULT);
}
else