void f_angle(void) { double dot, norma, normb; dot = dotprod((sp-1)->u.arr, sp->u.arr); if(dot <= (-INT_MAX + 2)) { pop_2_elems(); if(dot == -INT_MAX) error("angle: cannot calculate the angle between vectors of different sizes.\n"); else error("angle: invalid arg %d.\n", (dot + INT_MAX)); return; } norma = norm((sp-1)->u.arr); if(norma <= (-INT_MAX + 1)) { pop_2_elems(); error("angle: invalid argument 1.\n"); return; } normb = norm(sp->u.arr); if(normb <= (-INT_MAX + 1)) { pop_2_elems(); error("angle: invalid argument 2.\n"); return; } pop_2_elems(); push_real((double)acos( dot / (norma * normb) )); }
void f_async_db_exec(){ array_t *info; db_t *db; info = allocate_empty_array(1); info->item[0].type = T_STRING; info->item[0].subtype = STRING_MALLOC; info->item[0].u.string = string_copy((sp-1)->u.string, "f_db_exec"); valid_database("exec", info); db = find_db_conn((sp-1)->u.number); if (!db) { error("Attempt to exec on an invalid database handle\n"); } if (db->type->cleanup) { db->type->cleanup(&(db->c)); } function_to_call_t *cb = get_cb(); process_efun_callback(2, cb, F_ASYNC_READ); cb->f.fp->hdr.ref++; add_db_exec(db, (sp-1)->u.string, cb); pop_2_elems(); }
void f_async_getdir(){ function_to_call_t *cb = get_cb(); process_efun_callback(1, cb, F_ASYNC_READ); cb->f.fp->hdr.ref++; add_getdir(check_valid_path((sp-1)->u.string, current_object, "get_dir", 0), cb); pop_2_elems(); }
void f_pcre_extract(void) { pcre_t *run; array_t *ret; run = CALLOCATE(1, pcre_t, TAG_TEMPORARY, "f_pcre_extract : run"); assign_svalue_no_free(&run->pattern, sp); run->subject = (sp - 1)->u.string; run->s_length = SVALUE_STRLEN(sp - 1); run->ovector = NULL; run->ovecsize = 0; if(pcre_magic(run) < 0) { error("PCRE compilation failed at offset %d: %s\n", run->erroffset, run->error); pop_2_elems(); pcre_free_memory(run); return; } /* Pop the 2 arguments from the stack */ if (run->rc < 0) /* No match. could do handling of matching errors if wanted */ { pop_2_elems(); pcre_free_memory(run); push_refed_array(&the_null_array); return; } else if (run->rc > (run->ovecsize/3 - 1)) { pop_2_elems(); pcre_free_memory(run); error("Too many substrings.\n"); return; } ret = pcre_get_substrings(run); pop_2_elems(); push_refed_array(ret); pcre_free_memory(run); return; }
/* The (Euclidian) distance between two points */ void f_distance(void) { double total = vector_op((sp-1)->u.arr, sp->u.arr, distance_mult); if(total == -INT_MAX) { pop_2_elems(); error("distance: cannot take the distance of vectors of different sizes.\n"); return; } if((total == (-INT_MAX + 1)) || (total == (-INT_MAX + 2))) { pop_2_elems(); error("distance: invalid arg %d.\n", (total + INT_MAX)); return; } pop_2_elems(); push_real((double)sqrt(total)); }
void f_dotprod(void) { double total = vector_op((sp-1)->u.arr, sp->u.arr, dotprod_mult); if(total == -INT_MAX) { pop_2_elems(); error("dotprod: cannot take the dotprod of vectors of different sizes.\n"); return; } if((total == (-INT_MAX + 1)) || (total == (-INT_MAX + 2))) { pop_2_elems(); error("dotprod: invalid arg %d.\n", (total + INT_MAX)); return; } pop_2_elems(); push_real(total); }
void f_store_class_member() { int pos = ( sp - 1 )->u.number; array_t *arr; if( ( sp - 2 )->type != T_CLASS ) error( "Argument to store_class_member() not a class.\n" ); arr = ( sp - 2 )->u.arr; if( pos < 0 || pos >= arr->size ) error( "Class index out of bounds.\n" ); assign_svalue(&arr->item[pos], sp); pop_2_elems(); }
void f_socket_accept (void) { int port, fd; char addr[ADDR_BUF_SIZE]; if (!(sp->type & (T_STRING | T_FUNCTION))) { bad_arg(3, F_SOCKET_ACCEPT); } get_socket_address(fd = (sp-2)->u.number, addr, &port, 0); (sp-2)->u.number = VALID_SOCKET("accept") ? socket_accept(fd, (sp - 1), sp) : EESECURITY; pop_2_elems(); }
void c_multiply() { switch((sp-1)->type|sp->type) { case T_NUMBER: { sp--; sp->u.number *= (sp+1)->u.number; break; } case T_REAL: { sp--; sp->u.real *= (sp+1)->u.real; break; } case T_NUMBER|T_REAL: { if ((--sp)->type == T_NUMBER) { sp->type = T_REAL; sp->u.real = sp->u.number * (sp+1)->u.real; } else sp->u.real *= (sp+1)->u.number; break; } case T_MAPPING: { mapping_t *m; m = compose_mapping((sp-1)->u.map, sp->u.map, 1); pop_2_elems(); push_refed_mapping(m); break; } default: { if (!((sp-1)->type & (T_NUMBER|T_REAL|T_MAPPING))) bad_argument(sp-1, T_NUMBER|T_REAL|T_MAPPING,1, F_MULTIPLY); if (!(sp->type & (T_NUMBER|T_REAL|T_MAPPING))) bad_argument(sp, T_NUMBER|T_REAL|T_MAPPING,2, F_MULTIPLY); error("Args to * are not compatible.\n"); } } }
void c_sscanf(int num_arg) { svalue_t *fp; int i; /* * allocate stack frame for rvalues and return value (number of matches); * perform some stack manipulation; note: source and template strings are * already on the stack by this time */ fp = sp; CHECK_STACK_OVERFLOW(num_arg + 1); sp += num_arg + 1; *sp = *(fp--); /* move format description to top of stack */ *(sp - 1) = *(fp); /* move source string just below the format * desc. */ fp->type = T_NUMBER; /* this svalue isn't invalidated below, and * if we don't change it to something safe, * it will get freed twice if an error occurs */ /* * prep area for rvalues */ for (i = 1; i <= num_arg; i++) fp[i].type = T_INVALID; /* * do it... */ i = inter_sscanf(sp - 2, sp - 1, sp, num_arg); /* * remove source & template strings from top of stack */ pop_2_elems(); /* * save number of matches on stack */ fp->type = T_NUMBER; fp->u.number = i; }
void f_pcre_assoc(void) { svalue_t *arg; array_t *vec; arg = sp - st_num_arg + 1; if ((arg + 2)->type != T_ARRAY) error("Bad argument 3 to pcre_assoc()\n"); vec = pcre_assoc(arg, (arg+1)->u.arr, (arg+2)->u.arr, st_num_arg > 3 ? (arg+3) : &const0); if (st_num_arg == 4) pop_3_elems(); else pop_2_elems(); free_string_svalue(sp); sp->type = T_ARRAY; sp->u.arr = vec; }
void f_addn_temp () { int i, j; object_t *ob; unsigned short type; mapping_t *map; svalue_t *value; char *src, *dst; char *tmpstr; if( st_num_arg == 3 ) { ob = sp->u.ob; pop_stack(); } else ob = current_object; i = find_global_variable(ob->prog, "tmp_dbase", &type, 0); if (i == -1) { pop_2_elems(); error("(addn_temp) %s 物件未宣告全域映射资料库变数。\n", ob->obname); } value = &ob->variables[i]; if( value->type != T_MAPPING ) { pop_2_elems(); error("(addn_temp) %s 物件的资料库变数型态错误。\n", ob->obname); } map = value->u.map; src = (char *)(sp-1)->u.string; dst = tmpstr = (char *)DMALLOC(SVALUE_STRLEN(sp-1) + 1, TAG_STRING, "addn_temp"); j=0; while (*src) { i=0; if( ++j > 20 ) { pop_2_elems(); error("(addn_temp) %s too deep mapping(20)。\n", ob->obname); } while (*src != '/' && *src) { *(dst+i) = *src++; i++; } if (*src == '/') { while (*++src == '/'); if(!i) continue; } *(dst+i) = '\0'; value = find_string_in_mapping(map, tmpstr); if(!*src) { if( value == &const0u || value->type != T_NUMBER ) { value = insert_in_mapping(map, dst); *value = *sp--; } else value->u.number += (sp--)->u.number; break; } if(value == &const0u || value->type != T_MAPPING) { value = insert_in_mapping(map, dst); value->type = T_MAPPING; value->u.map = allocate_mapping(0); } map = value->u.map; dst = tmpstr; } FREE(tmpstr); free_string_svalue(sp--); push_svalue(value); }
void f_pcre_replace(void) { pcre_t *run; array_t *replacements; unsigned int i; char *ret; run = CALLOCATE(1, pcre_t, TAG_TEMPORARY, "f_pcre_replace: run"); run->ovector = NULL; run->ovecsize = 0; assign_svalue_no_free(&run->pattern, (sp - 1)); run->subject = (sp - 2)->u.string; replacements = sp->u.arr; run->s_length = SVALUE_STRLEN(sp - 2); if(pcre_magic(run) < 0) { pcre_free_memory(run); error("PCRE compilation failed at offset %d: %s\n", run->erroffset, run->error); } if (run->rc < 0) /* No match. could do handling of matching errors if wanted */ { pcre_free_memory(run); pop_2_elems(); return; } if (run->rc > (run->ovecsize/3-1)) { pcre_free_memory(run); error("Too many substrings.\n"); } if ( (run->rc - 1) != replacements->size ) { int tmp = run->rc-1; pcre_free_memory(run); error("Number of captured substrings and replacements do not match, " "%d vs %d.\n", tmp, replacements->size); } if (run->rc == 1) { /* No captured substrings, return subject */ pcre_free_memory(run); pop_2_elems(); return; //push_malloced_string(run->subject); } ret = pcre_get_replace(run, replacements); pop_3_elems(); push_malloced_string(ret); pcre_free_memory(run); return; }