/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1982-2010 AT&T Intellectual Property *
* and is licensed under the *
* Common Public License, Version 1.0 *
* by AT&T Intellectual Property *
* *
* A copy of the License is available at *
* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
* *
* Information and Software Systems Research *
* AT&T Research *
* Florham Park NJ *
* *
* David Korn <dgk@research.att.com> *
* *
***********************************************************************/
#pragma prototyped
/*
* Array processing routines
*
* David Korn
* AT&T Labs
* dgk@research.att.com
*
*/
#include "defs.h"
#include <stak.h>
#include "name.h"
struct index_array
{
};
struct assoc_array
{
};
{
if(size==0)
return(0);
if(is_associative(aq))
{
return(aq);
}
return(aq);
}
{
return(0);
if(is_associative(ap))
return(1);
}
{
}
{
return(0);
}
/*
* replace discipline with new one
*/
{
if(*fp)
{
}
}
/*
* Calculate the amount of space to be allocated to hold an
* indexed array into which <maxi> is a legal index. The number of
* elements that will actually fit into the array (> <maxi>
* but <= ARRAY_MAX) is returned.
*
*/
{
}
/* return index of highest element of an array */
{
if(is_associative(ap))
return(-1);
return(i+1);
}
{
int nofree;
if(!arp)
if(is_associative(ap))
{
if(mp)
{
}
else
}
else
{
}
if(update)
{
if(nofree)
else
}
return(up);
}
{
if(is_associative(ap))
return(0);
}
/*
* Get the Value pointer for an array.
* Delete space as necessary if flag is ARRAY_DELETE
* After the lookup is done the last @ or * subscript is incremented
*/
{
int wasundef;
if(flag&ARRAY_LOOKUP)
else
{
/* delete array is the same as delete array[@] */
if(flag&ARRAY_DELETE)
{
}
else /* same as array[0] */
{
if(is_associative(ap))
else
}
}
if(is_associative(ap))
{
if(!mp)
else if(nv_isarray(mp))
{
if(wasundef)
return(mp);
}
else
{
if(nv_isvtree(mp))
{
{
}
return(mp);
}
}
}
else
{
{
char *cp;
}
{
}
}
{
if(flag!=ARRAY_ASSIGN)
}
return(np);
}
#if SHOPT_TYPEDEF
{
av[1] = 0;
sh.last_table = 0;
{
{
}
return(0);
if(!rdonly)
{
if(xtrace)
if(xtrace)
}
return(1);
}
return(0);
}
#endif /* SHOPT_TYPEDEF */
{
{
{
do
{
}
while(nv_nextsub(np));
}
return(fp);
}
if(nelem&ARRAY_NOCLONE)
return(0);
{
}
{
}
{
{
}
}
if(!is_associative(ap))
{
skipped=1;
goto skip;
}
do
{
mq = 0;
{
if(!is_associative(ap))
}
{
{
}
}
{
if(!is_associative(ap))
}
else
{
if(!is_associative(ap))
}
}
while(nv_nextsub(np));
skip:
if(sub)
{
if(!skipped)
}
}
{
{
{
}
}
}
{
{
{
}
}
}
{
do
{
{
{
goto skip;
}
if(string)
{
#if SHOPT_TYPEDEF
#endif /* SHOPT_TYPEDEF */
continue;
}
}
if(!string)
{
if(mp)
{
if(is_associative(ap))
{
}
else
{
{
}
}
}
{
if(is_associative(ap))
}
continue;
}
skip:
/* prevent empty string from being deleted */
if(nv_isarray(np))
if(!is_associative(ap))
{
if(string)
}
#if SHOPT_TYPEDEF
#endif /* SHOPT_TYPEDEF */
}
if(ap)
if(nofree)
else
{
{
}
{
}
}
}
{
sizeof(Namarr_t),
0,
0,
};
{
}
/*
* Increase the size of the indexed array of elements in <arp>
* so that <maxi> is a legal index. If <arp> is 0, an array
* of the required size is allocated. A pointer to the
* allocated Namarr_t structure is returned.
* <maxi> becomes the current index of the array.
*/
{
register int i;
if(arp)
{
}
else
{
i = 0;
{
i = ARRAY_TREE;
}
{
{
i++;
}
}
i++;
{
i++;
}
if(mp)
{
}
}
for(;i < newsize;i++)
return(ap);
}
{
if(tp)
{
if(!ap)
return(1);
}
return(0);
}
{
return(0);
}
/*
* Verify that argument is an indexed array and convert to associative,
* freeing relevant storage
*/
{
{
{
*--string_index = '0';
else while( n = digit )
{
digit /= 10;
}
}
}
return(ap);
}
/*
* set the associative array processing method for node <np> to <fun>
* The array pointer is returned if sucessful.
*/
{
char *value=0;
int nelem = 0;
{
/*
* if it's already an indexed array, convert to
* associative structure
*/
if(!is_associative(ap))
return(ap);
}
{
nelem = ARRAY_TREE;
}
{
/* check for preexisting initialization and save */
{
if(value)
else
{
}
}
return(ap);
}
}
/*
* move parent subscript into child
*/
{
if(!nq)
if(!ap)
{
}
return((Namval_t*)0);
{
if(c=='t')
else
}
{
}
if(c=='.')
return(nq);
}
/*
* This routine sets subscript of <np> to the next element, if any.
* The return value is zero, if there are no more elements
* Otherwise, 1 is returned.
*/
{
register unsigned dot;
return(0);
if(is_associative(ap))
{
{
return(1);
}
return(0);
}
{
{
continue;
}
{
{
continue;
if(nv_isarray(mp))
}
return(1);
}
}
return(0);
}
/*
* Set an array subscript for node <np> given the subscript <sp>
* An array is created if necessary.
* <mode> can be a number, plus or more of symbolic constants
* ARRAY_SCAN, ARRAY_UNDEF, ARRAY_ADD
* The node pointer is returned which can be NULL if <np> is
* not already array and the ARRAY_ADD bit of <mode> is not set.
* ARRAY_FILL sets the specified subscript to the empty string when
* ARRAY_ADD is specified and there is no value or sets all
* the elements up to the number specified if ARRAY_ADD is not specified
*/
{
{
if(sp)
{
{
}
else
}
{
}
{
}
#if 0
{
{
{
break;
}
}
}
#endif
np = 0;
{
{
int n;
for(n=0; n <= size; n++)
{
{
}
}
}
{
}
}
else if(!(mode&ARRAY_SCAN))
{
np = 0;
}
}
if(!(mode&ARRAY_FILL))
if(sp)
{
if(mode&ARRAY_SETSUB)
{
return(np);
}
np = 0;
}
else if(mode&ARRAY_SCAN)
else if(mode&ARRAY_UNDEF)
np = 0;
return(np);
}
/*
* process an array subscript for node <np> given the subscript <cp>
* returns pointer to character after the subscript
*/
{
/* first find matching ']' */
{
{
quoted=1;
cp++;
}
else if(c=='[')
count++;
else if(c==']')
count--;
}
*cp = 0;
if(quoted)
{
/* strip escape characters */
}
{
int scan = 0;
if(ap)
if(scan)
}
if(quoted)
*cp++ = c;
return(cp);
}
{
if(ap)
{
if(is_associative(ap))
}
}
{
register unsigned dot, n;
return(NIL(char*));
if(is_associative(ap))
{
}
*--cp = '0';
else while(n=dot)
{
dot /= 10;
}
return(cp);
}
/*
* If <np> is an indexed array node, the current subscript index
* returned, otherwise returns -1
*/
{
if(!ap)
return(0);
else if(is_associative(ap))
return(-1);
}
{
return(array_elem(ap));
}
{
return(-1);
return(sub);
}
/*
* This is the default implementation for associative arrays
*/
{
register int type;
switch(mode)
{
case NV_AINIT:
{
}
return((void*)ap);
case NV_ADELETE:
{
if(!ap->header.scope || (Dt_t*)ap->header.scope==ap->header.table || !nv_search(ap->cur->nvname,(Dt_t*)ap->header.scope,0))
}
return((void*)ap);
case NV_AFREE:
{
}
else
return((void*)ap);
case NV_ANEXT:
{
{
}
}
else
{
{
continue;
return((void*)ap);
}
}
{
}
return(NIL(void*));
case NV_ASETSUB:
case NV_ACURRENT:
case NV_ANAME:
{
return(NIL(void*));
}
return(NIL(void*));
default:
if(sp)
{
return(0);
if(mode)
mode = HASH_NOSCOPE;
{
{
}
}
{
}
}
else
}
}
/*
* Assign values to an array
*/
{
int arg0=0;
if(nv_isarray(np))
{
}
if(append)
{
if(ap)
{
arg0++;
}
arg0=1;
}
while(--argc >= 0)
{
}
}