/** * cleanup the given element */ void tree_delete_node(Node *node) { // cleanup v_new v_free(node->key); v_detach(node->key); // cleanup v_new if (node->value) { v_free(node->value); v_detach(node->value); } // cleanup the node free(node); }
/** * free parameter table */ void slib_free_ptable(slib_par_t *ptable, int pcount) { #if defined(LNX_EXTLIB) || defined(WIN_EXTLIB) int i; for (i = 0; i < pcount; i++) { if (ptable[i].byref == 0) { v_free(ptable[i].var_p); v_detach(ptable[i].var_p); } } #endif }
char *System::loadResource(const char *fileName) { char *buffer = NULL; if (strstr(fileName, "://") != NULL) { String *cached = _cache.get(fileName); if (cached != NULL) { int len = cached->length(); buffer = (char *)malloc(len + 1); memcpy(buffer, cached->c_str(), len); buffer[len] = '\0'; } else { int handle = 1; var_t *var_p = v_new(); dev_file_t *f = dev_getfileptr(handle); _output->setStatus("Loading..."); _output->redraw(); if (dev_fopen(handle, fileName, 0)) { if (http_read(f, var_p) == 0) { systemPrint("\nfailed to read %s\n", fileName); } else { int len = var_p->v.p.length; buffer = (char *)malloc(len + 1); memcpy(buffer, var_p->v.p.ptr, len); buffer[len] = '\0'; _cache.add(fileName, buffer); } } else { systemPrint("\nfailed to open %s\n", fileName); } _output->setStatus(NULL); dev_fclose(handle); v_free(var_p); v_detach(var_p); opt_file_permitted = 0; } } if (buffer == NULL) { // remove failed item from history strlib::String *old = _history.peek(); if (old && old->equals(fileName)) { delete _history.pop(); } } return buffer; }
var_p_t hashmap_putv(var_p_t map, const var_p_t key) { // hashmap takes ownership of key if (key->type != V_STR) { // keys are always strings v_tostr(key); } Node *node = hashmap_search(map, key->v.p.ptr, key->v.p.length); if (node->key == NULL) { node->key = key; node->value = v_new(); map->v.m.count++; } else { // discard unused key v_free(key); v_detach(key); } return node->value; }
/** * build parameter table */ int slib_build_ptable(slib_par_t *ptable) { #if defined(LNX_EXTLIB) || defined(WIN_EXTLIB) int pcount = 0; var_t *arg = NULL; byte ready, code; bcip_t ofs; if (code_peek() == kwTYPE_LEVEL_BEGIN) { code_skipnext(); ready = 0; do { code = code_peek(); switch (code) { case kwTYPE_EOC: code_skipnext(); break; case kwTYPE_SEP: code_skipsep(); break; case kwTYPE_LEVEL_END: ready = 1; break; case kwTYPE_VAR: // variable ofs = prog_ip; if (code_isvar()) { // push parameter ptable[pcount].var_p = code_getvarptr(); ptable[pcount].byref = 1; pcount++; break; } // restore IP prog_ip = ofs; // no 'break' here default: // default --- expression (BYVAL ONLY) arg = v_new(); eval(arg); if (!prog_error) { // push parameter ptable[pcount].var_p = arg; ptable[pcount].byref = 0; pcount++; } else { v_free(arg); v_detach(arg); return pcount; } } } while (!ready); // kwTYPE_LEVEL_END code_skipnext(); } return pcount; #else return 0; #endif }
/** * execute a call to a unit */ int unit_exec(int lib_id, int index, var_t *ret) { unit_sym_t *us; // unit's symbol data bc_symbol_rec_t *ps; // program's symbol data int my_tid; stknode_t udf_rv; my_tid = ctask->tid; ps = &prog_symtable[index]; us = &(taskinfo(ps->task_id)->sbe.exec.exptable[ps->exp_idx]); switch (ps->type) { case stt_variable: break; case stt_procedure: exec_sync_variables(1); cmd_call_unit_udp(kwPROC, ps->task_id, us->address, INVALID_ADDR); activate_task(ps->task_id); if (prog_error) { gsb_last_error = prog_error; taskinfo(my_tid)->error = gsb_last_error; return 0; } bc_loop(2); if (prog_error) { gsb_last_error = prog_error; taskinfo(my_tid)->error = gsb_last_error; return 0; } activate_task(my_tid); exec_sync_variables(0); break; case stt_function: exec_sync_variables(1); cmd_call_unit_udp(kwFUNC, ps->task_id, us->address, us->vid); activate_task(ps->task_id); if (prog_error) { gsb_last_error = prog_error; taskinfo(my_tid)->error = gsb_last_error; return 0; } bc_loop(2); if (prog_error) { gsb_last_error = prog_error; taskinfo(my_tid)->error = gsb_last_error; return 0; } // get last variable from stack code_pop(&udf_rv, kwTYPE_RET); if (udf_rv.type != kwTYPE_RET) { err_stackmess(); } else { v_set(ret, udf_rv.x.vdvar.vptr); v_free(udf_rv.x.vdvar.vptr); // free ret-var v_detach(udf_rv.x.vdvar.vptr); } activate_task(my_tid); exec_sync_variables(0); break; }; return (prog_error == 0); }