cb2256 | 1995-10-11 | Fredrik Hübinette (Hubbe) | | |
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | ||| This file a part of Pike, and is copyright by Fredrik Hubinette
||| Pike is distributed as GPL (General Public License)
|
cb2256 | 1995-10-11 | Fredrik Hübinette (Hubbe) | | ||| See the files COPYING and DISCLAIMER for more information.
\*/
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | #include "global.h"
#include "svalue.h"
#include "array.h"
#include "object.h"
#include "las.h"
#include "stralloc.h"
#include "interpret.h"
#include "language.h"
#include "error.h"
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | #include "pike_types.h"
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | #include "fsort.h"
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | #include "builtin_functions.h"
|
9aa6fa | 1997-05-19 | Fredrik Hübinette (Hubbe) | | #include "pike_memory.h"
|
624d09 | 1996-02-24 | Fredrik Hübinette (Hubbe) | | #include "gc.h"
|
e3c6e1 | 1996-05-16 | Fredrik Hübinette (Hubbe) | | #include "main.h"
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
struct array empty_array=
{
1,
&empty_array,
&empty_array,
0,
0,
0,
|
fc3345 | 1997-10-02 | Fredrik Hübinette (Hubbe) | | 0,
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | };
|
2a129b | 1996-03-24 | Fredrik Hübinette (Hubbe) | | struct array *low_allocate_array(INT32 size,INT32 extra_space)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
struct array *v;
|
2a129b | 1996-03-24 | Fredrik Hübinette (Hubbe) | | INT32 e;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
99946c | 1996-02-17 | Fredrik Hübinette (Hubbe) | | if(size == 0)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
empty_array.refs++;
return &empty_array;
}
|
624d09 | 1996-02-24 | Fredrik Hübinette (Hubbe) | | GC_ALLOC();
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | v=(struct array *)malloc(sizeof(struct array)+
(size+extra_space-1)*sizeof(struct svalue));
if(!v)
error("Couldn't allocate array, out of memory.\n");
|
624d09 | 1996-02-24 | Fredrik Hübinette (Hubbe) | |
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | |
|
e3c6e1 | 1996-05-16 | Fredrik Hübinette (Hubbe) | | v->type_field=BIT_MIXED | BIT_UNFINISHED;
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | |
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | v->malloced_size=size+extra_space;
v->size=size;
v->refs=1;
v->prev=&empty_array;
v->next=empty_array.next;
empty_array.next=v;
v->next->prev=v;
|
2a129b | 1996-03-24 | Fredrik Hübinette (Hubbe) | | for(e=0;e<v->size;e++)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
2a129b | 1996-03-24 | Fredrik Hübinette (Hubbe) | | ITEM(v)[e].type=T_INT;
ITEM(v)[e].subtype=NUMBER_NUMBER;
ITEM(v)[e].u.integer=0;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
2a129b | 1996-03-24 | Fredrik Hübinette (Hubbe) | |
return v;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
static void array_free_no_free(struct array *v)
{
struct array *next,*prev;
next = v->next;
prev = v->prev;
v->prev->next=next;
v->next->prev=prev;
free((char *)v);
|
624d09 | 1996-02-24 | Fredrik Hübinette (Hubbe) | |
GC_FREE();
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
void really_free_array(struct array *v)
{
#ifdef DEBUG
if(v == & empty_array)
fatal("Tried to free the empty_array.\n");
#endif
|
ed36ce | 1996-08-12 | Fredrik Hübinette (Hubbe) | | #ifdef DEBUG
if(d_flag > 1) array_check_type_field(v);
#endif
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
ed36ce | 1996-08-12 | Fredrik Hübinette (Hubbe) | | v->refs++;
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | free_svalues(ITEM(v), v->size, v->type_field);
|
ed36ce | 1996-08-12 | Fredrik Hübinette (Hubbe) | | v->refs--;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | array_free_no_free(v);
}
|
2a3269 | 1998-01-31 | Fredrik Hübinette (Hubbe) | | void do_free_array(struct array *a)
{
free_array(a);
}
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
void array_index_no_free(struct svalue *s,struct array *v,INT32 index)
{
#ifdef DEBUG
if(index<0 || index>=v->size)
fatal("Illegal index in low level index routine.\n");
#endif
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | assign_svalue_no_free(s, ITEM(v) + index);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
void array_index(struct svalue *s,struct array *v,INT32 index)
{
#ifdef DEBUG
if(index<0 || index>=v->size)
fatal("Illegal index in low level index routine.\n");
#endif
v->refs++;
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | assign_svalue(s, ITEM(v) + index);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | free_array(v);
}
|
fc3345 | 1997-10-02 | Fredrik Hübinette (Hubbe) | | void simple_array_index_no_free(struct svalue *s,
struct array *a,struct svalue *ind)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
INT32 i;
|
de2a58 | 1997-09-28 | Fredrik Hübinette (Hubbe) | | switch(ind->type)
{
case T_INT:
i=ind->u.integer;
if(i<0) i+=a->size;
if(i<0 || i>=a->size) error("Index out of range.\n");
array_index_no_free(s,a,i);
break;
case T_STRING:
check_stack(4);
ref_push_array(a);
assign_svalue_no_free(sp++,ind);
f_column(2);
s[0]=sp[-1];
sp--;
break;
|
fc3345 | 1997-10-02 | Fredrik Hübinette (Hubbe) | |
|
de2a58 | 1997-09-28 | Fredrik Hübinette (Hubbe) | | default:
error("Index is not an integer.\n");
}
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
void array_free_index(struct array *v,INT32 index)
{
#ifdef DEBUG
if(index<0 || index>=v->size)
fatal("Illegal index in low level free index routine.\n");
#endif
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | free_svalue(ITEM(v) + index);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
void array_set_index(struct array *v,INT32 index, struct svalue *s)
{
#ifdef DEBUG
if(index<0 || index>v->size)
fatal("Illegal index in low level array set routine.\n");
#endif
v->refs++;
check_destructed(s);
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | |
|
e3c6e1 | 1996-05-16 | Fredrik Hübinette (Hubbe) | | v->type_field = (v->type_field & ~BIT_UNFINISHED) | 1 << s->type;
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | assign_svalue( ITEM(v) + index, s);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | free_array(v);
}
void simple_set_index(struct array *a,struct svalue *ind,struct svalue *s)
{
INT32 i;
if(ind->type != T_INT)
error("Index is not an integer.\n");
i=ind->u.integer;
if(i<0) i+=a->size;
if(i<0 || i>=a->size) error("Index out of range.\n");
array_set_index(a,i,s);
}
struct array *array_insert(struct array *v,struct svalue *s,INT32 index)
{
#ifdef DEBUG
if(index<0 || index>v->size)
fatal("Illegal index in low level insert routine.\n");
#endif
if(v->refs<=1 && v->malloced_size > v->size)
{
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | MEMMOVE((char *)(ITEM(v)+index+1),
(char *)(ITEM(v)+index),
(v->size-index) * sizeof(struct svalue));
ITEM(v)[index].type=T_INT;
|
f9771c | 1995-11-15 | Fredrik Hübinette (Hubbe) | | #ifdef __CHECKER__
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | ITEM(v)[index].subtype=0;
ITEM(v)[index].u.refs=0;
|
f9771c | 1995-11-15 | Fredrik Hübinette (Hubbe) | | #endif
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | v->size++;
}else{
struct array *ret;
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | ret=allocate_array_no_init(v->size+1, (v->size >> 3) + 1);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | ret->type_field = v->type_field;
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | MEMCPY(ITEM(ret), ITEM(v), sizeof(struct svalue) * index);
MEMCPY(ITEM(ret)+index+1, ITEM(v)+index, sizeof(struct svalue) * (v->size-index));
ITEM(ret)[index].type=T_INT;
|
f9771c | 1995-11-15 | Fredrik Hübinette (Hubbe) | | #ifdef __CHECKER__
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | ITEM(ret)[index].subtype=0;
ITEM(ret)[index].u.refs=0;
|
f9771c | 1995-11-15 | Fredrik Hübinette (Hubbe) | | #endif
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | v->size=0;
free_array(v);
v=ret;
}
array_set_index(v,index,s);
return v;
}
static struct array *resize_array(struct array *a, INT32 size)
{
if(a->size == size) return a;
if(size > a->size)
{
|
4ac838 | 1997-04-16 | Fredrik Hübinette (Hubbe) | |
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | if(a->malloced_size >= size)
{
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | for(;a->size < size; a->size++)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | ITEM(a)[a->size].type=T_INT;
ITEM(a)[a->size].subtype=NUMBER_NUMBER;
ITEM(a)[a->size].u.integer=0;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
e3c6e1 | 1996-05-16 | Fredrik Hübinette (Hubbe) | | a->type_field |= BIT_INT;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | return a;
}else{
struct array *ret;
|
4ac838 | 1997-04-16 | Fredrik Hübinette (Hubbe) | | ret=low_allocate_array(size, (size>>3)+1);
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | MEMCPY(ITEM(ret),ITEM(a),sizeof(struct svalue)*a->size);
|
e3c6e1 | 1996-05-16 | Fredrik Hübinette (Hubbe) | | ret->type_field = a->type_field | BIT_INT;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | a->size=0;
free_array(a);
return ret;
}
}else{
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | free_svalues(ITEM(a)+size, a->size - size, a->type_field);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | a->size = size;
return a;
}
}
struct array *array_shrink(struct array *v,INT32 size)
{
struct array *a;
#ifdef DEBUG
if(v->refs>2)
fatal("Array shrink on array with many references.\n");
if(size > v->size)
fatal("Illegal argument to array_shrink.\n");
#endif
if(size*2 < v->malloced_size + 4)
{
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | a=allocate_array_no_init(size,0);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | a->type_field = v->type_field;
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | free_svalues(ITEM(v) + size, v->size - size, v->type_field);
MEMCPY(ITEM(a), ITEM(v), size*sizeof(struct svalue));
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | v->size=0;
free_array(v);
return a;
}else{
|
99946c | 1996-02-17 | Fredrik Hübinette (Hubbe) | | free_svalues(ITEM(v) + size, v->size - size, v->type_field);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | v->size=size;
return v;
}
}
struct array *array_remove(struct array *v,INT32 index)
{
struct array *a;
#ifdef 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 )
{
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | a=allocate_array_no_init(v->size-1, 0);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | a->type_field = v->type_field;
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | if(index>0)
MEMCPY(ITEM(a), ITEM(v), index*sizeof(struct svalue));
if(v->size-index>1)
MEMCPY(ITEM(a)+index,
ITEM(v)+index+1,
(v->size-index-1)*sizeof(struct svalue));
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | v->size=0;
free_array(v);
return a;
}else{
if(v->size-index>1)
{
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | MEMMOVE((char *)(ITEM(v)+index),
(char *)(ITEM(v)+index+1),
(v->size-index-1)*sizeof(struct svalue));
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
v->size--;
return v;
}
}
INT32 array_search(struct array *v, struct svalue *s,INT32 start)
{
INT32 e;
#ifdef DEBUG
if(start<0)
fatal("Start of find_index is less than zero.\n");
#endif
check_destructed(s);
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | |
|
e3c6e1 | 1996-05-16 | Fredrik Hübinette (Hubbe) | | #ifdef DEBUG
|
c9fba6 | 1997-06-06 | Fredrik Hübinette (Hubbe) | | if(d_flag > 1) array_check_type_field(v);
|
e3c6e1 | 1996-05-16 | Fredrik Hübinette (Hubbe) | | #endif
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | if(v->type_field & (1 << s->type))
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
c9fba6 | 1997-06-06 | Fredrik Hübinette (Hubbe) | | if(start)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
c9fba6 | 1997-06-06 | Fredrik Hübinette (Hubbe) | | for(e=start;e<v->size;e++)
if(is_eq(ITEM(v)+e,s)) return e;
}else{
TYPE_FIELD t=0;
for(e=0;e<v->size;e++)
{
if(is_eq(ITEM(v)+e,s)) return e;
t |= 1<<ITEM(v)[e].type;
}
v->type_field=t;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
}
return -1;
}
struct array *slice_array(struct array *v,INT32 start,INT32 end)
{
struct array *a;
#ifdef DEBUG
if(start > end || end>v->size || start<0)
fatal("Illegal arguments to slice_array()\n");
#endif
if(start==0 && v->refs==1)
{
v->refs++;
return array_shrink(v,end);
}
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | a=allocate_array_no_init(end-start,0);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | a->type_field = v->type_field;
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | assign_svalues_no_free(ITEM(a), ITEM(v)+start, end-start, v->type_field);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
return a;
}
struct array *copy_array(struct array *v)
{
struct array *a;
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | a=allocate_array_no_init(v->size, 0);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | a->type_field = v->type_field;
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | assign_svalues_no_free(ITEM(a), ITEM(v), v->size, v->type_field);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
return a;
}
void check_array_for_destruct(struct array *v)
{
int e;
INT16 types;
types = 0;
|
e3c6e1 | 1996-05-16 | Fredrik Hübinette (Hubbe) | | #ifdef DEBUG
if(d_flag > 1) array_check_type_field(v);
#endif
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | if(v->type_field & (BIT_OBJECT | BIT_FUNCTION))
{
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | for(e=0; e<v->size; e++)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | if((ITEM(v)[e].type == T_OBJECT ||
|
bdb509 | 1996-09-25 | Fredrik Hübinette (Hubbe) | | (ITEM(v)[e].type == T_FUNCTION &&
ITEM(v)[e].subtype!=FUNCTION_BUILTIN)) &&
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | (!ITEM(v)[e].u.object->prog))
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | free_svalue(ITEM(v)+e);
ITEM(v)[e].type=T_INT;
ITEM(v)[e].subtype=NUMBER_DESTRUCTED;
ITEM(v)[e].u.integer=0;
types |= BIT_INT;
}else{
types |= 1<<ITEM(v)[e].type;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
}
v->type_field = types;
}
}
INT32 array_find_destructed_object(struct array *v)
{
INT32 e;
TYPE_FIELD types;
|
e3c6e1 | 1996-05-16 | Fredrik Hübinette (Hubbe) | | #ifdef DEBUG
if(d_flag > 1) array_check_type_field(v);
#endif
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | if(v->type_field & (BIT_OBJECT | BIT_FUNCTION))
{
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | types=0;
for(e=0; e<v->size; e++)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | if((ITEM(v)[e].type == T_OBJECT ||
|
bdb509 | 1996-09-25 | Fredrik Hübinette (Hubbe) | | (ITEM(v)[e].type == T_FUNCTION &&
ITEM(v)[e].subtype!=FUNCTION_BUILTIN)) &&
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | (!ITEM(v)[e].u.object->prog))
return e;
types |= 1<<ITEM(v)[e].type;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
v->type_field = types;
}
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | #ifdef DEBUG
if(d_flag > 1) array_check_type_field(v);
#endif
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | return -1;
}
static struct svalue *current_array_p;
static cmpfun current_cmpfun;
static int internal_cmpfun(INT32 *a,INT32 *b)
{
return current_cmpfun(current_array_p + *a, current_array_p + *b);
}
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | INT32 *get_order(struct array *v, cmpfun fun)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
INT32 e, *current_order;
if(!v->size) return 0;
current_cmpfun = fun;
current_order=(INT32 *)xalloc(v->size * sizeof(INT32));
for(e=0; e<v->size; e++) current_order[e]=e;
|
f4ec7c | 1997-09-07 | Fredrik Hübinette (Hubbe) | | if(current_array_p) free((char *)current_array_p);
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | current_array_p = ITEM(v);
current_cmpfun = fun;
fsort((char *)current_order,
v->size,
sizeof(INT32),
(fsortfun)internal_cmpfun);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
f4ec7c | 1997-09-07 | Fredrik Hübinette (Hubbe) | | current_array_p=0;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | return current_order;
}
static int set_svalue_cmpfun(struct svalue *a, struct svalue *b)
{
INT32 tmp;
|
9c6f7d | 1997-04-15 | Fredrik Hübinette (Hubbe) | | if((tmp=(a->type - b->type))) return tmp;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | 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:
|
5c8e89 | 1995-10-29 | Fredrik Hübinette (Hubbe) | | if(a->u.refs < b->u.refs) return -1;
if(a->u.refs > b->u.refs) return 1;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | return a->subtype - b->subtype;
|
5c8e89 | 1995-10-29 | Fredrik Hübinette (Hubbe) | | case T_INT:
|
71b72b | 1996-06-09 | Fredrik Hübinette (Hubbe) | | if(a->u.integer < b->u.integer) return -1;
if(a->u.integer > b->u.integer) return 1;
return 0;
|
5c8e89 | 1995-10-29 | Fredrik Hübinette (Hubbe) | |
default:
if(a->u.refs < b->u.refs) return -1;
if(a->u.refs > b->u.refs) return 1;
return 0;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
}
static int switch_svalue_cmpfun(struct svalue *a, struct svalue *b)
{
if(a->type != b->type) return a->type - b->type;
switch(a->type)
|
5c8e89 | 1995-10-29 | Fredrik Hübinette (Hubbe) | | {
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | case T_INT:
|
71b72b | 1996-06-09 | Fredrik Hübinette (Hubbe) | | if(a->u.integer < b->u.integer) return -1;
if(a->u.integer > b->u.integer) return 1;
return 0;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
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 my_strcmp(a->u.string, b->u.string);
default:
return set_svalue_cmpfun(a,b);
}
}
|
71b72b | 1996-06-09 | Fredrik Hübinette (Hubbe) | | static int alpha_svalue_cmpfun(struct svalue *a, struct svalue *b)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
f4ec7c | 1997-09-07 | Fredrik Hübinette (Hubbe) | | if(a->type == b->type)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
f4ec7c | 1997-09-07 | Fredrik Hübinette (Hubbe) | | 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 my_strcmp(a->u.string, b->u.string);
case T_ARRAY:
if(a==b) return 0;
if(!a->u.array->size) return -1;
if(!b->u.array->size) return 1;
return alpha_svalue_cmpfun(ITEM(a->u.array), ITEM(b->u.array));
default:
return set_svalue_cmpfun(a,b);
case T_OBJECT:
break;
}
}else{
if(a->type!=T_OBJECT && b->type!=T_OBJECT)
return a->type - b->type;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
f4ec7c | 1997-09-07 | Fredrik Hübinette (Hubbe) | | return is_gt(a,b);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
f5f7b1 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | void sort_array_destructively(struct array *v)
{
if(!v->size) return;
fsort((char *)ITEM(v),
v->size,
sizeof(struct svalue),
(fsortfun)alpha_svalue_cmpfun);
}
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | |
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | * return an 'order' suitable for making mappings and multisets
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | */
INT32 *get_set_order(struct array *a)
{
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | return get_order(a, set_svalue_cmpfun);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
INT32 *get_switch_order(struct array *a)
{
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | return get_order(a, switch_svalue_cmpfun);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
71b72b | 1996-06-09 | Fredrik Hübinette (Hubbe) | |
INT32 *get_alpha_order(struct array *a)
{
return get_order(a, alpha_svalue_cmpfun);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
static INT32 low_lookup(struct array *v,
struct svalue *s,
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | cmpfun fun)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
INT32 a,b,c;
int q;
|
f9771c | 1995-11-15 | Fredrik Hübinette (Hubbe) | |
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | a=0;
b=v->size;
while(b > a)
{
c=(a+b)/2;
q=fun(ITEM(v)+c,s);
if(q < 0)
a=c+1;
else if(q > 0)
b=c;
else
return c;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | if(a<v->size && fun(ITEM(v)+a,s)<0) a++;
return ~a;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
INT32 set_lookup(struct array *a, struct svalue *s)
{
|
e3c6e1 | 1996-05-16 | Fredrik Hübinette (Hubbe) | | #ifdef DEBUG
if(d_flag > 1) array_check_type_field(a);
#endif
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | |
|
99946c | 1996-02-17 | Fredrik Hübinette (Hubbe) | | if( (((2 << s->type) -1) & a->type_field) == 0)
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | return -1;
|
99946c | 1996-02-17 | Fredrik Hübinette (Hubbe) | | if( ((BIT_MIXED << s->type) & BIT_MIXED & a->type_field) == 0)
return ~a->size;
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | |
return low_lookup(a,s,set_svalue_cmpfun);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
INT32 switch_lookup(struct array *a, struct svalue *s)
{
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | |
|
e3c6e1 | 1996-05-16 | Fredrik Hübinette (Hubbe) | | #ifdef DEBUG
if(d_flag > 1) array_check_type_field(a);
#endif
|
99946c | 1996-02-17 | Fredrik Hübinette (Hubbe) | | if( (((2 << s->type) -1) & a->type_field) == 0)
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | return -1;
|
99946c | 1996-02-17 | Fredrik Hübinette (Hubbe) | | if( ((BIT_MIXED << s->type) & BIT_MIXED & a->type_field) == 0)
return ~a->size;
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | |
return low_lookup(a,s,switch_svalue_cmpfun);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
struct array *order_array(struct array *v, INT32 *order)
{
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | reorder((char *)ITEM(v),v->size,sizeof(struct svalue),order);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | return v;
}
struct array *reorder_and_copy_array(struct array *v, INT32 *order)
{
INT32 e;
struct array *ret;
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | ret=allocate_array_no_init(v->size, 0);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | ret->type_field = v->type_field;
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | for(e=0;e<v->size;e++)
assign_svalue_no_free(ITEM(ret)+e, ITEM(v)+order[e]);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
return ret;
}
void array_fix_type_field(struct array *v)
{
int e;
TYPE_FIELD t;
t=0;
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | for(e=0; e<v->size; e++) t |= 1 << ITEM(v)[e].type;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
afa365 | 1996-02-10 | Fredrik Hübinette (Hubbe) | | #ifdef DEBUG
if(t & ~(v->type_field))
fatal("Type field out of order!\n");
#endif
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | v->type_field = t;
}
|
e3c6e1 | 1996-05-16 | Fredrik Hübinette (Hubbe) | | #ifdef DEBUG
void array_check_type_field(struct array *v)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
e3c6e1 | 1996-05-16 | Fredrik Hübinette (Hubbe) | | int e;
TYPE_FIELD t;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
e3c6e1 | 1996-05-16 | Fredrik Hübinette (Hubbe) | | t=0;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
e3c6e1 | 1996-05-16 | Fredrik Hübinette (Hubbe) | | for(e=0; e<v->size; e++) t |= 1 << ITEM(v)[e].type;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
e3c6e1 | 1996-05-16 | Fredrik Hübinette (Hubbe) | | if(t & ~(v->type_field))
fatal("Type field out of order!\n");
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
e3c6e1 | 1996-05-16 | Fredrik Hübinette (Hubbe) | | #endif
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | struct array *compact_array(struct array *v) { return v; }
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
union anything *low_array_get_item_ptr(struct array *a,
INT32 ind,
TYPE_T t)
{
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | if(ITEM(a)[ind].type == t) return & (ITEM(a)[ind].u);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | return 0;
}
union anything *array_get_item_ptr(struct array *a,
struct svalue *ind,
TYPE_T t)
{
INT32 i;
if(ind->type != T_INT)
error("Index is not an integer.\n");
i=ind->u.integer;
if(i<0) i+=a->size;
if(i<0 || i>=a->size) error("Index out of range.\n");
return low_array_get_item_ptr(a,i,t);
}
INT32 * merge(struct array *a,struct array *b,INT32 opcode)
{
INT32 ap,bp,i,*ret,*ptr;
ap=bp=0;
|
e3c6e1 | 1996-05-16 | Fredrik Hübinette (Hubbe) | | #ifdef DEBUG
if(d_flag > 1)
{
array_check_type_field(a);
array_check_type_field(b);
}
#endif
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | if(!(a->type_field & b->type_field))
{
switch(opcode)
{
case OP_AND:
ret=(INT32 *)xalloc(sizeof(INT32));
*ret=0;
return ret;
case 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));
ptr++;
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | while(ap < a->size && bp < b->size)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | i=set_svalue_cmpfun(ITEM(a)+ap,ITEM(b)+bp);
if(i < 0)
i=opcode >> 8;
else if(i > 0)
i=opcode;
else
i=opcode >> 4;
if(i & OP_A) *(ptr++)=ap;
if(i & OP_B) *(ptr++)=~bp;
if(i & OP_SKIP_A) ap++;
if(i & OP_SKIP_B) bp++;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
if((opcode >> 8) & OP_A) while(ap<a->size) *(ptr++)=ap++;
if(opcode & OP_B) while(bp<b->size) *(ptr++)=~(bp++);
*ret=(ptr-ret-1);
return ret;
}
struct array *array_zip(struct array *a, struct array *b,INT32 *zipper)
{
INT32 size,e;
struct array *ret;
size=zipper[0];
zipper++;
|
99946c | 1996-02-17 | Fredrik Hübinette (Hubbe) | | ret=allocate_array_no_init(size,0);
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | for(e=0; e<size; e++)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | if(*zipper >= 0)
assign_svalue_no_free(ITEM(ret)+e, ITEM(a)+*zipper);
else
assign_svalue_no_free(ITEM(ret)+e, ITEM(b)+~*zipper);
zipper++;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
ret->type_field = a->type_field | b->type_field;
return ret;
}
struct array *add_arrays(struct svalue *argp, INT32 args)
{
INT32 e, size;
struct array *v;
|
99946c | 1996-02-17 | Fredrik Hübinette (Hubbe) | | for(size=e=0;e<args;e++)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | size+=argp[e].u.array->size;
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | if(args && argp[0].u.array->refs==1)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
e=argp[0].u.array->size;
v=resize_array(argp[0].u.array, size);
argp[0].type=T_INT;
size=e;
e=1;
}else{
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | v=allocate_array_no_init(size, 0);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | v->type_field=0;
e=size=0;
}
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | |
for(; e<args; e++)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | v->type_field|=argp[e].u.array->type_field;
assign_svalues_no_free(ITEM(v)+size,
ITEM(argp[e].u.array),
argp[e].u.array->size,
argp[e].u.array->type_field);
size+=argp[e].u.array->size;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
return v;
}
int array_equal_p(struct array *a, struct array *b, struct processing *p)
{
struct processing curr;
INT32 e;
if(a == b) return 1;
if(a->size != b->size) return 0;
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | if(!a->size) return 1;
|
e3c6e1 | 1996-05-16 | Fredrik Hübinette (Hubbe) | | #ifdef DEBUG
if(d_flag > 1)
{
array_check_type_field(a);
array_check_type_field(b);
}
#endif
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | |
|
1b89ad | 1997-10-10 | Fredrik Hübinette (Hubbe) | | if(!(a->type_field & b->type_field) &&
!( (a->type_field | b->type_field) & BIT_OBJECT ))
return 0;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
curr.pointer_a = a;
curr.pointer_b = b;
curr.next = p;
for( ;p ;p=p->next)
if(p->pointer_a == (void *)a && p->pointer_b == (void *)b)
return 1;
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | for(e=0; e<a->size; e++)
if(!low_is_equal(ITEM(a)+e, ITEM(b)+e, &curr))
return 0;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
return 1;
}
static INT32 *ordera=0, *orderb=0;
static int array_merge_fun(INT32 *a, INT32 *b)
{
if(*a<0)
{
if(*b<0)
{
return orderb[~*a] - orderb[~*b];
}else{
return -1;
}
}else{
if(*b<0)
{
return 1;
}else{
return ordera[*a] - ordera[*b];
}
}
}
struct array *merge_array_with_order(struct array *a, struct array *b,INT32 op)
{
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);
orderb=get_set_order(b);
tmpb=reorder_and_copy_array(b,orderb);
zipper=merge(tmpa,tmpb,op);
fsort((char *)(zipper+1),*zipper,sizeof(INT32),(fsortfun)array_merge_fun);
free((char *)ordera);
free((char *)orderb);
orderb=ordera=0;
ret=array_zip(tmpa,tmpb,zipper);
free_array(tmpa);
free_array(tmpb);
free((char *)zipper);
return ret;
}
struct array *merge_array_without_order(struct array *a,
struct array *b,
INT32 op)
{
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;
orderb=get_set_order(b);
tmpb=reorder_and_copy_array(b,orderb);
free((char *)orderb);
orderb=0;
zipper=merge(tmpa,tmpb,op);
ret=array_zip(tmpa,tmpb,zipper);
free_array(tmpa);
free_array(tmpb);
free((char *)zipper);
return ret;
}
struct array *subtract_arrays(struct array *a, struct array *b)
{
|
e3c6e1 | 1996-05-16 | Fredrik Hübinette (Hubbe) | | #ifdef DEBUG
if(d_flag > 1)
{
array_check_type_field(b);
}
#endif
|
c68c5a | 1996-12-01 | Fredrik Hübinette (Hubbe) | | check_array_for_destruct(a);
|
e3c6e1 | 1996-05-16 | Fredrik Hübinette (Hubbe) | |
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | if(a->type_field & b->type_field)
{
return merge_array_with_order(a, b, OP_SUB);
}else{
if(a->refs == 1)
{
a->refs++;
return a;
}
return slice_array(a,0,a->size);
}
}
struct array *and_arrays(struct array *a, struct array *b)
{
|
e3c6e1 | 1996-05-16 | Fredrik Hübinette (Hubbe) | | #ifdef DEBUG
if(d_flag > 1)
{
array_check_type_field(b);
}
#endif
|
c68c5a | 1996-12-01 | Fredrik Hübinette (Hubbe) | | check_array_for_destruct(a);
|
e3c6e1 | 1996-05-16 | Fredrik Hübinette (Hubbe) | |
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | if(a->type_field & b->type_field)
{
return merge_array_without_order(a, b, OP_AND);
}else{
|
99946c | 1996-02-17 | Fredrik Hübinette (Hubbe) | | return allocate_array_no_init(0,0);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
}
int check_that_array_is_constant(struct array *a)
{
array_fix_type_field(a);
|
e3c6e1 | 1996-05-16 | Fredrik Hübinette (Hubbe) | | if(a->type_field & (BIT_FUNCTION | BIT_OBJECT))
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | return 0;
return 1;
}
node *make_node_from_array(struct array *a)
{
struct svalue s;
INT32 e;
array_fix_type_field(a);
|
e3c6e1 | 1996-05-16 | Fredrik Hübinette (Hubbe) | | if(a->type_field == BIT_INT)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | for(e=0; e<a->size; e++)
if(ITEM(a)[e].u.integer != 0)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | break;
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | if(e == a->size)
{
|
3c0c28 | 1998-01-26 | Fredrik Hübinette (Hubbe) | | return mkefuncallnode("allocate",mkintnode(a->size));
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
}
if(check_that_array_is_constant(a))
{
s.type=T_ARRAY;
s.subtype=0;
s.u.array=a;
return mkconstantsvaluenode(&s);
}else{
node *ret=0;
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | for(e=0; e<a->size; e++)
ret=mknode(F_ARG_LIST,ret,mksvaluenode(ITEM(a)+e));
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | return mkefuncallnode("aggregate",ret);
}
}
void push_array_items(struct array *a)
{
|
f5f7b1 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | check_stack(a->size);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | check_array_for_destruct(a);
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | if(a->refs == 1)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | MEMCPY(sp,ITEM(a),sizeof(struct svalue)*a->size);
sp += a->size;
a->size=0;
free_array(a);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }else{
|
99946c | 1996-02-17 | Fredrik Hübinette (Hubbe) | | assign_svalues_no_free(sp, ITEM(a), a->size, a->type_field);
|
f5f7b1 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | sp += a->size;
free_array(a);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
}
void describe_array_low(struct array *a, struct processing *p, int indent)
{
INT32 e,d;
indent += 2;
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | |
for(e=0; e<a->size; e++)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | if(e) my_strcat(",\n");
for(d=0; d<indent; d++) my_putchar(' ');
describe_svalue(ITEM(a)+e,indent,p);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
}
void simple_describe_array(struct array *a)
{
char *s;
init_buf();
describe_array_low(a,0,0);
s=simple_free_buf();
fprintf(stderr,"({\n%s\n})\n",s);
free(s);
}
void describe_index(struct array *a,
int e,
struct processing *p,
int indent)
{
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | describe_svalue(ITEM(a)+e, indent, p);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
void describe_array(struct array *a,struct processing *p,int indent)
{
struct processing doing;
INT32 e;
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | char buf[60];
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | if(! a->size)
{
my_strcat("({ })");
return;
}
doing.next=p;
doing.pointer_a=(void *)a;
for(e=0;p;e++,p=p->next)
{
if(p->pointer_a == (void *)a)
{
|
f90e54 | 1995-08-17 | Fredrik Hübinette (Hubbe) | | sprintf(buf,"@%ld",(long)e);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | my_strcat(buf);
return;
}
}
|
f90e54 | 1995-08-17 | Fredrik Hübinette (Hubbe) | | sprintf(buf,"({ /* %ld elements */\n",(long)a->size);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | my_strcat(buf);
describe_array_low(a,&doing,indent);
my_putchar('\n');
for(e=2; e<indent; e++) my_putchar(' ');
my_strcat("})");
}
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | struct array *aggregate_array(INT32 args)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
struct array *a;
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | a=allocate_array_no_init(args,0);
MEMCPY((char *)ITEM(a),(char *)(sp-args),args*sizeof(struct svalue));
a->type_field=BIT_MIXED;
sp-=args;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | return a;
}
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | struct array *explode(struct pike_string *str,
struct pike_string *del)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
f5f7b1 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | INT32 e;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | struct array *ret;
char *s, *end, *tmp;
if(!del->len)
{
|
99946c | 1996-02-17 | Fredrik Hübinette (Hubbe) | | ret=allocate_array_no_init(str->len,0);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | for(e=0;e<str->len;e++)
|
99946c | 1996-02-17 | Fredrik Hübinette (Hubbe) | | {
ITEM(ret)[e].type=T_STRING;
ITEM(ret)[e].u.string=make_shared_binary_string(str->str+e,1);
}
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }else{
|
f5f7b1 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | struct mem_searcher searcher;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | s=str->str;
end=s+str->len;
|
018292 | 1997-10-06 | Fredrik Hübinette (Hubbe) | |
ret=allocate_array(10);
ret->size=0;
|
f5f7b1 | 1996-06-21 | Fredrik Hübinette (Hubbe) | |
init_memsearch(&searcher, del->str, del->len, str->len);
|
9c6f7d | 1997-04-15 | Fredrik Hübinette (Hubbe) | | while((tmp=memory_search(&searcher, s, end-s)))
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
018292 | 1997-10-06 | Fredrik Hübinette (Hubbe) | | if(ret->size == ret->malloced_size)
{
e=ret->size;
|
e1741a | 1997-10-06 | Fredrik Hübinette (Hubbe) | | ret=resize_array(ret, e * 2);
ret->size=e;
|
018292 | 1997-10-06 | Fredrik Hübinette (Hubbe) | | }
ITEM(ret)[ret->size].u.string=make_shared_binary_string(s, tmp-s);
ITEM(ret)[ret->size].type=T_STRING;
ret->size++;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | s=tmp+del->len;
}
|
018292 | 1997-10-06 | Fredrik Hübinette (Hubbe) | |
if(ret->size == ret->malloced_size)
|
e1741a | 1997-10-06 | Fredrik Hübinette (Hubbe) | | {
e=ret->size;
ret=resize_array(ret, e * 2);
ret->size=e;
}
|
018292 | 1997-10-06 | Fredrik Hübinette (Hubbe) | |
ITEM(ret)[ret->size].u.string=make_shared_binary_string(s, end-s);
ITEM(ret)[ret->size].type=T_STRING;
ret->size++;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
f5f7b1 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | ret->type_field=BIT_STRING;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | return ret;
}
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | struct pike_string *implode(struct array *a,struct pike_string *del)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
INT32 len,e, inited;
char *r;
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | struct pike_string *ret,*tmp;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
len=0;
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | for(e=0;e<a->size;e++)
if(ITEM(a)[e].type==T_STRING)
len+=ITEM(a)[e].u.string->len + del->len;
if(len) len-=del->len;
ret=begin_shared_string(len);
r=ret->str;
inited=0;
for(e=0;e<a->size;e++)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | if(ITEM(a)[e].type==T_STRING)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | if(inited)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | MEMCPY(r,del->str,del->len);
r+=del->len;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | inited=1;
tmp=ITEM(a)[e].u.string;
MEMCPY(r,tmp->str,tmp->len);
r+=tmp->len;
len++;
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
}
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | return end_shared_string(ret);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
struct array *copy_array_recursively(struct array *a,struct processing *p)
{
struct processing doing;
struct array *ret;
doing.next=p;
doing.pointer_a=(void *)a;
for(;p;p=p->next)
{
if(p->pointer_a == (void *)a)
{
ret=(struct array *)p->pointer_b;
ret->refs++;
return ret;
}
}
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | ret=allocate_array_no_init(a->size,0);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | doing.pointer_b=(void *)ret;
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | |
copy_svalues_recursively_no_free(ITEM(ret),ITEM(a),a->size,&doing);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | return ret;
}
void apply_array(struct array *a, INT32 args)
{
INT32 e;
struct array *ret;
|
f5f7b1 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | INT32 argp;
argp=sp-args - evaluator_stack;
check_stack(a->size + args + 1);
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | for(e=0;e<a->size;e++)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
f5f7b1 | 1996-06-21 | Fredrik Hübinette (Hubbe) | | assign_svalues_no_free(sp,evaluator_stack+argp,args,BIT_MIXED);
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | sp+=args;
apply_svalue(ITEM(a)+e,args);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
99946c | 1996-02-17 | Fredrik Hübinette (Hubbe) | | ret=aggregate_array(a->size);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | pop_n_elems(args);
push_array(ret);
}
struct array *reverse_array(struct array *a)
{
INT32 e;
struct array *ret;
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | |
ret=allocate_array_no_init(a->size,0);
for(e=0;e<a->size;e++)
assign_svalue_no_free(ITEM(ret)+e,ITEM(a)+a->size+~e);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | return ret;
}
void array_replace(struct array *a,
struct svalue *from,
struct svalue *to)
{
INT32 i = -1;
while((i=array_search(a,from,i+1)) >= 0) array_set_index(a,i,to);
}
#ifdef DEBUG
|
624d09 | 1996-02-24 | Fredrik Hübinette (Hubbe) | | void check_array(struct array *a)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
INT32 e;
if(a->next->prev != a)
fatal("Array check: a->next->prev != a\n");
if(a->size > a->malloced_size)
fatal("Array is larger than malloced block!\n");
if(a->refs <=0 )
fatal("Array has zero refs.\n");
|
624d09 | 1996-02-24 | Fredrik Hübinette (Hubbe) | | for(e=0;e<a->size;e++)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
624d09 | 1996-02-24 | Fredrik Hübinette (Hubbe) | | if(! ( (1 << ITEM(a)[e].type) & (a->type_field) ))
fatal("Type field lies.\n");
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | |
|
624d09 | 1996-02-24 | Fredrik Hübinette (Hubbe) | | check_svalue(ITEM(a)+e);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
}
|
be478c | 1997-08-30 | Henrik Grubbström (Grubba) | | void check_all_arrays(void)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
struct array *a;
a=&empty_array;
do
{
|
624d09 | 1996-02-24 | Fredrik Hübinette (Hubbe) | | check_array(a);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
a=a->next;
if(!a)
fatal("Null pointer in array list.\n");
} while (a != & empty_array);
|
fc7695 | 1996-02-17 | Fredrik Hübinette (Hubbe) | | }
#endif /* DEBUG */
|
c94c37 | 1996-03-28 | Fredrik Hübinette (Hubbe) | | void gc_mark_array_as_referenced(struct array *a)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
c94c37 | 1996-03-28 | Fredrik Hübinette (Hubbe) | | if(gc_mark(a))
if(a->type_field & BIT_COMPLEX)
gc_mark_svalues(ITEM(a), a->size);
|
624d09 | 1996-02-24 | Fredrik Hübinette (Hubbe) | | }
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | |
|
be478c | 1997-08-30 | Henrik Grubbström (Grubba) | | void gc_check_all_arrays(void)
|
624d09 | 1996-02-24 | Fredrik Hübinette (Hubbe) | | {
|
c94c37 | 1996-03-28 | Fredrik Hübinette (Hubbe) | | struct array *a;
|
624d09 | 1996-02-24 | Fredrik Hübinette (Hubbe) | | a=&empty_array;
do
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
e3c6e1 | 1996-05-16 | Fredrik Hübinette (Hubbe) | | #ifdef DEBUG
if(d_flag > 1) array_check_type_field(a);
#endif
|
c94c37 | 1996-03-28 | Fredrik Hübinette (Hubbe) | | if(a->type_field & BIT_COMPLEX)
|
e3c6e1 | 1996-05-16 | Fredrik Hübinette (Hubbe) | | {
TYPE_FIELD t;
|
f6d017 | 1997-10-15 | Fredrik Hübinette (Hubbe) | | t=debug_gc_check_svalues(ITEM(a), a->size, T_ARRAY, a);
|
e3c6e1 | 1996-05-16 | Fredrik Hübinette (Hubbe) | |
|
ed36ce | 1996-08-12 | Fredrik Hübinette (Hubbe) | | * Actually we just need beter primitives for building arrays.
|
e3c6e1 | 1996-05-16 | Fredrik Hübinette (Hubbe) | | */
if(!(a->type_field & BIT_UNFINISHED) || a->refs!=1)
a->type_field = t;
|
ed36ce | 1996-08-12 | Fredrik Hübinette (Hubbe) | | else
a->type_field |= t;
|
e3c6e1 | 1996-05-16 | Fredrik Hübinette (Hubbe) | | }
|
c94c37 | 1996-03-28 | Fredrik Hübinette (Hubbe) | |
a=a->next;
|
624d09 | 1996-02-24 | Fredrik Hübinette (Hubbe) | | } while (a != & empty_array);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
c94c37 | 1996-03-28 | Fredrik Hübinette (Hubbe) | |
|
be478c | 1997-08-30 | Henrik Grubbström (Grubba) | | void gc_mark_all_arrays(void)
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
struct array *a;
a=&empty_array;
do
{
|
c94c37 | 1996-03-28 | Fredrik Hübinette (Hubbe) | | if(gc_is_referenced(a))
gc_mark_array_as_referenced(a);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | a=a->next;
|
624d09 | 1996-02-24 | Fredrik Hübinette (Hubbe) | | } while (a != & empty_array);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
|
be478c | 1997-08-30 | Henrik Grubbström (Grubba) | | void gc_free_all_unreferenced_arrays(void)
|
c94c37 | 1996-03-28 | Fredrik Hübinette (Hubbe) | | {
struct array *a,*next;
a=&empty_array;
do
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | {
|
c94c37 | 1996-03-28 | Fredrik Hübinette (Hubbe) | | if(gc_do_free(a))
{
a->refs++;
free_svalues(ITEM(a), a->size, a->type_field);
a->size=0;
if(!(next=a->next))
fatal("Null pointer in array list.\n");
free_array(a);
a=next;
}else{
a=a->next;
}
} while (a != & empty_array);
}
|
624d09 | 1996-02-24 | Fredrik Hübinette (Hubbe) | |
|
ed36ce | 1996-08-12 | Fredrik Hübinette (Hubbe) | | #ifdef DEBUG
void debug_dump_type_field(TYPE_FIELD t)
{
int e;
|
c330a9 | 1997-10-14 | Fredrik Hübinette (Hubbe) | | for(e=0;e<=MAX_TYPE;e++)
|
ed36ce | 1996-08-12 | Fredrik Hübinette (Hubbe) | | if(t & (1<<e))
fprintf(stderr," %s",get_name_of_type(e));
for(;e<16;e++)
if(t & (1<<e))
fprintf(stderr," <%d>",e);
}
void debug_dump_array(struct array *a)
{
|
2fc087 | 1998-01-30 | Henrik Grubbström (Grubba) | | fprintf(stderr,"Location=%p Refs=%d, next=%p, prev=%p, size=%d, malloced_size=%d\n",
|
864d3c | 1998-01-29 | Fredrik Hübinette (Hubbe) | | a,
|
ed36ce | 1996-08-12 | Fredrik Hübinette (Hubbe) | | a->refs,
a->next,
a->prev,
a->size,
a->malloced_size);
fprintf(stderr,"Type field = ");
debug_dump_type_field(a->type_field);
fprintf(stderr,"\n");
simple_describe_array(a);
|
5267b7 | 1995-08-09 | Fredrik Hübinette (Hubbe) | | }
#endif
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | |
|
be478c | 1997-08-30 | Henrik Grubbström (Grubba) | | void zap_all_arrays(void)
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | {
struct array *a,*next;
a=&empty_array;
do
{
|
61e9a0 | 1998-01-25 | Fredrik Hübinette (Hubbe) | |
#if defined(DEBUG) && defined(DEBUG_MALLOC)
|
3c0c28 | 1998-01-26 | Fredrik Hübinette (Hubbe) | | if(verbose_debug_exit && a!=&empty_array)
|
61e9a0 | 1998-01-25 | Fredrik Hübinette (Hubbe) | | debug_dump_array(a);
#endif
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | a->refs++;
free_svalues(ITEM(a), a->size, a->type_field);
a->size=0;
if(!(next=a->next))
fatal("Null pointer in array list.\n");
|
cbd60b | 1996-12-04 | Fredrik Hübinette (Hubbe) | |
|
06983f | 1996-09-22 | Fredrik Hübinette (Hubbe) | | a=next;
} while (a != & empty_array);
}
|
c3c703 | 1996-12-04 | Fredrik Hübinette (Hubbe) | |
|
61e9a0 | 1998-01-25 | Fredrik Hübinette (Hubbe) | |
|
c3c703 | 1996-12-04 | Fredrik Hübinette (Hubbe) | | void count_memory_in_arrays(INT32 *num_, INT32 *size_)
{
INT32 num=0, size=0;
struct array *m;
for(m=empty_array.next;m!=&empty_array;m=m->next)
{
num++;
size+=sizeof(struct array)+
sizeof(struct svalue) * (m->malloced_size - 1);
}
*num_=num;
*size_=size;
}
|
f5466b | 1997-02-18 | Fredrik Hübinette (Hubbe) | |
struct array *explode_array(struct array *a, struct array *b)
{
INT32 e,d,q,start;
struct array *tmp;
q=start=0;
push_array(a);
a->refs++;
if(b->size)
{
|
a2a908 | 1997-02-19 | Fredrik Hübinette (Hubbe) | | for(e=0;e<=a->size - b->size;e++)
|
f5466b | 1997-02-18 | Fredrik Hübinette (Hubbe) | | {
for(d=0;d<b->size;d++)
{
if(!is_eq(ITEM(a)+(e+d),ITEM(b)+d))
break;
}
if(d==b->size)
{
check_stack(1);
push_array(slice_array(a, start, e));
q++;
e+=b->size-1;
start=e+1;
}
}
check_stack(1);
push_array(slice_array(a, start, a->size));
q++;
}else{
check_stack(a->size);
for(e=0;e<a->size;e++) push_array(slice_array(a, e, e+1));
q=a->size;
}
tmp=aggregate_array(q);
if(tmp->size) tmp->type_field=BIT_ARRAY;
pop_stack();
return tmp;
}
struct array *implode_array(struct array *a, struct array *b)
{
INT32 e,size;
struct array *ret;
size=0;
for(e=0;e<a->size;e++)
{
if(ITEM(a)[e].type!=T_ARRAY)
error("Implode array contains non-arrays.\n");
size+=ITEM(a)[e].u.array->size;
}
ret=allocate_array((a->size -1) * b->size + size);
size=0;
ret->type_field=0;
for(e=0;e<a->size;e++)
{
if(e)
{
ret->type_field|=b->type_field;
assign_svalues_no_free(ITEM(ret)+size,
ITEM(b),
b->size,
b->type_field);
size+=b->size;
}
ret->type_field|=ITEM(a)[e].u.array->type_field;
assign_svalues_no_free(ITEM(ret)+size,
ITEM(ITEM(a)[e].u.array),
ITEM(a)[e].u.array->size,
ITEM(a)[e].u.array->type_field);
size+=ITEM(a)[e].u.array->size;
}
#ifdef DEBUG
if(size != ret->size)
fatal("Implode_array failed miserably\n");
#endif
return ret;
}
|