pike.git / src / array.c

version» Context lines:

pike.git/src/array.c:1:   /*   || This file is part of Pike. For copyright information see COPYRIGHT.   || Pike is distributed under GPL, LGPL and MPL. See the file COPYING   || for more information. - || $Id: array.c,v 1.174 2004/10/16 07:27:30 agehall Exp $ + || $Id: array.c,v 1.175 2004/10/16 22:03:45 nilsson Exp $   */      #include "global.h"   #include "svalue.h"   #include "array.h"   #include "object.h"   #include "las.h"   #include "stralloc.h"   #include "interpret.h"   #include "opcodes.h"
pike.git/src/array.c:20:   #include "pike_memory.h"   #include "gc.h"   #include "main.h"   #include "pike_security.h"   #include "stuff.h"   #include "bignum.h"   #include "cyclic.h"   #include "multiset.h"   #include "mapping.h"    + /** The empty array. */   PMOD_EXPORT struct array empty_array=   {    PIKE_CONSTANT_MEMOBJ_INIT(1), /* Never free */    &weak_empty_array, /* Next */    0, /* previous */    0, /* Size = 0 */    0, /* malloced Size = 0 */    0, /* no types */    0, /* no flags */    empty_array.real_item, /* Initialize the item pointer. */   #ifdef HAVE_UNION_INIT    {{0, 0, {0}}}, /* Only to avoid warnings. */   #endif   }; -  +  + /** The empty weak array. */   PMOD_EXPORT struct array weak_empty_array=   {    PIKE_CONSTANT_MEMOBJ_INIT(1),    0, &empty_array, 0, 0, 0, ARRAY_WEAK_FLAG,    weak_empty_array.real_item,   #ifdef HAVE_UNION_INIT    {{0, 0, {0}}}, /* Only to avoid warnings. */   #endif   };   
pike.git/src/array.c:57: Inside #if defined(TRACE_UNFINISHED_TYPE_FIELDS)
     #ifdef TRACE_UNFINISHED_TYPE_FIELDS   PMOD_EXPORT int accept_unfinished_type_fields = 0;   PMOD_EXPORT void dont_accept_unfinished_type_fields (void *orig)   {    accept_unfinished_type_fields = (int) orig;   }   #endif       - /* Allocate an array, this might be changed in the future to -  * allocate linked lists or something -  * NOTE: the new array has zero references + /** +  * Allocate an array. This might be changed in the future to allocate +  * linked lists or something. The new array has zero references. +  * +  * When building arrays, it is recommended that you push the values on +  * the stack and call aggregate_array or f_aggregate instead of +  * allocating and filling in the values 'by hand'. +  * +  * @param size The size of the new array, in elements. +  * @param extra_space The number of extra elements space +  * should be reserved for.    */ -  +    PMOD_EXPORT struct array *real_allocate_array(ptrdiff_t size,    ptrdiff_t extra_space)   {    struct array *v;    ptrdiff_t e;       if(size+extra_space == 0)    {    add_ref(&empty_array);    return &empty_array;
