X-Git-Url: https://git.xonotic.org/?p=xonotic%2Fgmqcc.git;a=blobdiff_plain;f=exec.c;h=2957d4c5bf315431353a5d6d7d9c8aaa7528adbc;hp=54201ffe66a0faeca60c28ae7e16b5d985c48959;hb=c0eca32b92c2a255ec33e0911a28af3ce91e20d4;hpb=67bc99223d064fd5ff5e719433e200ca8ca83b84 diff --git a/exec.c b/exec.c index 54201ff..2957d4c 100644 --- a/exec.c +++ b/exec.c @@ -359,7 +359,7 @@ static void trace_print_global(qc_program *prog, unsigned int glob, int vtype) done: if (len < (int)sizeof(spaces)-1) { spaces[sizeof(spaces)-1-len] = 0; - printf(spaces); + file_puts(stdout, spaces); spaces[sizeof(spaces)-1-len] = ' '; } } @@ -744,17 +744,67 @@ static int qc_vlen(qc_program *prog) return 0; } +static int qc_strcat(qc_program *prog) +{ + char *buffer; + size_t len1, len2; + char *cstr1, *cstr2; + qcany *str1, *str2; + qcany out; + + CheckArgs(2); + str1 = GetArg(0); + str2 = GetArg(1); + cstr1 = prog_getstring(prog, str1->string); + cstr2 = prog_getstring(prog, str2->string); + len1 = strlen(cstr1); + len2 = strlen(cstr2); + buffer = (char*)mem_a(len1 + len2 + 1); + memcpy(buffer, cstr1, len1); + memcpy(buffer+len1, cstr2, len2+1); + out.string = prog_tempstring(prog, buffer); + mem_d(buffer); + Return(out); + return 0; +} + +static int qc_strcmp(qc_program *prog) +{ + char *cstr1, *cstr2; + qcany *str1, *str2; + qcany out; + + if (prog->argc != 2 && prog->argc != 3) { + printf("ERROR: invalid number of arguments for strcmp/strncmp: %i, expected 2 or 3\n", + prog->argc); + return -1; + } + + str1 = GetArg(0); + str2 = GetArg(1); + cstr1 = prog_getstring(prog, str1->string); + cstr2 = prog_getstring(prog, str2->string); + if (prog->argc == 3) + out._float = strncmp(cstr1, cstr2, GetArg(2)->_float); + else + out._float = strcmp(cstr1, cstr2); + Return(out); + return 0; +} + static prog_builtin qc_builtins[] = { NULL, - &qc_print, /* 1 */ - &qc_ftos, /* 2 */ - &qc_spawn, /* 3 */ - &qc_kill, /* 4 */ - &qc_vtos, /* 5 */ - &qc_error, /* 6 */ - &qc_vlen, /* 7 */ - &qc_etos, /* 8 */ - &qc_stof /* 9 */ + &qc_print, /* 1 */ + &qc_ftos, /* 2 */ + &qc_spawn, /* 3 */ + &qc_kill, /* 4 */ + &qc_vtos, /* 5 */ + &qc_error, /* 6 */ + &qc_vlen, /* 7 */ + &qc_etos, /* 8 */ + &qc_stof, /* 9 */ + &qc_strcat, /* 10 */ + &qc_strcmp /* 11 */ }; static size_t qc_builtins_count = sizeof(qc_builtins) / sizeof(qc_builtins[0]); @@ -774,14 +824,17 @@ static void usage() { 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(" -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" + " -disasm-func func disassemble and exit\n" + " -printdefs list the defs section\n" + " -printfields list the field section\n" + " -printfuns list functions information\n" + " -v be verbose\n" + " -vv be even more verbose\n"); printf("parameters:\n"); printf(" -vector pass a vector parameter to main()\n" " -float pass a float parameter to main()\n" @@ -839,6 +892,8 @@ int main(int argc, char **argv) bool opts_info = false; bool noexec = false; const char *progsfile = NULL; + const char **dis_list = NULL; + int opts_v = 0; arg0 = argv[0]; @@ -855,8 +910,25 @@ int main(int argc, char **argv) usage(); exit(0); } - else if (!strcmp(argv[1], "-v") || - !strcmp(argv[1], "-version") || + else if (!strcmp(argv[1], "-v")) { + ++opts_v; + --argc; + ++argv; + } + else if (!strncmp(argv[1], "-vv", 3)) { + const char *av = argv[1]+1; + for (; *av; ++av) { + if (*av == 'v') + ++opts_v; + else { + usage(); + exit(1); + } + } + --argc; + ++argv; + } + else if (!strcmp(argv[1], "-version") || !strcmp(argv[1], "--version")) { version(); @@ -884,6 +956,18 @@ int main(int argc, char **argv) opts_disasm = true; noexec = true; } + else if (!strcmp(argv[1], "-disasm-func")) { + --argc; + ++argv; + if (argc <= 1) { + usage(); + exit(1); + } + vec_push(dis_list, argv[1]); + --argc; + ++argv; + noexec = true; + } else if (!strcmp(argv[1], "-printdefs")) { --argc; ++argv; @@ -998,6 +1082,17 @@ int main(int argc, char **argv) prog_delete(prog); return 0; } + for (i = 0; i < vec_size(dis_list); ++i) { + size_t k; + printf("Looking for `%s`\n", dis_list[i]); + for (k = 1; k < vec_size(prog->functions); ++k) { + const char *name = prog_getstring(prog, prog->functions[k].name); + if (!strcmp(name, dis_list[i])) { + prog_disasm_function(prog, k); + break; + } + } + } if (opts_disasm) { for (i = 1; i < vec_size(prog->functions); ++i) prog_disasm_function(prog, i); @@ -1030,9 +1125,32 @@ int main(int argc, char **argv) for (a = 0; a < prog->functions[i].nargs; ++a) { printf(" %i", prog->functions[i].argsize[a]); } - printf(") locals: %i + %i\n", - prog->functions[i].firstlocal, - prog->functions[i].locals); + if (opts_v > 1) { + int32_t start = prog->functions[i].entry; + if (start < 0) + printf(") builtin %i\n", (int)-start); + else { + size_t funsize = 0; + prog_section_statement *st = prog->code + start; + for (;st->opcode != INSTR_DONE; ++st) + ++funsize; + printf(") - %lu instructions", (unsigned long)funsize); + if (opts_v > 2) { + printf(" - locals: %i + %i\n", + prog->functions[i].firstlocal, + prog->functions[i].locals); + } + else + printf("\n"); + } + } + else if (opts_v) { + printf(") locals: %i + %i\n", + prog->functions[i].firstlocal, + prog->functions[i].locals); + } + else + printf(")\n"); } } if (!noexec) {