blob: 56c8348104f3b2cd641403e54634a4e4e1d721dc [file] [log] [blame]
/* $Header$
*
* Copyright (c) 1989, Larry Wall
*
* You may distribute under the terms of the GNU General Public License
* as specified in the README file that comes with the perl 3.0 kit.
*
* $Log$
* Revision 1.2 2004/09/01 14:33:24 criswell
* Migrating test suite out of the source tree.
*
* Revision 1.1 2004/02/17 22:21:15 criswell
* Initial commit of the perl Malloc Benchmark. I've cheated a little by
* generating the yacc output files and committing them directly, but it was
* easier than disabling the Bison Voodoo that gets executed by default.
*
* Revision 4.0 91/03/20 01:03:32 lwall
* 4.0 baseline.
*
*/
#include "EXTERN.h"
#include "perl.h"
STR *
afetch(ar,key,lval)
register ARRAY *ar;
int key;
int lval;
{
STR *str;
if (key < 0 || key > ar->ary_fill) {
if (lval && key >= 0) {
if (ar->ary_flags & ARF_REAL)
str = Str_new(5,0);
else
str = str_mortal(&str_undef);
(void)astore(ar,key,str);
return str;
}
else
return &str_undef;
}
if (!ar->ary_array[key]) {
if (lval) {
str = Str_new(6,0);
(void)astore(ar,key,str);
return str;
}
return &str_undef;
}
return ar->ary_array[key];
}
bool
astore(ar,key,val)
register ARRAY *ar;
int key;
STR *val;
{
int retval;
if (key < 0)
return FALSE;
if (key > ar->ary_max) {
int newmax;
if (ar->ary_alloc != ar->ary_array) {
retval = ar->ary_array - ar->ary_alloc;
Copy(ar->ary_array, ar->ary_alloc, ar->ary_max+1, STR*);
Zero(ar->ary_alloc+ar->ary_max+1, retval, STR*);
ar->ary_max += retval;
ar->ary_array -= retval;
if (key > ar->ary_max - 10) {
newmax = key + ar->ary_max;
goto resize;
}
}
else {
if (ar->ary_alloc) {
newmax = key + ar->ary_max / 5;
resize:
Renew(ar->ary_alloc,newmax+1, STR*);
Zero(&ar->ary_alloc[ar->ary_max+1], newmax - ar->ary_max, STR*);
}
else {
newmax = key < 4 ? 4 : key;
Newz(2,ar->ary_alloc, newmax+1, STR*);
}
ar->ary_array = ar->ary_alloc;
ar->ary_max = newmax;
}
}
if ((ar->ary_flags & ARF_REAL) && ar->ary_fill < key) {
while (++ar->ary_fill < key) {
if (ar->ary_array[ar->ary_fill] != Nullstr) {
str_free(ar->ary_array[ar->ary_fill]);
ar->ary_array[ar->ary_fill] = Nullstr;
}
}
}
retval = (ar->ary_array[key] != Nullstr);
if (retval && (ar->ary_flags & ARF_REAL))
str_free(ar->ary_array[key]);
ar->ary_array[key] = val;
return retval;
}
ARRAY *
anew(stab)
STAB *stab;
{
register ARRAY *ar;
New(1,ar,1,ARRAY);
ar->ary_magic = Str_new(7,0);
ar->ary_alloc = ar->ary_array = 0;
str_magic(ar->ary_magic, stab, '#', Nullch, 0);
ar->ary_max = ar->ary_fill = -1;
ar->ary_flags = ARF_REAL;
return ar;
}
ARRAY *
afake(stab,size,strp)
STAB *stab;
register int size;
register STR **strp;
{
register ARRAY *ar;
New(3,ar,1,ARRAY);
New(4,ar->ary_alloc,size+1,STR*);
Copy(strp,ar->ary_alloc,size,STR*);
ar->ary_array = ar->ary_alloc;
ar->ary_magic = Str_new(8,0);
str_magic(ar->ary_magic, stab, '#', Nullch, 0);
ar->ary_fill = size - 1;
ar->ary_max = size - 1;
ar->ary_flags = 0;
while (size--) {
(*strp++)->str_pok &= ~SP_TEMP;
}
return ar;
}
void
aclear(ar)
register ARRAY *ar;
{
register int key;
if (!ar || !(ar->ary_flags & ARF_REAL) || ar->ary_max < 0)
return;
if (key = ar->ary_array - ar->ary_alloc) {
ar->ary_max += key;
ar->ary_array -= key;
}
for (key = 0; key <= ar->ary_max; key++)
str_free(ar->ary_array[key]);
ar->ary_fill = -1;
Zero(ar->ary_array, ar->ary_max+1, STR*);
}
void
afree(ar)
register ARRAY *ar;
{
register int key;
if (!ar)
return;
if (key = ar->ary_array - ar->ary_alloc) {
ar->ary_max += key;
ar->ary_array -= key;
}
if (ar->ary_flags & ARF_REAL) {
for (key = 0; key <= ar->ary_max; key++)
str_free(ar->ary_array[key]);
}
str_free(ar->ary_magic);
Safefree(ar->ary_alloc);
Safefree(ar);
}
bool
apush(ar,val)
register ARRAY *ar;
STR *val;
{
return astore(ar,++(ar->ary_fill),val);
}
STR *
apop(ar)
register ARRAY *ar;
{
STR *retval;
if (ar->ary_fill < 0)
return Nullstr;
retval = ar->ary_array[ar->ary_fill];
ar->ary_array[ar->ary_fill--] = Nullstr;
return retval;
}
aunshift(ar,num)
register ARRAY *ar;
register int num;
{
register int i;
register STR **sstr,**dstr;
if (num <= 0)
return;
if (ar->ary_array - ar->ary_alloc >= num) {
ar->ary_max += num;
ar->ary_fill += num;
while (num--)
*--ar->ary_array = Nullstr;
}
else {
(void)astore(ar,ar->ary_fill+num,(STR*)0); /* maybe extend array */
dstr = ar->ary_array + ar->ary_fill;
sstr = dstr - num;
#ifdef BUGGY_MSC5
# pragma loop_opt(off) /* don't loop-optimize the following code */
#endif /* BUGGY_MSC5 */
for (i = ar->ary_fill; i >= 0; i--) {
*dstr-- = *sstr--;
#ifdef BUGGY_MSC5
# pragma loop_opt() /* loop-optimization back to command-line setting */
#endif /* BUGGY_MSC5 */
}
Zero(ar->ary_array, num, STR*);
}
}
STR *
ashift(ar)
register ARRAY *ar;
{
STR *retval;
if (ar->ary_fill < 0)
return Nullstr;
retval = *ar->ary_array;
*(ar->ary_array++) = Nullstr;
ar->ary_max--;
ar->ary_fill--;
return retval;
}
int
alen(ar)
register ARRAY *ar;
{
return ar->ary_fill;
}
afill(ar, fill)
register ARRAY *ar;
int fill;
{
if (fill < 0)
fill = -1;
if (fill <= ar->ary_max)
ar->ary_fill = fill;
else
(void)astore(ar,fill,Nullstr);
}