struct vector * set_manipulate_array(struct vector *arr1, struct vector *arr2, int op) { struct mapping *m; struct vector *r; struct svalue tmp, *v; char *flags; int cnt, res; if (arr1->size < 1 || arr2->size < 1) { switch (op) { case SETARR_SUBTRACT: INCREF(arr1->ref); return arr1; case SETARR_INTERSECT: return allocate_array(0); } } m = make_mapping(arr2, 0); tmp.type = T_NUMBER; tmp.u.number = 1; assign_svalue_no_free(get_map_lvalue(m, &arr2->item[0], 1), &tmp); res = 0; flags = alloca((size_t)arr1->size + 1); for (cnt = 0; cnt < arr1->size; cnt++) { flags[cnt] = 0; v = get_map_lvalue(m, &(arr1->item[cnt]), 0); if (op == SETARR_INTERSECT && v != &const0) { flags[cnt] = 1; res++; } else if (op == SETARR_SUBTRACT && v == &const0) { flags[cnt] = 1; res++; } } r = allocate_array(res); if (res) { for (cnt = res = 0; cnt < arr1->size; cnt++) { if (flags[cnt]) assign_svalue_no_free(&r->item[res++], &arr1->item[cnt]); } } free_mapping(m); return r; }
static INLINE struct apair * newpair(struct apair *n, struct svalue *k, struct svalue *v, short h) { struct apair *p = (struct apair *)xalloc(sizeof(struct apair)); p->next = n; p->hashval = h; assign_svalue_no_free(&p->arg, k); assign_svalue_no_free(&p->val, v); total_mapping_size += sizeof(struct apair); return p; }
INLINE struct vector * union_array(struct vector *arr1, struct vector *arr2) { int i, size; struct mapping *mp; struct vector *arr3; char *set; if (arr1->size == 0) { INCREF(arr2->ref); return arr2; } if (arr2->size == 0) { INCREF(arr1->ref); return arr1; } mp = allocate_map(arr1->size); for (i = 0; i < arr1->size; i++) assign_svalue(get_map_lvalue(mp, &arr1->item[i], 1), &const1); set = alloca((size_t)arr2->size); for (i = size = 0; i < arr2->size; i++) { if (get_map_lvalue(mp, &arr2->item[i], 0) == &const0) set[i] = 1, size++; else set[i] = 0; } free_mapping(mp); arr3 = allocate_array(arr1->size + size); for (i = 0; i < arr1->size; i++) assign_svalue_no_free(&arr3->item[i], &arr1->item[i]); size = arr1->size; for (i = 0; i < arr2->size; i++) if (set[i]) assign_svalue_no_free(&arr3->item[size++], &arr2->item[i]); return arr3; }
int add_write(const char *fname, const char *buf, int size, char flags, function_to_call_t *fun) { if (fname) { aiob *aio = get_aiob(); memset(aio, 0, sizeof(aiob)); int fd = open(fname, flags & 1 ? O_CREAT|O_WRONLY : O_CREAT|O_WRONLY|O_APPEND, S_IRWXU|S_IRWXG); aio->aio_fildes = fd; aio->aio_buf = buf; aio->aio_nbytes = size; struct request *req = get_req(); req->aio = aio; req->fun = fun; req->type = awrite; assign_svalue_no_free(&req->tmp, sp-2); add_req(req); #ifdef PACKAGE_COMPRESS if(flags & 2) return aio_gzwrite(aio); else #endif return aio_write(aio); } else error("permission denied\n"); return 1; }
/*-------------------------------------------------------------------------*/ static vector_t * intersect_ordered_arr (vector_t *a1, vector_t *a2) /* Compute the intersection of the two ordered arrays <a1> and <a2>. * * The result is a new sorted(!) vector with all elements, which are present * in both input vectors. * This function is called by f_intersect_alists(). */ { vector_t *a3; mp_int d, l, i1, i2, a1s, a2s; a1s = (mp_int)VEC_SIZE(a1); a2s = (mp_int)VEC_SIZE(a2); a3 = allocate_array( a1s < a2s ? a1s : a2s); for (i1=i2=l=0; i1 < a1s && i2 < a2s; ) { d = svalue_cmp(&a1->item[i1], &a2->item[i2]); if (d<0) i1++; else if (d>0) i2++; else { assign_svalue_no_free(&a3->item[l++], &a2->item[(i1++,i2++)] ); } } return shrink_array(a3, l); } /* intersect_ordered_arr() */
static int pcre_match_single(svalue_t *str, svalue_t *pattern) { pcre_t *run; int ret; run = CALLOCATE(1, pcre_t, TAG_TEMPORARY, "pcre_match_single : run"); run->ovector = NULL; run->ovecsize = 0; assign_svalue_no_free(&run->pattern, pattern); run->subject = str->u.string; run->s_length = SVALUE_STRLEN(str); if(pcre_magic(run) < 0) { error("PCRE compilation failed at offset %d: %s\n", run->erroffset, run->error); pcre_free_memory(run); return 0; } ret = pcre_query_match(run); /* Free memory */ pcre_free_memory(run); return ret; }
void c_rindex() { int i; switch (sp->type) { #ifndef NO_BUFFER_TYPE case T_BUFFER: { if ((sp-1)->type != T_NUMBER) error("Indexing a buffer with an illegal type.\n"); i = sp->u.buf->size - (sp - 1)->u.number; if ((i > sp->u.buf->size) || (i < 0)) error("Buffer index out of bounds.\n"); i = sp->u.buf->item[i]; free_buffer(sp->u.buf); (--sp)->u.number = i; break; } #endif case T_STRING: { int len = SVALUE_STRLEN(sp); if ((sp-1)->type != T_NUMBER) { error("Indexing a string with an illegal type.\n"); } i = len - (sp - 1)->u.number; if ((i > len) || (i < 0)) error("String index out of bounds.\n"); i = (unsigned char) sp->u.string[i]; free_string_svalue(sp); (--sp)->u.number = i; break; } case T_ARRAY: { array_t *vec = sp->u.arr; if ((sp-1)->type != T_NUMBER) error("Indexing an array with an illegal type\n"); i = vec->size - (sp - 1)->u.number; if (i < 0 || i >= vec->size) error("Array index out of bounds.\n"); assign_svalue_no_free(--sp, &vec->item[i]); free_array(vec); break; } default: error("Indexing from the right on illegal type.\n"); } /* * Fetch value of a variable. It is possible that it is a * variable that points to a destructed object. In that case, * it has to be replaced by 0. */ if (sp->type == T_OBJECT && (sp->u.ob->flags & O_DESTRUCTED)) { free_object(sp->u.ob, "F_RINDEX"); *sp = const0u; } }
/* EFUN: filter (array part) Runs all elements of an array through fun and returns an array holding those elements that fun returned 1 for. */ struct vector * filter_arr(struct vector *p, struct closure *fun) { struct vector *r; char *flags; int cnt,res; if (p->size<1) return allocate_array(0); res = 0; flags = tmpalloc((size_t)p->size + 1); for (cnt = 0; cnt < p->size; cnt++) { push_svalue(&p->item[cnt]); (void)call_var(1, fun); if (sp->type == T_NUMBER && sp->u.number) { flags[cnt] = 1; res++; } else flags[cnt] = 0; pop_stack(); } r = allocate_array(res); for (cnt = res = 0; res < r->size && cnt < p->size; cnt++) { if (flags[cnt]) assign_svalue_no_free(&r->item[res++], &p->item[cnt]); } /* tmpfree(flags); */ return r; }
/* * Slice of an array. */ struct vector * slice_array(struct vector *p, long long from, long long to) { struct vector *d; long long cnt; #ifdef NEGATIVE_SLICE_INDEX if (from < 0) from = p->size + from; #endif if (from < 0) from = 0; if (from >= p->size) return allocate_array(0); /* Slice starts above array */ #ifdef NEGATIVE_SLICE_INDEX if (to < 0) to = p->size + to; #endif if (to >= p->size) to = p->size - 1; if (to < from) return allocate_array(0); d = allocate_array(to - from + 1); for (cnt = from; cnt <= to; cnt++) assign_svalue_no_free (&d->item[cnt - from], &p->item[cnt]); return d; }
int add_db_exec(int handle, function_to_call_t *fun) { struct request *req = get_req(); req->fun = fun; req->type = adbexec; req->buf = (char *)handle; assign_svalue_no_free(&req->tmp, sp-1); return aio_db_exec(req); }
void f_element_of(){ array_t *arr = sp->u.arr; if(!arr->size){ error("Can't take element from empty array.\n"); } assign_svalue_no_free(sp, &arr->item[random_number(arr->size)]); free_array(arr); }
void c_member(int idx) { array_t *arr; if (sp->type != T_CLASS) error("Tried to take a member of something that isn't a class.\n"); arr = sp->u.arr; if (idx >= arr->size) error("Class has no corresponding member.\n"); assign_svalue_no_free(sp, &arr->item[idx]); free_class(arr); }
struct vector * make_unique(struct vector *arr, struct closure *fun, struct svalue *skipnum) { struct vector *res, *ret; struct unique *head, *nxt, *nxt2; int cnt, ant, cnt2; if (arr->size < 1) return allocate_array(0); head = 0; ant = 0; INCREF(arr->ref); for(cnt = 0; cnt < arr->size; cnt++) { if (arr->item[cnt].type == T_OBJECT) { push_svalue(&arr->item[cnt]); (void)call_var(1, fun); if ((!sp) || (sp->type != skipnum->type) || !equal_svalue(sp, skipnum)) { if (sp) { ant = put_in(&head, sp, &(arr->item[cnt])); } } pop_stack(); } } DECREF(arr->ref); ret = allocate_array(ant); for (cnt = ant - 1; cnt >= 0; cnt--) /* Reverse to compensate put_in */ { ret->item[cnt].type = T_POINTER; ret->item[cnt].u.vec = res = allocate_array(head->count); nxt2 = head; head = head->next; cnt2 = 0; while (nxt2) { assign_svalue_no_free (&res->item[cnt2++], nxt2->val); free_svalue(&nxt2->mark); nxt = nxt2->same; /* tmpfree((char *) nxt2); */ nxt2 = nxt; } if (!head) break; /* It shouldn't but, to avoid skydive just in case */ } return ret; }
void c_expand_varargs(int where) { svalue_t *s, *t; array_t *arr; int n; s = sp - where; if (s->type != T_ARRAY) error("Item being expanded with ... is not an array\n"); arr = s->u.arr; n = arr->size; num_varargs += n - 1; if (!n) { t = s; while (t < sp) { *t = *(t + 1); t++; } sp--; } else if (n == 1) { assign_svalue_no_free(s, &arr->item[0]); } else { t = sp; CHECK_STACK_OVERFLOW(n - 1); sp += n - 1; while (t > s) { *(t + n - 1) = *t; t--; } t = s + n - 1; if (arr->ref == 1) { memcpy(s, arr->item, n * sizeof(svalue_t)); free_empty_array(arr); return; } else { while (n--) assign_svalue_no_free(t--, &arr->item[n]); } } free_array(arr); }
/* Concatenation of two arrays into one */ struct vector * add_array(struct vector *p, struct vector *r) { int cnt,res; struct vector *d; d = allocate_array(p->size + r->size); res = 0; for (cnt = 0; cnt < p->size; cnt++) { assign_svalue_no_free (&d->item[res],&p->item[cnt]); res++; } for (cnt = 0; cnt < r->size; cnt++) { assign_svalue_no_free (&d->item[res],&r->item[cnt]); res++; } return d; }
/*! @decl void set_output_closed_callback(void|function(mixed, object:mixed) close_cb, @ *! void|mixed id) *! *! Set the callback function to be called when one of the outputs has *! been closed from the other side. */ static void pipe_set_output_closed_callback(INT32 args) { if (args==0) { free_svalue(&THIS->output_closed_callback); THIS->output_closed_callback.type=T_INT; return; } if (args<1 || (sp[-args].type!=T_FUNCTION && sp[-args].type!=T_ARRAY)) Pike_error("Illegal argument to set_output_closed_callback()\n"); if (args>1) { free_svalue(&THIS->id); assign_svalue_no_free(&(THIS->id),sp-args+1); } free_svalue(&THIS->output_closed_callback); assign_svalue_no_free(&(THIS->output_closed_callback),sp-args); pop_n_elems(args-1); }
/* * Copy of an array */ array_t *copy_array P1(array_t *, p) { array_t *d; int n; svalue_t *sv1 = p->item, *sv2; d = allocate_empty_array(n = p->size); sv2 = d->item; while (n--) assign_svalue_no_free(sv2 + n, sv1 + n); return d; }
/* * Slice of an array. * It now frees the passed array */ array_t *slice_array P3(array_t *, p, int, from, int, to) { int cnt; svalue_t *sv1, *sv2; if (from < 0) from = 0; if (to >= p->size) to = p->size - 1; if (from > to) { free_array(p); return null_array(); } if (!(--p->ref)){ #ifdef PACKAGE_MUDLIB_STATS add_array_size(&p->stats, -((int)p->size)); #endif total_array_size += (to - from + 1 - p->size) * sizeof(svalue_t); if (from) { sv1 = p->item + from; cnt = from; while (cnt--) free_svalue(--sv1, "slice_array:2"); cnt = to - from + 1; sv1 = p->item; sv2 = p->item + from; while (cnt--) *sv1++ = *sv2++; } else { sv2 = p->item + to + 1; } cnt = (p->size - 1) - to; while (cnt--) free_svalue(sv2++, "slice_array:3"); p = RESIZE_ARRAY(p, to-from+1); #ifdef PACKAGE_MUDLIB_STATS if (current_object) { assign_stats(&p->stats, current_object); add_array_size(&p->stats, to - from + 1); } else null_stats(&p->stats); #endif p->size = to-from+1; p->ref = 1; return p; } else { array_t *d; d = allocate_empty_array(to - from + 1); sv1 = d->item - from; sv2 = p->item; for (cnt = from; cnt <= to; cnt++) assign_svalue_no_free(sv1 + cnt, sv2 + cnt); return d; } }
static int put_in(struct unique **ulist, struct svalue *marker, struct svalue *elem) { struct unique *llink, *slink, *tlink; int cnt,fixed; llink = *ulist; cnt = 0; fixed = 0; while (llink) { if ((!fixed) && (equal_svalue(marker, &(llink->mark)))) { for (tlink = llink; tlink->same; tlink = tlink->same) (tlink->count)++; (tlink->count)++; slink = (struct unique *) tmpalloc(sizeof(struct unique)); slink->count = 1; assign_svalue_no_free(&slink->mark, marker); slink->val = elem; slink->same = 0; slink->next = 0; tlink->same = slink; fixed = 1; /* We want the size of the list so do not break here */ } llink = llink->next; cnt++; } if (fixed) return cnt; llink = (struct unique *) tmpalloc(sizeof(struct unique)); llink->count = 1; assign_svalue_no_free(&llink->mark, marker); llink->val = elem; llink->same = 0; llink->next = *ulist; *ulist = llink; return cnt + 1; }
/* do the done_callback, then close and free everything */ static INLINE void pipe_done(void) { if (THIS->done_callback.type!=T_INT) { assign_svalue_no_free(sp++,&THIS->id); apply_svalue(&(THIS->done_callback),1); pop_stack(); if(!THISOBJ->prog) /* We will not free anything in this case. */ return; /* Pike_error("Pipe done callback destructed pipe.\n"); */ } close_and_free_everything(THISOBJ,THIS); }
void implode_array P4(funptr_t *, fp, array_t *, arr, svalue_t *, dest, int, first_on_stack) { int i = 0, n; svalue_t *v; if (first_on_stack) { if (!(n = arr->size)) { *dest = *sp--; return; } } else { if (!(n = arr->size)) { *dest = const0; return; } else if (n == 1) { assign_svalue_no_free(dest, &arr->item[0]); return; } } if (!first_on_stack) push_svalue(&arr->item[i++]); while (1) { push_svalue(&arr->item[i++]); v = call_function_pointer(fp, 2); if (!v) { *dest = const0; return; } if (i < n) push_svalue(v); else break; } assign_svalue_no_free(dest, v); }
struct svalue get_variable(struct object *ob, char *var_name) { int i; struct svalue res = const0; if (ob->flags & O_DESTRUCTED) return res; if (!ob->variables) return const0; if ((i = find_status(ob->prog, var_name,0)) != -1) assign_svalue_no_free(&res, &ob->variables[i]); return res; }
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; }
static void finished_p(struct callback *foo, void *b, void *c) { extern void f_low_aap_reqo__init( struct c_request_object * ); aap_clean_cache(); while(request) { struct args *arg; struct object *o; struct c_request_object *obj; mt_lock(&queue_mutex); arg = request; request = arg->next; mt_unlock(&queue_mutex); o = clone_object( request_program, 0 ); /* see requestobject.c */ obj = (struct c_request_object *)get_storage(o, c_request_program ); MEMSET(obj, 0, sizeof(struct c_request_object)); obj->request = arg; obj->done_headers = allocate_mapping( 20 ); obj->misc_variables = allocate_mapping( 40 ); f_low_aap_reqo__init( obj ); push_object( o ); assign_svalue_no_free(sp++, &arg->args); /* { */ /* JMP_BUF recovery; */ /* free_svalue(& throw_value); */ /* mark_free_svalue (&throw_value); */ /* if(SETJMP(recovery)) */ /* { */ /* } */ /* else */ /* { */ apply_svalue(&arg->cb, 2); /* } */ /* } */ pop_stack(); } }
struct svalue get_variables(struct object *ob) { int i, j; struct vector *names; struct vector *values; struct svalue res; int num_var; if (ob->flags & O_DESTRUCTED) return const0; if (!ob->variables) return const0; num_var = ob->prog->num_variables + ob->prog->inherit[ob->prog->num_inherited - 1] .variable_index_offset; names = allocate_array(num_var); values = allocate_array(num_var); for (j = ob->prog->num_inherited - 1; j >= 0; j--) if (!(ob->prog->inherit[j].type & TYPE_MOD_SECOND) && ob->prog->inherit[j].prog->num_variables > 0) { for (i = 0; i < (int)ob->prog->inherit[j].prog->num_variables; i++) { if (num_var == 0) error("Wrong number of variables in object.\n"); names->item[--num_var].type = T_STRING; names->item[num_var].string_type = STRING_SSTRING; names->item[num_var].u.string = reference_sstring(ob->prog->inherit[j].prog-> variable_names[i].name); assign_svalue_no_free(&values->item[num_var], &ob->variables[ob->prog->inherit[j] .variable_index_offset + i]); } } res.type = T_MAPPING; res.u.map = make_mapping(names, values); free_vector(names); free_vector(values); return res; }
void f_fetch_class_member() { int pos = sp->u.number; array_t *arr; pos = sp->u.number; pop_stack(); if( sp->type != T_CLASS ) error( "Argument to fetch_class_member() not a class.\n" ); arr = sp->u.arr; if( pos < 0 || pos >= arr->size ) error( "Class index out of bounds.\n" ); assign_svalue_no_free( sp, &arr->item[pos] ); free_array( arr ); }
struct svalue * json_to_array(json_object *ob) { int arraylen = json_object_array_length(ob); static struct svalue ret; ret.type = T_POINTER; ret.u.vec = allocate_array(arraylen); for (int x = 0; x < arraylen; x++) { json_object *element = json_object_array_get_idx(ob, x); assign_svalue_no_free(&ret.u.vec->item[x], json_to_value(element)); } return &ret; }
struct svalue * json_to_mapping(json_object *ob) { static struct svalue ret; ret.type = T_MAPPING; ret.u.map = allocate_map(10); json_object_object_foreach(ob, name, val) { struct svalue key = {}; key.type = T_STRING; key.string_type = STRING_MSTRING; key.u.string = make_mstring(name); assign_svalue_no_free(get_map_lvalue(ret.u.map, &key, 1), json_to_value(val)); } return &ret; }
int add_write(const char *fname, const char *buf, int size, char flags, function_to_call_t *fun) { if (fname) { struct request *req = get_req(); req->buf = buf; req->size = size; req->fun = fun; req->type = awrite; req->flags = flags; strcpy(req->path, fname); assign_svalue_no_free(&req->tmp, sp-2); #ifdef PACKAGE_COMPRESS if(flags & 2) return aio_gzwrite(req); else #endif return aio_write(req); } else error("permission denied\n"); return 1; }
struct vector * multiply_array(struct vector *vec, long long factor) { struct vector *result; long long size = vec->size, newsize,j, offset; if (factor <= 0 || size == 0) { return allocate_array(0); } if (factor > MAX_ARRAY_SIZE) error("Illegal array size.\n"); newsize = size * factor; result = allocate_array(newsize); for (offset = 0; offset < newsize;) { for (j = 0; j < size; j++, offset++) assign_svalue_no_free(result->item + offset, vec->item + j); } return result; }