pike.git / src / array.c

version» Context lines:

pike.git/src/array.c:16:   #include "pike_types.h"   #include "fsort.h"   #include "builtin_functions.h"   #include "pike_memory.h"   #include "gc.h"   #include "main.h"   #include "security.h"   #include "stuff.h"   #include "bignum.h"    - RCSID("$Id: array.c,v 1.92 2000/10/20 10:05:40 grubba Exp $"); + RCSID("$Id: array.c,v 1.93 2000/11/08 20:03:45 hubbe Exp $");      PMOD_EXPORT struct array empty_array=   {    1, /* Never free */   #ifdef PIKE_SECURITY    0,   #endif    &empty_array, /* Next */    &empty_array, /* previous (circular) */    0, /* Size = 0 */
pike.git/src/array.c:397:   }      /*    * 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(v->refs>1) -  fatal("Array remove on array with many references.\n"); -  +     if(index<0 || index >= v->size)    fatal("Illegal argument to array_remove.\n");   #endif       array_free_index(v, index);    if(v->size!=1 &&    v->size*2 + 4 < v->malloced_size ) /* Should we realloc it? */    {    a=allocate_array_no_init(v->size-1, 0);    a->type_field = v->type_field;
pike.git/src/array.c:653:       get_order_fsort(current_order,    current_order+v->size-1,    fun,    ITEM(v));       UNSET_ONERROR(tmp);    return current_order;   }    - static int set_svalue_cmpfun(struct svalue *a, struct svalue *b) + static INLINE int set_svalue_cmpfun(struct svalue *a, struct svalue *b)   { -  INT32 tmp; -  if((tmp=(a->type - b->type))) return tmp; +  INT32 def,fun; +  if(a->type == b->type) +  {    switch(a->type)    {    case T_FLOAT:    if(a->u.float_number < b->u.float_number) return -1;    if(a->u.float_number > b->u.float_number) return 1;    return 0;       case T_FUNCTION:    if(a->u.refs < b->u.refs) return -1;    if(a->u.refs > b->u.refs) return 1;
pike.git/src/array.c:678:       case T_INT:    if(a->u.integer < b->u.integer) return -1;    if(a->u.integer > b->u.integer) return 1;    return 0;       default:    if(a->u.refs < b->u.refs) return -1;    if(a->u.refs > b->u.refs) return 1;    return 0; +  +  case T_OBJECT: +  if(a->u.object == b->u.object) return 0; +  if(a->u.refs < b->u.refs) { def=-1; break; } +  if(a->u.refs > b->u.refs) { def=1; break; } +  def=0; +  break;    } -  +  }else{ +  def=a->type - b->type;    }    -  +  if(a->type == T_OBJECT && a->u.object->prog && +  FIND_LFUN(a->u.object->prog,LFUN_LT) != -1) +  { +  push_svalue(b); +  apply_lfun(a->u.object,LFUN_LT,1); +  if(!IS_ZERO(sp-1)) +  { +  pop_stack(); +  return -1; +  }else{ +  pop_stack(); +  } +  +  push_svalue(b); +  apply_lfun(a->u.object,LFUN_GT,1); +  if(!IS_ZERO(sp-1)) +  { +  pop_stack(); +  return 1; +  }else{ +  pop_stack(); +  } +  return 0; +  } +  +  if(b->type == T_OBJECT && b->u.object->prog && +  FIND_LFUN(b->u.object->prog,LFUN_LT) != -1) +  { +  push_svalue(a); +  apply_lfun(b->u.object,LFUN_LT,1); +  if(!IS_ZERO(sp-1)) +  { +  pop_stack(); +  return 1; +  }else{ +  pop_stack(); +  } +  +  push_svalue(a); +  apply_lfun(b->u.object,LFUN_GT,1); +  if(!IS_ZERO(sp-1)) +  { +  pop_stack(); +  return -1; +  }else{ +  pop_stack(); +  } +  return 0; +  } +  +  return def; + } +    static int switch_svalue_cmpfun(struct svalue *a, struct svalue *b)   { -  if(a->type != b->type) return a->type - b->type; +  if(a->type == b->type) +  {    switch(a->type)    {    case T_INT:    if(a->u.integer < b->u.integer) return -1;    if(a->u.integer > b->u.integer) return 1;    return 0;       case T_FLOAT:    if(a->u.float_number < b->u.float_number) return -1;    if(a->u.float_number > b->u.float_number) return 1;    return 0;       case T_STRING:    return DO_NOT_WARN((int)my_quick_strcmp(a->u.string, b->u.string));       default:    return set_svalue_cmpfun(a,b);    } -  +  }else{ +  return a->type - b->type;    } -  + }      static int alpha_svalue_cmpfun(struct svalue *a, struct svalue *b)   {    if(a->type == b->type)    {    switch(a->type)    {    case T_INT:    if(a->u.integer < b->u.integer) return -1;    if(a->u.integer > b->u.integer) return 1;
pike.git/src/array.c:819:    }    if(a<v->size && fun(ITEM(v)+a,s)<0) a++;    return ~a;   }      INT32 set_lookup(struct array *a, struct svalue *s)   {   #ifdef PIKE_DEBUG    if(d_flag > 1) array_check_type_field(a);   #endif +  +  /* objects may have `< `> operators, evil stuff! */ +  if(s->type != T_OBJECT && !(a->flags & BIT_OBJECT)) +  {    /* face it, it's not there */    if( (((2 << s->type) -1) & a->type_field) == 0)    return -1;       /* 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,set_svalue_cmpfun);   }      INT32 switch_lookup(struct array *a, struct svalue *s)   {    /* face it, it's not there */   #ifdef PIKE_DEBUG    if(d_flag > 1) array_check_type_field(a);   #endif -  +  /* objects may have `< `> operators, evil stuff! */ +  if(s->type != T_OBJECT && !(a->flags & BIT_OBJECT)) +  {    if( (((2 << s->type) -1) & a->type_field) == 0)    return -1;       /* 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 specifyed by 'order'    */   PMOD_EXPORT struct array *order_array(struct array *v, INT32 *order)   {
pike.git/src/array.c:975:      /*    * 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 rest is n >= 0 for a[ 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)    {    array_check_type_field(a);    array_check_type_field(b);    }   #endif
pike.git/src/array.c:1004:       case PIKE_ARRAY_OP_SUB:    ptr=ret=(INT32 *)xalloc(sizeof(INT32)*(a->size+1));    *(ptr++)=a->size;    for(i=0;i<a->size;i++) *(ptr++)=i;    return ret;    }    }       ptr=ret=(INT32 *)xalloc(sizeof(INT32)*(a->size + b->size + 1)); +  SET_ONERROR(r, free,ret);    ptr++;       while(ap < a->size && bp < b->size)    {    i=set_svalue_cmpfun(ITEM(a)+ap,ITEM(b)+bp);    if(i < 0)    i=opcode >> 8;    else if(i > 0)    i=opcode;    else
pike.git/src/array.c:1027:    if(i & PIKE_ARRAY_OP_B) *(ptr++)=~bp;    if(i & PIKE_ARRAY_OP_SKIP_A) ap++;    if(i & PIKE_ARRAY_OP_SKIP_B) bp++;    }       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    */   PMOD_EXPORT struct array *array_zip(struct array *a, struct array *b,INT32 *zipper)   {    INT32 size,e;
pike.git/src/array.c:1162:            /*    * 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;    INT32 *zipper;    struct array *tmpa,*tmpb,*ret;       if(ordera) { free((char *)ordera); ordera=0; }    if(orderb) { free((char *)orderb); orderb=0; }       ordera=get_set_order(a); -  +  orderb=get_set_order(b); +     tmpa=reorder_and_copy_array(a,ordera); -  +  SET_ONERROR(r1,do_free_array,tmpa);    -  orderb=get_set_order(b); +     tmpb=reorder_and_copy_array(b,orderb); -  +  SET_ONERROR(r2,do_free_array,tmpb);       zipper=merge(tmpa,tmpb,op); -  +  SET_ONERROR(r3,free,zipper);       fsort((char *)(zipper+1),*zipper,sizeof(INT32),(fsortfun)array_merge_fun); -  free((char *)ordera); +     free((char *)orderb); -  +  free((char *)ordera);    orderb=ordera=0; -  +     ret=array_zip(tmpa,tmpb,zipper); -  free_array(tmpa); -  free_array(tmpb); -  free((char *)zipper); +  UNSET_ONERROR(r3); free((char *)zipper); +  UNSET_ONERROR(r2); free_array(tmpb); +  UNSET_ONERROR(r1); free_array(tmpa);    return ret;   }         #define CMP(X,Y) set_svalue_cmpfun(X,Y)   #define TYPE struct svalue   #define ID set_sort_svalues   #include "fsort_template.h"   #undef CMP   #undef TYPE   #undef ID         /*    * 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_without_order2(struct array *a, struct array *b,INT32 op)   { -  +  ONERROR r1,r2,r3,r4,r5;    INT32 ap,bp,i;    struct svalue *arra,*arrb;    struct array *ret;      #ifdef PIKE_DEBUG    if(d_flag > 1)    {    array_check_type_field(a);    array_check_type_field(b);    }   #endif    -  +  SET_ONERROR(r1,do_free_array,a); +  SET_ONERROR(r2,do_free_array,b); +     if(a->refs==1 || !a->size)    {    arra=ITEM(a);    }else{    arra=(struct svalue *)xalloc(a->size*sizeof(struct svalue));    MEMCPY(arra,ITEM(a),a->size*sizeof(struct svalue)); -  +  SET_ONERROR(r3,free,arra);    }       if(b->refs==1 || !b->size)    {    arrb=ITEM(b);    }else{    arrb=(struct svalue *)xalloc(b->size*sizeof(struct svalue));    MEMCPY(arrb,ITEM(b),b->size*sizeof(struct svalue)); -  +  SET_ONERROR(r4,free,arrb);    }       set_sort_svalues(arra,arra+a->size-1);    set_sort_svalues(arrb,arrb+b->size-1);       ret=low_allocate_array(0,32); -  +  SET_ONERROR(r5,do_free_array,ret);    ap=bp=0;       while(ap < a->size && bp < b->size)    {    i=set_svalue_cmpfun(arra+ap,arrb+bp);    if(i < 0)    i=op >> 8;    else if(i > 0)    i=op;    else
pike.git/src/array.c:1262:    }       if((op >> 8) & PIKE_ARRAY_OP_A)    while(ap<a->size)    ret=append_array(ret,arra + ap++);       if(op & PIKE_ARRAY_OP_B)    while(bp<b->size)    ret=append_array(ret,arrb + bp++);    -  if(arra != ITEM(a)) free((char *)arra); -  if(arrb != ITEM(b)) free((char *)arrb); +  UNSET_ONERROR(r5);    -  free_array(a); +  if(arrb != ITEM(b)) +  { +  UNSET_ONERROR(r4); +  free((char *)arrb); +  } +  +  if(arra != ITEM(a)) +  { +  UNSET_ONERROR(r3); +  free((char *)arra); +  } +  +  UNSET_ONERROR(r2);    free_array(b);    -  +  UNSET_ONERROR(r1); +  free_array(a); +     return ret;   }         /* merge two arrays without paying attention to the order    * the elements has presently    */   PMOD_EXPORT struct array *merge_array_without_order(struct array *a,    struct array *b,    INT32 op)   {   #if 0 -  +  /* FIXME: If this routine is ever reinstated, it has to be +  * fixed to use ONERROR +  */    INT32 *zipper;    struct array *tmpa,*tmpb,*ret;       if(ordera) { free((char *)ordera); ordera=0; }    if(orderb) { free((char *)orderb); orderb=0; }       ordera=get_set_order(a);    tmpa=reorder_and_copy_array(a,ordera);    free((char *)ordera);    ordera=0;
pike.git/src/array.c:1311: Inside #if 0
   return ret;      #else    add_ref(a);    add_ref(b);    return merge_array_without_order2(a,b,op);   #endif   }      /* subtract an array from another */ +    PMOD_EXPORT struct array *subtract_arrays(struct array *a, struct array *b)   {   #ifdef PIKE_DEBUG    if(d_flag > 1)    {    array_check_type_field(b);    }   #endif    check_array_for_destruct(a);