void handle_read(struct request *req, int val){ aiob *aio = req->aio; close(aio->aio_fildes); if(val){ FREE(aio->aio_buf); push_number(val); set_eval(max_cost); safe_call_efun_callback(req->fun, 1); return; } val = aio_return(aio); if(val < 0){ FREE(aio->aio_buf); push_number(val); set_eval(max_cost); safe_call_efun_callback(req->fun, 1); return; } char *file = new_string(val, "read_file_async: str"); memcpy(file, (char *)(aio->aio_buf), val); file[val]=0; push_malloced_string(file); FREE(aio->aio_buf); set_eval(max_cost); safe_call_efun_callback(req->fun, 1); }
static void bmod(void) { struct number *a, *b, *r; BN_CTX *ctx; u_int scale; a = pop_number(); if (a == NULL) return; b = pop_number(); if (b == NULL) { push_number(a); return; } r = new_number(); scale = max(a->scale, b->scale); r->scale = scale; if (BN_is_zero(a->number)) warnx("remainder by zero"); else { normalize(a, scale); normalize(b, scale); ctx = BN_CTX_new(); bn_checkp(ctx); bn_check(BN_mod(r->number, b->number, a->number, ctx)); BN_CTX_free(ctx); } push_number(r); free_number(a); free_number(b); }
void eval(stack **n_stack, stack **o_stack, double *x, double *y){ //Using easier names char op=top_operator(*o_stack); double n1, n2; //Checking the different cases for the top of the stack if(op=='='){ pop_operator(&(*o_stack)); if(pop_operator(&(*o_stack))=='x') *x=top_number(*n_stack); else *y=top_number(*n_stack); } else if(op=='x'){ pop_operator(&(*o_stack)); push_number(*x, &(*n_stack)); } else if(op=='y'){ pop_operator(&(*o_stack)); push_number(*y, &(*n_stack)); } else{//Push the computed result into the n_stack n1=pop_number(&(*n_stack)); n2=pop_number(&(*n_stack)); op=pop_operator(&(*o_stack)); push_number(compute(n1, op, n2), &(*n_stack)); } }
static void bsub(void) { struct number *a, *b, *r; a = pop_number(); if (a == NULL) return; b = pop_number(); if (b == NULL) { push_number(a); return; } r = new_number(); r->scale = max(a->scale, b->scale); if (r->scale > a->scale) normalize(a, r->scale); else if (r->scale > b->scale) normalize(b, r->scale); bn_check(BN_sub(r->number, b->number, a->number)); push_number(r); free_number(a); free_number(b); }
void f_bson_buf_find(void){ int size; bson b[1]; bson sub; svalue_t v; bson_iterator it; size = (sp-1)->u.buf->size; bson_init_empty(b); bson_init_size( b, size ); memcpy(b->data, (sp-1)->u.buf->item, size); b->finished = 1; /* buff不合法 */ if(bson_size(b) != size){ pop_n_elems(st_num_arg); push_number(0); goto free_bson; } /* 找不到数据 */ if(!bson_find( &it, b, sp->u.string )){ pop_n_elems(st_num_arg); push_number(0); goto free_bson; } bson_to_v(&it, &v); free_buffer((sp-1)->u.buf); pop_stack(); *sp = v; free_bson: bson_destroy( b ); }
static void efun_cat_file(struct svalue *fp) { extern int read_file_len; char *str; if (fp[0].type != T_STRING || fp[1].type != T_NUMBER || fp[2].type != T_NUMBER) { push_number(0); return; } str = read_file(fp[0].u.string, fp[1].u.number, fp[2].u.number); if (str) { push_mstring(str); if (command_giver) (void)apply("catch_tell", command_giver, 1, 0); else (void)apply("catch_tell", current_interactive, 1, 0); push_number(read_file_len); } else push_number(0); }
static void efun_atoi(struct svalue *fp) { if (fp->type == T_STRING) push_number(atoi(fp->u.string)); else push_number(0); }
static void bdivmod(void) { struct number *a, *b, *frac, *quotient, *rdiv, *remainder; BN_CTX *ctx; u_int scale; a = pop_number(); if (a == NULL) return; b = pop_number(); if (b == NULL) { push_number(a); return; } rdiv = new_number(); quotient = new_number(); remainder = new_number(); scale = max(a->scale, b->scale); rdiv->scale = 0; remainder->scale = scale; quotient->scale = bmachine.scale; scale = max(a->scale, b->scale); if (BN_is_zero(a->number)) warnx("divide by zero"); else { normalize(a, scale); normalize(b, scale); ctx = BN_CTX_new(); bn_checkp(ctx); /* * Unlike other languages' divmod operations, dc is specified * to return the remainder and the full quotient, rather than * the remainder and the floored quotient. bn(3) has no * function to calculate both. So we'll use BN_div to get the * remainder and floored quotient, then calculate the full * quotient from those. * * quotient = rdiv + remainder / divisor */ bn_check(BN_div(rdiv->number, remainder->number, b->number, a->number, ctx)); frac = div_number(remainder, a, bmachine.scale); normalize(rdiv, bmachine.scale); normalize(remainder, scale); bn_check(BN_add(quotient->number, rdiv->number, frac->number)); free_number(frac); BN_CTX_free(ctx); } push_number(quotient); push_number(remainder); free_number(rdiv); free_number(a); free_number(b); }
static void test(struct hash *h) { push_number(h, "a" , 1.0); push_string(h, "b" , "hello world"); push_nil(h, "c"); int i; char buffer[10]; for (i=0;i<100;i++) { sprintf(buffer,"%d",i*2); push_number(h,buffer,i); } debug_table(h); hash_genpool(h); }
static void load_array(void) { int reg; struct number *inumber, *n; u_long index; struct stack *stack; struct value *v, copy; reg = readreg(); if (reg >= 0) { inumber = pop_number(); if (inumber == NULL) return; index = get_ulong(inumber); if (BN_cmp(inumber->number, &zero) < 0) warnx("negative index"); else if (index == BN_MASK2 || index > MAX_ARRAY_INDEX) warnx("index too big"); else { stack = &bmachine.reg[reg]; v = frame_retrieve(stack, index); if (v == NULL) { n = new_number(); bn_check(BN_zero(n->number)); push_number(n); } else push(stack_dup_value(v, ©)); } free_number(inumber); } }
static void parse_number(void) { unreadch(); push_number(readnumber(&bmachine.readstack[bmachine.readsp], bmachine.ibase)); }
static void load_array(void) { struct number *inumber, *n; struct stack *stack; struct value *v; struct value copy; u_long idx; int reg; reg = readreg(); if (reg >= 0) { inumber = pop_number(); if (inumber == NULL) return; idx = get_ulong(inumber); if (BN_is_negative(inumber->number)) warnx("negative idx"); else if (idx == ULONG_MAX || idx > MAX_ARRAY_INDEX) warnx("idx too big"); else { stack = &bmachine.reg[reg]; v = frame_retrieve(stack, idx); if (v == NULL || v->type == BCODE_NONE) { n = new_number(); bn_check(BN_zero(n->number)); push_number(n); } else push(stack_dup_value(v, ©)); } free_number(inumber); } }
static void push_scale(void) { struct value *value; u_int scale = 0; struct number *n; value = pop(); if (value != NULL) { switch (value->type) { case BCODE_NONE: return; case BCODE_NUMBER: scale = value->u.num->scale; break; case BCODE_STRING: break; } stack_free_value(value); n = new_number(); bn_check(BN_set_word(n->number, scale)); push_number(n); } }
static void num_digits(void) { struct number *n = NULL; struct value *value; size_t digits; value = pop(); if (value != NULL) { switch (value->type) { case BCODE_NONE: return; case BCODE_NUMBER: digits = count_digits(value->u.num); n = new_number(); bn_check(BN_set_word(n->number, digits)); break; case BCODE_STRING: digits = strlen(value->u.string); n = new_number(); bn_check(BN_set_word(n->number, digits)); break; } stack_free_value(value); push_number(n); } }
static void bsqrt(void) { struct number *n; struct number *r; BIGNUM *x, *y; u_int scale, onecount; BN_CTX *ctx; onecount = 0; n = pop_number(); if (n == NULL) { return; } if (BN_is_zero(n->number)) { r = new_number(); push_number(r); } else if (BN_is_negative(n->number)) warnx("square root of negative number"); else { scale = max(bmachine.scale, n->scale); normalize(n, 2*scale); x = BN_dup(n->number); bn_checkp(x); bn_check(BN_rshift(x, x, BN_num_bits(x)/2)); y = BN_new(); bn_checkp(y); ctx = BN_CTX_new(); bn_checkp(ctx); for (;;) { bn_checkp(BN_copy(y, x)); bn_check(BN_div(x, NULL, n->number, x, ctx)); bn_check(BN_add(x, x, y)); bn_check(BN_rshift1(x, x)); if (bsqrt_stop(x, y, &onecount)) break; } r = bmalloc(sizeof(*r)); r->scale = scale; r->number = y; BN_free(x); BN_CTX_free(ctx); push_number(r); } free_number(n); }
void eval_exp(char *exp, int len){ //Using two stacks stack *n_stack=NULL;//number stack int i=0;//counter for the above array double n;//To store the converted number char c;//To store the character in the expression double x=1.0, y=1.0; //Making changes so that the end and beginning of the exoression can be identified stack *o_stack=NULL; push_operator('{', &o_stack);;//initializing the first value of o_stack strcat(exp,"}"); ++len; while(isnotempty(o_stack)){ c=exp[i]; if(isdigit(c)){ n=atof((exp+i));//Getting the entire number while(isdigit(c)||c=='.'){ ++i; c=exp[i]; } --i;//The last increment takes an extra character from the expression //Pushing into n stack push_number(n, &n_stack); } else{ if(c=='}'){//End of the expression while(top_operator(o_stack)!='{'){ //Updating stacks after computation eval(&n_stack, &o_stack, &x, &y); } pop_operator(&o_stack);//poping the '{' from the o_stack } else if(c==')'){//Priority of parenthesis while(top_operator(o_stack)!='('){ //updating stacks after computation eval(&n_stack, &o_stack, &x, &y); } pop_operator(&o_stack);//popping the '(' operator from the o_stack } else if(in_stack_priority(top_operator(o_stack))>=out_stack_priority(c)){ do{ //Pooping elements and taking temporary values eval(&n_stack, &o_stack, &x, &y); }while(in_stack_priority(top_operator(o_stack))>=out_stack_priority(c)); push_operator(c, &o_stack);//Pushing the new operator into the o_stack } else{//Pushing the operator in the o_stack push_operator(c, &o_stack); } } ++i;//incrementing the counter } //returning the final result printf("\nThe value of x is %lf and y is %lf.\nThe value of the expression is: %lf\n", x, y, pop_number(&n_stack)); }
void f_reference_allowed() { svalue_t *sv = sp - st_num_arg + 1; svalue_t *v; object_t *referee = NULL; object_t *referrer_obj = command_giver; /* Default to this_player(). */ const char *referrer_name = NULL; int result = 0; int num_arg = st_num_arg; /* Maybe I could learn how to use this :p CHECK_TYPES(sp-1, T_NUMBER, 1, F_MEMBER_ARRAY); */ if (sv->type == T_OBJECT && sv->u.ob) { referee = sv->u.ob; } if (st_num_arg > 1) { if (sv[1].type == T_STRING && sv[1].u.string) { /* We've been passed in a string, now we need to call * find_player() */ #ifdef F_FIND_PLAYER /* If we have a find_player() efun, then we need to sue * the following method. This hasn't been tested! */ referrer = find_living_object(sv[1].u.string, 1); #else if (simul_efun_ob) { push_svalue(&sv[1]); v = apply("find_player", simul_efun_ob, 1, ORIGIN_EFUN); if (v && v->type == T_OBJECT) { referrer_obj = v->u.ob; referrer_name = sv[1].u.string; } else { referrer_obj = NULL; referrer_name = sv[1].u.string; } } #endif } if (sv[1].type == T_OBJECT && sv[1].u.ob) { referrer_obj = sv[1].u.ob; referrer_name = NULL; } } if (referee && (referrer_obj || referrer_name)) { result = reference_allowed(referee, referrer_obj, referrer_name); pop_n_elems(num_arg); push_number(result); } else { pop_n_elems(num_arg); push_undefined(); } }
void f_query_verb (void) { if (!last_verb) { push_number(0); return; } share_and_push_string(last_verb); }
void c_end_catch(error_context_t * econ) { free_svalue(&catch_value, "F_END_CATCH"); catch_value = const0; /* We come here when no longjmp() was executed */ pop_control_stack(); push_number(0); pop_context(econ); }
static void slow_shut_down(void *v) { shutdown_task = 0; push_number(slow_shut_down_to_do); slow_shut_down_to_do = 0; apply_master_ob(M_MEMORY_FAILURE, 1); }
static void get_ibase(void) { struct number *n; n = new_number(); bn_check(BN_set_word(n->number, bmachine.ibase)); push_number(n); }
void f_strwidth(){ int len = SVALUE_STRLEN(sp); int width = 0; int i; for(i=0; i<len; i++) width += !(((sp->u.string[i]) & 0xc0) == 0x80); pop_stack(); push_number(width); }
static void lesseq_numbers(void) { struct number *a, *b, *r; a = pop_number(); if (a == NULL) return; b = pop_number(); if (b == NULL) { push_number(a); return; } r = new_number(); bn_check(BN_set_word(r->number, compare_numbers(BCODE_NOT_GREATER, a, b) ? 1 : 0)); push_number(r); }
void f_pcre_cache(void) { mapping_t *m=NULL; m = pcre_get_cache(); if (!m) push_number(0); else push_refed_mapping(m); }
static void equal_numbers(void) { struct number *a, *b, *r; a = pop_number(); if (a == NULL) { return; } b = pop_number(); if (b == NULL) { push_number(a); return; } r = new_number(); bn_check(BN_set_word(r->number, compare_numbers(BCODE_EQUAL, a, b) ? 1 : 0)); push_number(r); }
void f_set_encoding(){ if(current_object->interactive){ struct translation *newt = get_translator((char *)sp->u.string); if(newt){ current_object->interactive->trans = newt; return; } } pop_stack(); push_number(0); }
void handle_db_exec(struct request *req){ free_svalue(&req->tmp, "handle_db_exec"); int val = req->ret; if(val == -1){ copy_and_push_string(req->path); } else push_number(val); set_eval(max_cost); safe_call_efun_callback(req->fun, 1); }
static void bdiv(void) { struct number *a, *b, *r; a = pop_number(); if (a == NULL) return; b = pop_number(); if (b == NULL) { push_number(a); return; } r = div_number(b, a, bmachine.scale); push_number(r); free_number(a); free_number(b); }
static void stackdepth(void) { struct number *n; size_t i; i = stack_size(&bmachine.stack); n = new_number(); bn_check(BN_set_word(n->number, i)); push_number(n); }
static void bdivmod(void) { struct number *a, *b; struct number *rdiv, *rmod; u_int scale; BN_CTX *ctx; a = pop_number(); if (a == NULL) { return; } b = pop_number(); if (b == NULL) { push_number(a); return; } rdiv = new_number(); rmod = new_number(); rdiv->scale = bmachine.scale; rmod->scale = max(b->scale, a->scale + bmachine.scale); scale = max(a->scale, b->scale); if (BN_is_zero(a->number)) warnx("divide by zero"); else { normalize(a, scale); normalize(b, scale + bmachine.scale); ctx = BN_CTX_new(); bn_checkp(ctx); bn_check(BN_div(rdiv->number, rmod->number, b->number, a->number, ctx)); BN_CTX_free(ctx); } push_number(rdiv); push_number(rmod); free_number(a); free_number(b); }