PRIVATE int cmd_load(struct comal_line *line) { char *fn; if (!line->lc.str && !curenv->name) run_error(CMD_ERR, "Missing program name (to LOAD)"); else if (check_changed()) { if (line->lc.str) fn = line->lc.str->s; else { fn = curenv->name; my_printf(MSG_DIALOG, 1, fn); } fn = my_strdup(MISC_POOL, fn); prog_load(fn); curenv->name = fn; prog_structure_scan(); mem_freepool(PARSE_POOL); longjmp(RESTART, JUST_RESTART); } return 0; }
void prog_load(Prog* prog, const char* cmdpipe, const char* filename) { int bufsize = BUF_EXT; char* buf = malloc((size_t)bufsize); MFP* fp; char* s; int lineno = 1; char newname [1024]; char* temp; char* myfilename; assert(prog != NULL); assert(filename != NULL); assert(buf != NULL); assert(filename != NULL); if (cmdpipe == NULL) myfilename = strdup(filename); else { myfilename = malloc(strlen(filename) + strlen(cmdpipe) + 1024); sprintf(&myfilename[1], cmdpipe, filename); myfilename[0] = '#'; } if (NULL == (fp = mio_open(myfilename, ".zpl"))) zpl_exit(EXIT_FAILURE); if (verbose) printf("Reading %s\n", myfilename); while((s = get_line(&buf, &bufsize, fp, &lineno)) != NULL) { assert(!isspace(*s)); /* This could happen if we have a ;; somewhere. */ if (*s == '\0') continue; if (1 == sscanf(s, "include \"%1023[^\"]\"", newname)) { temp = malloc(strlen(filename) + strlen(newname) + 2); prog_load(prog, cmdpipe, make_pathname(temp, filename, newname)); free(temp); } else { add_stmt(prog, filename, lineno, s); } } mio_close(fp); free(myfilename); free(buf); }
int create_filtered_socket_fd(struct bpf_insn *insns, size_t insns_count) { int progfd = prog_load(insns, insns_count); // hook eBPF program up to a socket // sendmsg() to the socket will trigger the filter // returning 0 in the filter should toss the packet int socks[2]; if (socketpair(AF_UNIX, SOCK_DGRAM, 0, socks)) err(1, "socketpair"); if (setsockopt(socks[0], SOL_SOCKET, SO_ATTACH_BPF, &progfd, sizeof(int))) err(1, "setsockopt"); return socks[1]; }
static int attach_filter(int cg_fd, int type, int verdict) { int prog_fd, map_fd, ret, key; long long pkt_cnt, byte_cnt; map_fd = bpf_create_map(BPF_MAP_TYPE_ARRAY, sizeof(key), sizeof(byte_cnt), 256, 0); if (map_fd < 0) { printf("Failed to create map: '%s'\n", strerror(errno)); return EXIT_FAILURE; } prog_fd = prog_load(map_fd, verdict); printf("Output from kernel verifier:\n%s\n-------\n", bpf_log_buf); if (prog_fd < 0) { printf("Failed to load prog: '%s'\n", strerror(errno)); return EXIT_FAILURE; } ret = bpf_prog_attach(prog_fd, cg_fd, type); if (ret < 0) { printf("Failed to attach prog to cgroup: '%s'\n", strerror(errno)); return EXIT_FAILURE; } while (1) { key = MAP_KEY_PACKETS; assert(bpf_lookup_elem(map_fd, &key, &pkt_cnt) == 0); key = MAP_KEY_BYTES; assert(bpf_lookup_elem(map_fd, &key, &byte_cnt) == 0); printf("cgroup received %lld packets, %lld bytes\n", pkt_cnt, byte_cnt); sleep(1); } return EXIT_SUCCESS; }
static int test_foo_bar(void) { int drop_prog, allow_prog, foo = 0, bar = 0, rc = 0; allow_prog = prog_load(1); if (!allow_prog) goto err; drop_prog = prog_load(0); if (!drop_prog) goto err; if (setup_cgroup_environment()) goto err; /* Create cgroup /foo, get fd, and join it */ foo = create_and_get_cgroup(FOO); if (foo < 0) goto err; if (join_cgroup(FOO)) goto err; if (bpf_prog_attach(drop_prog, foo, BPF_CGROUP_INET_EGRESS, BPF_F_ALLOW_OVERRIDE)) { log_err("Attaching prog to /foo"); goto err; } printf("Attached DROP prog. This ping in cgroup /foo should fail...\n"); assert(system(PING_CMD) != 0); /* Create cgroup /foo/bar, get fd, and join it */ bar = create_and_get_cgroup(BAR); if (bar < 0) goto err; if (join_cgroup(BAR)) goto err; printf("Attached DROP prog. This ping in cgroup /foo/bar should fail...\n"); assert(system(PING_CMD) != 0); if (bpf_prog_attach(allow_prog, bar, BPF_CGROUP_INET_EGRESS, BPF_F_ALLOW_OVERRIDE)) { log_err("Attaching prog to /foo/bar"); goto err; } printf("Attached PASS prog. This ping in cgroup /foo/bar should pass...\n"); assert(system(PING_CMD) == 0); if (bpf_prog_detach(bar, BPF_CGROUP_INET_EGRESS)) { log_err("Detaching program from /foo/bar"); goto err; } printf("Detached PASS from /foo/bar while DROP is attached to /foo.\n" "This ping in cgroup /foo/bar should fail...\n"); assert(system(PING_CMD) != 0); if (bpf_prog_attach(allow_prog, bar, BPF_CGROUP_INET_EGRESS, BPF_F_ALLOW_OVERRIDE)) { log_err("Attaching prog to /foo/bar"); goto err; } if (bpf_prog_detach(foo, BPF_CGROUP_INET_EGRESS)) { log_err("Detaching program from /foo"); goto err; } printf("Attached PASS from /foo/bar and detached DROP from /foo.\n" "This ping in cgroup /foo/bar should pass...\n"); assert(system(PING_CMD) == 0); if (bpf_prog_attach(allow_prog, bar, BPF_CGROUP_INET_EGRESS, BPF_F_ALLOW_OVERRIDE)) { log_err("Attaching prog to /foo/bar"); goto err; } if (!bpf_prog_attach(allow_prog, bar, BPF_CGROUP_INET_EGRESS, 0)) { errno = 0; log_err("Unexpected success attaching prog to /foo/bar"); goto err; } if (bpf_prog_detach(bar, BPF_CGROUP_INET_EGRESS)) { log_err("Detaching program from /foo/bar"); goto err; } if (!bpf_prog_detach(foo, BPF_CGROUP_INET_EGRESS)) { errno = 0; log_err("Unexpected success in double detach from /foo"); goto err; } if (bpf_prog_attach(allow_prog, foo, BPF_CGROUP_INET_EGRESS, 0)) { log_err("Attaching non-overridable prog to /foo"); goto err; } if (!bpf_prog_attach(allow_prog, bar, BPF_CGROUP_INET_EGRESS, 0)) { errno = 0; log_err("Unexpected success attaching non-overridable prog to /foo/bar"); goto err; } if (!bpf_prog_attach(allow_prog, bar, BPF_CGROUP_INET_EGRESS, BPF_F_ALLOW_OVERRIDE)) { errno = 0; log_err("Unexpected success attaching overridable prog to /foo/bar"); goto err; } if (!bpf_prog_attach(allow_prog, foo, BPF_CGROUP_INET_EGRESS, BPF_F_ALLOW_OVERRIDE)) { errno = 0; log_err("Unexpected success attaching overridable prog to /foo"); goto err; } if (bpf_prog_attach(drop_prog, foo, BPF_CGROUP_INET_EGRESS, 0)) { log_err("Attaching different non-overridable prog to /foo"); goto err; } goto out; err: rc = 1; out: close(foo); close(bar); cleanup_cgroup_environment(); if (!rc) printf("### override:PASS\n"); else printf("### override:FAIL\n"); return rc; }
Bool zpl_read_with_args(char** argv, int argc, Bool with_management, void* user_data) { const char* options = "D:mP:sv:"; unsigned long seed = 13021967UL; char** param_table; int param_count = 0; int c; int i; Prog* prog = NULL; Set* set; void* lp = NULL; Bool ret = FALSE; char* inppipe = NULL; Bool use_startval = FALSE; stkchk_init(); yydebug = 0; yy_flex_debug = 0; param_table = malloc(sizeof(*param_table)); zpl_print_banner(stdout, FALSE); /* getopt might be called more than once */ optind = 1; while((c = getopt(argc, argv, options)) != -1) { switch(c) { case 'D' : param_table = realloc(param_table, ((unsigned int)param_count + 1) * sizeof(*param_table)); param_table[param_count] = strdup(optarg); if (verbose >= VERB_DEBUG) printf("Parameter %d [%s]\n", param_count, param_table[param_count]); param_count++; break; case 'm' : use_startval = TRUE; break; case 'P' : inppipe = strdup(optarg); break; case 's' : seed = (unsigned long)atol(optarg); break; case 'v' : verbose = atoi(optarg); break; case '?': fprintf(stderr, "Unknown option '%c'\n", c); return FALSE; default : abort(); } } if ((argc - optind) < 1) { fprintf(stderr, "Filename missing\n"); free(param_table); return FALSE; } blk_init(); str_init(); rand_init(seed); numb_init(with_management); elem_init(); set_init(); mio_init(); interns_init(); local_init(); if (0 == setjmp( zpl_read_env)) { is_longjmp_ok = TRUE; /* Make symbol to hold entries of internal variables */ set = set_pseudo_new(); (void)symbol_new(SYMBOL_NAME_INTERNAL, SYM_VAR, set, 100, NULL); set_free(set); /* Now store the param defines */ for(i = 0; i < param_count; i++) zpl_add_parameter(param_table[i]); prog = prog_new(); for(i = optind; i < argc; i++) prog_load(prog, inppipe, argv[i]); if (prog_is_empty(prog)) fprintf(stderr, "*** Error 168: No program statements to execute\n"); else { if (verbose >= VERB_DEBUG) prog_print(stderr, prog); lp = xlp_alloc(argv[optind], use_startval, user_data); prog_execute(prog, lp); ret = TRUE; } } is_longjmp_ok = FALSE; if (lp != NULL) xlp_free(lp); /* Now clean up. */ if (inppipe != NULL) free(inppipe); for(i = 0; i < param_count; i++) free(param_table[i]); free(param_table); if (prog != NULL) prog_free(prog); local_exit(); interns_exit(); mio_exit(); symbol_exit(); define_exit(); set_exit(); elem_exit(); numb_exit(); str_exit(); blk_exit(); return ret; }
Bool zpl_read(const char* filename, Bool with_management, void* user_data) { Prog* prog = NULL; Set* set; void* lp = NULL; Bool ret = FALSE; stkchk_init(); yydebug = 0; yy_flex_debug = 0; zpl_print_banner(stdout, FALSE); blk_init(); str_init(); rand_init(13021967UL); numb_init(with_management); elem_init(); set_init(); mio_init(); interns_init(); local_init(); if (0 == setjmp(zpl_read_env)) { is_longjmp_ok = TRUE; set = set_pseudo_new(); (void)symbol_new(SYMBOL_NAME_INTERNAL, SYM_VAR, set, 100, NULL); set_free(set); prog = prog_new(); prog_load(prog, NULL, filename); if (prog_is_empty(prog)) fprintf(stderr, "*** Error 168: No program statements to execute\n"); else { if (verbose >= VERB_DEBUG) prog_print(stderr, prog); lp = xlp_alloc(filename, FALSE, user_data); prog_execute(prog, lp); ret = TRUE; } } is_longjmp_ok = FALSE; if (lp != NULL) xlp_free(lp); if (prog != NULL) prog_free(prog); local_exit(); interns_exit(); mio_exit(); symbol_exit(); define_exit(); set_exit(); elem_exit(); numb_exit(); str_exit(); blk_exit(); return ret; }
int main(int argc, char **argv) { size_t i; qcint_t fnmain = -1; qc_program_t *prog; size_t xflags = VMXF_DEFAULT; bool opts_printfields = false; bool opts_printdefs = false; bool opts_printfuns = false; bool opts_disasm = false; bool opts_info = false; bool noexec = false; const char *progsfile = nullptr; const char **dis_list = nullptr; int opts_v = 0; arg0 = argv[0]; if (argc < 2) { usage(); exit(EXIT_FAILURE); } while (argc > 1) { if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "-help") || !strcmp(argv[1], "--help")) { usage(); exit(EXIT_SUCCESS); } 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(EXIT_FAILURE); } } --argc; ++argv; } else if (!strcmp(argv[1], "-version") || !strcmp(argv[1], "--version")) { version(); exit(EXIT_SUCCESS); } else 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; noexec = true; } else if (!strcmp(argv[1], "-disasm")) { --argc; ++argv; opts_disasm = true; noexec = true; } else if (!strcmp(argv[1], "-disasm-func")) { --argc; ++argv; if (argc <= 1) { usage(); exit(EXIT_FAILURE); } vec_push(dis_list, argv[1]); --argc; ++argv; 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") || !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; else p.vtype = TYPE_VOID; --argc; ++argv; if (argc < 2) { usage(); exit(EXIT_FAILURE); } 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) { fprintf(stderr, "only 1 program file may be specified\n"); usage(); exit(EXIT_FAILURE); } progsfile = argv[1]; --argc; ++argv; } else { fprintf(stderr, "unknown parameter: %s\n", argv[1]); usage(); exit(EXIT_FAILURE); } } if (argc == 2 && !progsfile) { progsfile = argv[1]; --argc; ++argv; } if (!progsfile) { fprintf(stderr, "must specify a program to execute\n"); usage(); exit(EXIT_FAILURE); } prog = prog_load(progsfile, noexec); if (!prog) { fprintf(stderr, "failed to load program '%s'\n", progsfile); exit(EXIT_FAILURE); } prog->builtins = qc_builtins; prog->builtins_count = GMQCC_ARRAY_COUNT(qc_builtins); if (opts_info) { printf("Program's system-checksum = 0x%04x\n", (unsigned int)prog->crc16); printf("Entity field space: %u\n", (unsigned int)prog->entityfields); printf("Globals: %zu\n", prog->globals.size()); printf("Counts:\n" " code: %zu\n" " defs: %zu\n" " fields: %zu\n" " functions: %zu\n" " strings: %zu\n", prog->code.size(), prog->defs.size(), prog->fields.size(), prog->functions.size(), prog->strings.size()); } if (opts_info) { 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 < prog->functions.size(); ++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 < prog->functions.size(); ++i) prog_disasm_function(prog, i); return 0; } if (opts_printdefs) { const char *getstring = nullptr; for (auto &it : prog->defs) { printf("Global: %8s %-16s at %u%s", type_name[it.type & DEF_TYPEMASK], prog_getstring(prog, it.name), (unsigned int)it.offset, ((it.type & DEF_SAVEGLOBAL) ? " [SAVE]" : "")); if (opts_v) { switch (it.type & DEF_TYPEMASK) { case TYPE_FLOAT: printf(" [init: %g]", ((qcany_t*)(&prog->globals[0] + it.offset))->_float); break; case TYPE_INTEGER: printf(" [init: %i]", (int)( ((qcany_t*)(&prog->globals[0] + it.offset))->_int )); break; case TYPE_ENTITY: case TYPE_FUNCTION: case TYPE_FIELD: case TYPE_POINTER: printf(" [init: %u]", (unsigned)( ((qcany_t*)(&prog->globals[0] + it.offset))->_int )); break; case TYPE_STRING: getstring = prog_getstring(prog, ((qcany_t*)(&prog->globals[0] + it.offset))->string); printf(" [init: `"); print_escaped_string(getstring, strlen(getstring)); printf("`]\n"); break; default: break; } } printf("\n"); } } if (opts_printfields) { for (auto &it : prog->fields) { printf("Field: %8s %-16s at %d%s\n", type_name[it.type], prog_getstring(prog, it.name), it.offset, ((it.type & DEF_SAVEGLOBAL) ? " [SAVE]" : "")); } } if (opts_printfuns) { for (auto &it : prog->functions) { int32_t a; printf("Function: %-16s taking %u parameters:(", prog_getstring(prog, it.name), (unsigned int)it.nargs); for (a = 0; a < it.nargs; ++a) { printf(" %i", it.argsize[a]); } if (opts_v > 1) { int32_t start = it.entry; if (start < 0) printf(") builtin %i\n", (int)-start); else { size_t funsize = 0; prog_section_statement_t *st = &prog->code[0] + start; for (;st->opcode != INSTR_DONE; ++st) ++funsize; printf(") - %zu instructions", funsize); if (opts_v > 2) { printf(" - locals: %i + %i\n", it.firstlocal, it.locals); } else printf("\n"); } } else if (opts_v) { printf(") locals: %i + %i\n", it.firstlocal, it.locals); } else printf(")\n"); } } if (!noexec) { for (i = 1; i < prog->functions.size(); ++i) { const char *name = prog_getstring(prog, prog->functions[i].name); if (!strcmp(name, "main")) fnmain = (qcint_t)i; } if (fnmain > 0) { prog_main_setparams(prog); prog_exec(prog, &prog->functions[fnmain], xflags, VM_JUMPS_DEFAULT); } else fprintf(stderr, "No main function found\n"); } prog_delete(prog); return 0; }
int main(int argc, char* const* argv) { Prog* prog; Set* set; void* lp; const char* extension = ""; char* filter = strdup("%s"); char* outfile; char* tblfile; char* ordfile; char* mstfile; char* basefile = NULL; char* inppipe = NULL; char* outpipe; LpFormat format = LP_FORM_LPF; FILE* fp; Bool write_order = FALSE; Bool write_mst = FALSE; Bool presolve = FALSE; int name_length = 0; char* prog_text; unsigned long seed = 13021967UL; char** param_table; int param_count = 0; int c; int i; FILE* (*openfile)(const char*, const char*) = fopen; int (*closefile)(FILE*) = fclose; stkchk_init(); yydebug = 0; yy_flex_debug = 0; verbose = VERB_NORMAL; param_table = malloc(sizeof(*param_table)); while((c = getopt(argc, argv, options)) != -1) { switch(c) { case 'b' : yydebug = 1; break; case 'D' : param_table = realloc(param_table, ((unsigned int)param_count + 1) * sizeof(*param_table)); param_table[param_count] = strdup(optarg); param_count++; break; case 'h' : zpl_print_banner(stdout, TRUE); printf(usage, argv[0]); puts(help); exit(0); case 'f' : yy_flex_debug = 1; break; case 'F' : free(filter); filter = strdup(optarg); openfile = popen; closefile = pclose; break; case 'l' : name_length = atoi(optarg); break; case 'm' : write_mst = TRUE; break; case 'n' : if (*optarg != 'c') { fprintf(stderr, usage, argv[0]); exit(0); } switch(optarg[1]) { case 'm' : conname_format(CON_FORM_MAKE); break; case 'n' : conname_format(CON_FORM_NAME); break; case 'f' : conname_format(CON_FORM_FULL); break; default : fprintf(stderr, usage, argv[0]); exit(0); } break; case 'o' : basefile = strdup(optarg); break; case 'O' : presolve = TRUE; break; case 'P' : inppipe = strdup(optarg); break; case 's' : seed = (unsigned long)atol(optarg); break; case 'r' : write_order = TRUE; break; case 't' : switch(tolower(*optarg)) { case 'h' : format = LP_FORM_HUM; break; case 'm' : format = LP_FORM_MPS; break; case 'l' : format = LP_FORM_LPF; break; case 'p' : format = LP_FORM_PIP; break; case 'r' : format = LP_FORM_RLP; break; default : if (verbose > VERB_QUIET) fprintf(stderr, "--- Warning 103: Output format \"%s\" not supported, using LP format\n", optarg); format = LP_FORM_LPF; break; } break; case 'v' : verbose = atoi(optarg); break; case 'V' : printf("%s\n", VERSION); exit(0); case '?': fprintf(stderr, usage, argv[0]); exit(0); default : abort(); } } if ((argc - optind) < 1) { fprintf(stderr, usage, argv[0]); exit(0); } zpl_print_banner(stdout, TRUE); if (basefile == NULL) basefile = strip_extension(strdup(strip_path(argv[optind]))); switch(format) { case LP_FORM_LPF : extension = ".lp"; break; case LP_FORM_MPS : extension = ".mps"; break; case LP_FORM_HUM : extension = ".hum"; break; case LP_FORM_RLP : extension = ".rlp"; break; case LP_FORM_PIP : extension = ".pip"; break; default : abort(); } assert(extension != NULL); outfile = add_extention(basefile, extension); tblfile = add_extention(basefile, ".tbl"); ordfile = add_extention(basefile, ".ord"); mstfile = add_extention(basefile, ".mst"); outpipe = malloc(strlen(basefile) + strlen(filter) + 256); assert(outpipe != NULL); blk_init(); str_init(); rand_init(seed); numb_init(TRUE); elem_init(); set_init(); mio_init(); interns_init(); local_init(); /* Make symbol to hold entries of internal variables */ set = set_pseudo_new(); (void)symbol_new(SYMBOL_NAME_INTERNAL, SYM_VAR, set, 100, NULL); set_free(set); /* Now store the param defines */ for(i = 0; i < param_count; i++) zpl_add_parameter(param_table[i]); /* Next we read in the zpl program(s) */ prog = prog_new(); for(i = optind; i < argc; i++) prog_load(prog, inppipe, argv[i]); if (prog_is_empty(prog)) { fprintf(stderr, "*** Error 168: No program statements to execute\n"); exit(EXIT_FAILURE); } if (verbose >= VERB_DEBUG) prog_print(stderr, prog); lp = xlp_alloc(argv[optind], write_mst || write_order, NULL); zlp_setnamelen(lp, name_length); prog_execute(prog, lp); /* Presolve */ if (presolve) fprintf(stderr, "--- Warning: Presolve no longer support. If you need it, send me an email\n"); #if 0 if (!zlp_presolve()) exit(EXIT_SUCCESS); #endif if (verbose >= VERB_NORMAL) zlp_stat(lp); /* Write order file */ if (write_order) { sprintf(outpipe, filter, ordfile, "ord"); if (verbose >= VERB_NORMAL) printf("Writing [%s]\n", outpipe); if (NULL == (fp = (*openfile)(outpipe, "w"))) { fprintf(stderr, "*** Error 104: File open failed "); perror(ordfile); exit(EXIT_FAILURE); } zlp_orderfile(lp, fp, format); check_write_ok(fp, ordfile); (void)(*closefile)(fp); } /* Write MST file */ if (write_mst) { sprintf(outpipe, filter, mstfile, "mst"); if (verbose >= VERB_NORMAL) printf("Writing [%s]\n", outpipe); if (NULL == (fp = (*openfile)(outpipe, "w"))) { fprintf(stderr, "*** Error 104: File open failed "); perror(mstfile); exit(EXIT_FAILURE); } zlp_mstfile(lp, fp, format); check_write_ok(fp, mstfile); (void)(*closefile)(fp); } /* Write Output */ sprintf(outpipe, filter, outfile, "lp"); if (verbose >= VERB_NORMAL) printf("Writing [%s]\n", outpipe); if (NULL == (fp = (*openfile)(outpipe, "w"))) { fprintf(stderr, "*** Error 104: File open failed "); perror(outfile); exit(EXIT_FAILURE); } if (format != LP_FORM_RLP) prog_text = prog_tostr(prog, format == LP_FORM_MPS ? "* " : "\\ ", title, 128); else { prog_text = malloc(strlen(title) + 4); assert(prog_text != NULL); sprintf(prog_text, "\\%s\n", title); } zlp_write(lp, fp, format, prog_text); check_write_ok(fp, outfile); (void)(*closefile)(fp); /* We do not need the translation table for human readable format * Has to be written after the LP file, so the scaling has been done. */ if (format != LP_FORM_HUM) { /* Write translation table */ sprintf(outpipe, filter, tblfile, "tbl"); if (verbose >= VERB_NORMAL) printf("Writing [%s]\n", outpipe); if (NULL == (fp = (*openfile)(outpipe, "w"))) { fprintf(stderr, "*** Error 104: File open failed"); perror(tblfile); exit(EXIT_FAILURE); } zlp_transtable(lp, fp, format); check_write_ok(fp, tblfile); (void)(*closefile)(fp); } free(prog_text); if (verbose >= VERB_DEBUG) symbol_print_all(stderr); #if defined(__INSURE__) || !defined(NDEBUG) || defined(FREEMEM) /* Now clean up. */ if (inppipe != NULL) free(inppipe); for(i = 0; i < param_count; i++) free(param_table[i]); free(param_table); prog_free(prog); local_exit(); interns_exit(); xlp_free(lp); mio_exit(); symbol_exit(); define_exit(); set_exit(); elem_exit(); numb_exit(); str_exit(); blk_exit(); free(mstfile); free(ordfile); free(outfile); free(tblfile); free(basefile); free(filter); free(outpipe); if (verbose >= VERB_NORMAL) { mem_display(stdout); stkchk_maximum(stdout); } #endif /* __INSURE__ || !NDEBUG || FREEMEM */ return 0; }
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_printfuns = false; bool opts_disasm = false; bool opts_info = false; bool noexec = false; const char *progsfile = NULL; arg0 = argv[0]; if (argc < 2) { usage(); exit(1); } 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; } else if (!strcmp(argv[1], "-profile")) { --argc; ++argv; xflags |= VMXF_PROFILE; } else if (!strcmp(argv[1], "-info")) { --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") || !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(); 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(progsfile); if (!prog) { printf("failed to load program '%s'\n", progsfile); exit(1); } prog->builtins = qc_builtins; prog->builtins_count = qc_builtins_count; if (opts_info) { printf("Program's system-checksum = 0x%04x\n", (unsigned int)prog->crc16); printf("Entity field space: %u\n", (unsigned int)prog->entityfields); printf("Globals: %u\n", (unsigned int)vec_size(prog->globals)); } if (opts_info) { prog_delete(prog); return 0; } if (opts_disasm) { for (i = 1; i < vec_size(prog->functions); ++i) prog_disasm_function(prog, i); return 0; } if (opts_printdefs) { for (i = 0; i < vec_size(prog->defs); ++i) { 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, ((prog->defs[i].type & DEF_SAVEGLOBAL) ? " [SAVE]" : "")); } } if (opts_printfields) { for (i = 0; i < vec_size(prog->fields); ++i) { 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, ((prog->fields[i].type & DEF_SAVEGLOBAL) ? " [SAVE]" : "")); } } if (opts_printfuns) { for (i = 0; i < vec_size(prog->functions); ++i) { int32_t a; printf("Function: %-16s taking %i parameters:(", prog_getstring(prog, prog->functions[i].name), (unsigned int)prog->functions[i].nargs); 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 (!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); prog_exec(prog, &prog->functions[fnmain], xflags, VM_JUMPS_DEFAULT); } else printf("No main function found\n"); } prog_delete(prog); return 0; }