pike.git/src/array.c:111:    for(e=0;e<v->size;e++)    {    ITEM(v)[e].type=T_INT;    ITEM(v)[e].subtype=NUMBER_NUMBER;    ITEM(v)[e].u.integer=0;    }       return v;   }    - /* -  * Free an array without freeing the values inside it + /** +  * Free an array without freeing the values inside it.    */   static void array_free_no_free(struct array *v)   {    DOUBLEUNLINK (first_array, v);       free((char *)v);       GC_FREE(v);   }    - /* -  * Free an array, call this when the array has zero references + /** +  * Free an array. Call this when the array has zero references.    */   PMOD_EXPORT void really_free_array(struct array *v)   {   #ifdef PIKE_DEBUG    if(v == & empty_array || v == &weak_empty_array)    Pike_fatal("Tried to free some *_empty_array.\n");    if (v->refs) {   #ifdef DEBUG_MALLOC    describe_something(v, T_ARRAY, 0,2,0, NULL);   #endif
pike.git/src/array.c:175:    case ARRAY_WEAK_FLAG:    add_ref(a = &weak_empty_array); break;    default:    Pike_fatal("Invalid flags %x\n", flags);    }    }    return a;   }       - /* -  * Extract an svalue from an array + /** +  * Extract an svalue from an array.    */   PMOD_EXPORT void array_index(struct svalue *s,struct array *v,INT32 index)   {   #ifdef PIKE_DEBUG    if(index<0 || index>=v->size)    Pike_fatal("Illegal index in low level index routine.\n");   #endif       add_ref(v);    assign_svalue(s, ITEM(v) + index);
pike.git/src/array.c:284:    default:    {    struct svalue tmp;    tmp.type=T_ARRAY;    tmp.u.array=a;    index_error(0,0,0,&tmp,ind,"Array index is neither int nor string.\n");    }    }   }    - /* -  * Extract an svalue from an array + /** +  * Extract an svalue from an array.    */   PMOD_EXPORT void array_free_index(struct array *v,INT32 index)   {   #ifdef PIKE_DEBUG    if(index<0 || index>=v->size)    Pike_fatal("Illegal index in low level free index routine.\n");   #endif       free_svalue(ITEM(v) + index);   }
pike.git/src/array.c:341:    default:    {    struct svalue tmp;    tmp.type=T_ARRAY;    tmp.u.array=a;    index_error(0,0,0,&tmp,ind,"Array index is neither int nor string.\n");    }    }   }    - /* -  * Insert an svalue into an array, grow the array if nessesary + /** +  * Insert an svalue into an array and grow the array if nessesary.    */   PMOD_EXPORT struct array *array_insert(struct array *v,struct svalue *s,INT32 index)   {   #ifdef PIKE_DEBUG    if(index<0 || index>v->size)    Pike_fatal("Illegal index in low level insert routine.\n");   #endif       /* Can we fit it into the existing block? */    if(v->refs<=1 && v->malloced_size > v->size)
pike.git/src/array.c:387:    v->size=0;    free_array(v);    v=ret;    }       array_set_index(v,index,s);       return v;   }    - /* + /**    * Shrink an array destructively    */   PMOD_EXPORT struct array *array_shrink(struct array *v, ptrdiff_t size)   {    struct array *a;      #ifdef PIKE_DEBUG    if(v->refs>2) /* Odd, but has to be two */    Pike_fatal("Array shrink on array with many references.\n");   
pike.git/src/array.c:421:    v->size=0;    free_array(v);    return a;    }else{    free_svalues(ITEM(v) + size, v->size - size, v->type_field);    v->size=size;    return v;    }   }    - /* -  * resize array, resize an array destructively + /** +  * Resize an array destructively.    */   PMOD_EXPORT struct array *resize_array(struct array *a, INT32 size)   {   #ifdef PIKE_DEBUG    if(d_flag > 1) array_check_type_field(a);   #endif       if(a->size == size) return a;    if(size > a->size)    {
pike.git/src/array.c:460:    ret->type_field = DO_NOT_WARN((TYPE_FIELD)(a->type_field | BIT_INT));    a->size=0;    free_array(a);    return ret;    }    } else {    return array_shrink(a, size);    }   }    - /* -  * Remove an index from an array and shrink the array + /** +  * Remove an index from an array and shrink the array.    */   PMOD_EXPORT struct array *array_remove(struct array *v,INT32 index)   {    struct array *a;      #ifdef PIKE_DEBUG    if(index<0 || index >= v->size)    Pike_fatal("Illegal argument to array_remove.\n");   #endif   
pike.git/src/array.c:505:    {    MEMMOVE((char *)(ITEM(v)+index),    (char *)(ITEM(v)+index+1),    (v->size-index-1)*sizeof(struct svalue));    }    v->size--;    return v;    }   }    - /* + /**    * Search for in svalue in an array. -  * return the index if found, -1 otherwise +  * @return the index if found, -1 otherwise    */   PMOD_EXPORT ptrdiff_t array_search(struct array *v, struct svalue *s,    ptrdiff_t start)   {    ptrdiff_t e;      #ifdef PIKE_DEBUG    if(start<0)    Pike_fatal("Start of find_index is less than zero.\n");   #endif
pike.git/src/array.c:549:    {    if(is_eq(ITEM(v)+e,s)) return e;    t |= 1<<ITEM(v)[e].type;    }    v->type_field=t;    }    }    return -1;   }    - /* + /**    * Slice a piece of an array (nondestructively) -  * return an array consisting of v[start..end-1] +  * @return an array consisting of v[start..end-1]    */   PMOD_EXPORT struct array *slice_array(struct array *v, ptrdiff_t start,    ptrdiff_t end)   {    struct array *a;      #ifdef PIKE_DEBUG    if(start > end || end>v->size || start<0)    Pike_fatal("Illegal arguments to slice_array()\n");   
pike.git/src/array.c:597:    a=allocate_array_no_init(end-start,0);    if (end-start) {    a->type_field = v->type_field;       assign_svalues_no_free(ITEM(a), ITEM(v)+start, end-start, v->type_field);    }       return a;   }    - /* -  * Slice a piece of an array (nondestructively) -  * return an array consisting of v[start..end-1] + /** +  * Slice a piece of an array (nondestructively). +  * @return an array consisting of v[start..end-1]    */   PMOD_EXPORT struct array *friendly_slice_array(struct array *v,    ptrdiff_t start,    ptrdiff_t end)   {    struct array *a;      #ifdef PIKE_DEBUG    if(start > end || end>v->size || start<0)    Pike_fatal("Illegal arguments to slice_array()\n");
pike.git/src/array.c:622:   #endif       a=allocate_array_no_init(end-start,0);    a->type_field = v->type_field;       assign_svalues_no_free(ITEM(a), ITEM(v)+start, end-start, v->type_field);       return a;   }    - /* -  * Copy an array + /** +  * Copy an array.    */   PMOD_EXPORT struct array *copy_array(struct array *v)   {    struct array *a;       if (!v->size) {    /* Empty array. */    add_ref(&empty_array);    return &empty_array;    }       a=allocate_array_no_init(v->size, 0);    a->type_field = v->type_field;       assign_svalues_no_free(ITEM(a), ITEM(v), v->size, v->type_field);       return a;   }    - /* -  * Clean an array from destructed objects + /** +  * Clean an array from destructed objects.    */   PMOD_EXPORT void check_array_for_destruct(struct array *v)   {    int e;    INT16 types;       types = 0;   #ifdef PIKE_DEBUG    if(d_flag > 1) array_check_type_field(v);   #endif
pike.git/src/array.c:678:       types |= BIT_INT;    }else{    types |= 1<<ITEM(v)[e].type;    }    }    v->type_field = types;    }   }    - /* -  * This function finds the index of any destructed object in a set -  * it could be optimized to search out the object part with a binary -  * search lookup if the array is mixed + /** +  * This function finds the index of any destructed object in a set. +  * It could be optimized to search out the object part with a binary +  * search lookup if the array is mixed.    */   PMOD_EXPORT INT32 array_find_destructed_object(struct array *v)   {    INT32 e;    TYPE_FIELD types;   #ifdef PIKE_DEBUG    if(d_flag > 1) array_check_type_field(v);   #endif    if(v->type_field & (BIT_OBJECT | BIT_FUNCTION))    {
pike.git/src/array.c:1007:   }      #define CMP(X,Y) alpha_svalue_cmpfun(X,Y)   #define TYPE struct svalue   #define ID low_sort_svalues   #include "fsort_template.h"   #undef CMP   #undef TYPE   #undef ID    - /* This sort is unstable. */ + /** This sort is unstable. */   PMOD_EXPORT void sort_array_destructively(struct array *v)   {    if(!v->size) return;    low_sort_svalues(ITEM(v), ITEM(v)+v->size-1);   }      #define SORT_BY_INDEX   #define EXTRA_LOCALS int cmpfun_res;   #define CMP(X,Y) ((cmpfun_res = alpha_svalue_cmpfun(svals + X, svals + Y)) ? \    cmpfun_res : pos[X] - pos[Y])
pike.git/src/array.c:1036:   #include "fsort_template.h"   #undef SORT_BY_INDEX   #undef EXTRA_LOCALS   #undef CMP   #undef SWAP   #undef TYPE   #undef ID   #undef EXTRA_ARGS   #undef XARGS    - /* This sort is stable. The return value is like the one from + /** This sort is stable. The return value is like the one from    * get_alpha_order. */   PMOD_EXPORT INT32 *stable_sort_array_destructively(struct array *v)   {    INT32 *current_order;    ONERROR tmp;    int e;       if(!v->size) return NULL;       /* Overlow safe: ((1<<29)-4)*4 < ULONG_MAX */
pike.git/src/array.c:1058:    SET_ONERROR(tmp, free, current_order);    for(e=0; e<v->size; e++) current_order[e]=e;       low_stable_sort_svalues (0, v->size - 1, ITEM (v), current_order, v->size);       UNSET_ONERROR (tmp);    return current_order;   }       - /* -  * return an 'order' suitable for making mappings and multisets + /** +  * Return an 'order' suitable for making mappings and multisets.    */   PMOD_EXPORT INT32 *get_set_order(struct array *a)   {    return get_order(a, set_svalue_cmpfun);   }    - /* -  * return an 'order' suitable for switches. + /** +  * Return an 'order' suitable for switches.    *    * Note: This is used by encode_value_canonic(). It must keep the    * sorting rules for all the types that function allows in multiset    * and mapping indices.    */   PMOD_EXPORT INT32 *get_switch_order(struct array *a)   {    return get_order(a, switch_svalue_cmpfun);   }       - /* -  * return an 'order' suitable for sorting. + /** +  * Return an 'order' suitable for sorting.    */   PMOD_EXPORT INT32 *get_alpha_order(struct array *a)   {    return get_order(a, alpha_svalue_cmpfun);   }         static INT32 low_lookup(struct array *v,    struct svalue *s,    cmpfun fun)
pike.git/src/array.c:1155:       /* face it, it's not there */    if( ((BIT_MIXED << s->type) & BIT_MIXED & a->type_field) == 0)    return ~a->size;    }       return low_lookup(a,s,switch_svalue_cmpfun);   }       - /* -  * reorganize an array in the order specified by 'order' + /** +  * Reorganize an array in the order specified by 'order'.    */   PMOD_EXPORT struct array *order_array(struct array *v, INT32 *order)   {    reorder((char *)ITEM(v),v->size,sizeof(struct svalue),order);    return v;   }       - /* -  * copy and reorganize an array + /** +  * Copy and reorganize an array.    */   PMOD_EXPORT struct array *reorder_and_copy_array(struct array *v, INT32 *order)   {    INT32 e;    struct array *ret;    ret=allocate_array_no_init(v->size, 0);    ret->type_field = v->type_field;       for(e=0;e<v->size;e++)    assign_svalue_no_free(ITEM(ret)+e, ITEM(v)+order[e]);
pike.git/src/array.c:1247: Inside #if defined(PIKE_DEBUG)
   }       if(t & ~(v->type_field))    {    describe(v);    Pike_fatal("Type field out of order!\n");    }   }   #endif /* PIKE_DEBUG */    - /* -  * Get a pointer to the 'union anything' specified IF it is of the specified + /** +  * Get a pointer to the 'union anything' specified if it is of the specified    * type. The 'union anything' may be changed, but not the type.    */   PMOD_EXPORT union anything *low_array_get_item_ptr(struct array *a,    INT32 ind,    TYPE_T t)   {    if(ITEM(a)[ind].type == t) return & (ITEM(a)[ind].u);    return 0;   }    - /* -  * Get a pointer to the 'union anything' specified IF it is of the specified + /** +  * Get a pointer to the 'union anything' specified if it is of the specified    * type. The 'union anything' may be changed, but not the type.    * The differance between this routine and the one above is that this takes    * the index as an svalue.    */   PMOD_EXPORT union anything *array_get_item_ptr(struct array *a,    struct svalue *ind,    TYPE_T t)   {    INT_TYPE i, p;    if(ind->type != T_INT)
pike.git/src/array.c:1287:    Pike_error("Index %"PRINTPIKEINT"d is out of array range "    "%"PRINTPTRDIFFT"d..%"PRINTPTRDIFFT"d.\n",    p, -a->size, a->size-1);    } else {    Pike_error("Attempt to index the empty array with %"PRINTPIKEINT"d.\n", p);    }    }    return low_array_get_item_ptr(a,i,t);   }    - /* -  * organize an array of INT32 to specify how to zip two arrays together + /** +  * Organize an array of INT32 to specify how to zip two arrays together    * to maintain the order. -  * the first item in this array is the size of the result +  * The first item in this array is the size of the result    * the rest is n >= 0 for a[ n ] -  * or n < 0 for b[ ~n ] +  * or n < 0 for b[ ~n ].    */   INT32 * merge(struct array *a,struct array *b,INT32 opcode)   {    ONERROR r;    INT32 ap,bp,i,*ret,*ptr;       ap=bp=0;   #ifdef PIKE_DEBUG    if(d_flag > 1)    {
pike.git/src/array.c:1361:    if((opcode >> 8) & PIKE_ARRAY_OP_A) while(ap<a->size) *(ptr++)=ap++;    if(opcode & PIKE_ARRAY_OP_B) while(bp<b->size) *(ptr++)=~(bp++);       *ret = DO_NOT_WARN((INT32)(ptr-ret-1));       UNSET_ONERROR(r);       return ret;   }    - /* + /**    * This routine merges two arrays in the order specified by 'zipper' -  * zipper normally produced by merge() above +  * zipper normally produced by merge() above.    */   PMOD_EXPORT struct array *array_zip(struct array *a, struct array *b,INT32 *zipper)   {    INT32 size,e;    struct array *ret;    size=zipper[0];    zipper++;       ret=allocate_array_no_init(size,0);    for(e=0; e<size; e++)
pike.git/src/array.c:1519:   #define TYPE INT32   #include "fsort_template.h"   #undef ID   #undef TYPE   #undef XARGS   #undef EXTRA_ARGS   #undef CMP          - /* -  * this is used to rearrange the zipper so that the order is retained -  * as it was before (check merge_array_with_order below) + /** +  * This is used to rearrange the zipper so that the order is retained +  * as it was before (check merge_array_with_order below).    */   static int array_merge_fun(INT32 *a, INT32 *b,    INT32 *ordera, INT32 *orderb)   {    if(*a<0)    {    if(*b<0)    {    return orderb[~*a] - orderb[~*b];    }else{
pike.git/src/array.c:1544:    }else{    if(*b<0)    {    return -1;    }else{    return ordera[*a] - ordera[*b];    }    }   }    - /* -  * merge two arrays and retain their order, this is done by arranging them + /** +  * Merge two arrays and retain their order. This is done by arranging them    * into ordered sets, merging them as sets and then rearranging the zipper    * before zipping the sets together.    */   PMOD_EXPORT struct array *merge_array_with_order(struct array *a,    struct array *b, INT32 op)   {    ONERROR r1,r2,r3,r4,r5;    INT32 *zipper;    struct array *tmpa,*tmpb,*ret;    INT32 *ordera, *orderb;
pike.git/src/array.c:1974:    } else {    sprintf(buf, "({ /* %ld elements */\n", (long)a->size);    }    my_strcat(buf);    describe_array_low(a,&doing,indent);    my_putchar('\n');    for(e=2; e<indent; e++) my_putchar(' ');    my_strcat("})");   }    + /** +  * Pops a number of arguments off of the stack an puts them in an array. +  * @argument args The number of arguments to aggregate. +  */   PMOD_EXPORT struct array *aggregate_array(INT32 args)   {    struct array *a;       a=allocate_array_no_init(args,0);    if (args) {    MEMCPY((char *)ITEM(a),(char *)(Pike_sp-args),args*sizeof(struct svalue));    array_fix_type_field (a);    Pike_sp-=args;    DO_IF_DMALLOC(while(args--) dmalloc_touch_svalue(Pike_sp + args));