home *** CD-ROM | disk | FTP | other *** search
- /*
- array.c
- */
- /* Copyright (c) 1994 Christian F. Tschudin. All rights reserved.
-
- Distributed under the terms of the GNU General Public License
- version 2 of june 1991 as published by the Free Software
- Foundation, Inc.
-
- This file is part of M0.
-
- M0 is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY. No author or distributor accepts responsibility to anyone for
- the consequences of using it or for whether it serves any particular
- purpose or works at all, unless he says so in writing. Refer to the GNU
- General Public License for full details.
-
- Everyone is granted permission to copy, modify and redistribute M0, but
- only under the conditions described in the GNU General Public License.
- A copy of this license is supposed to have been given to you along with
- M0 so you can know your rights and responsibilities. It should be in a
- file named LICENSE. Among other things, the copyright notice and this
- notice must be preserved on all copies. */
-
- #include "l_proto.h"
-
-
- eindex
- new_array(mproc p, uint len)
- {
- eindex ei = new_element(p, T_ARRAY), *ip;
- eptr ep;
-
- if (!ei )
- return 0;
-
- ep = eaddr(p,ei);
- if (len) {
- ep->V.arr.a = (eindex*) malloc(len * sizeof(eindex));
- if (!ep->V.arr.a) {
- free_element(p,ei);
- return 0;
- }
- }
- eplen(ep) = len;
- ep->V.arr.alen = len;
- for (ip = ep->V.arr.a; len > 0; len--, ip++)
- *ip = null_val;
- gaddr(null_val)->R += eplen(ep);
- return ei;
- }
-
-
- eindex
- array_get(mproc p, eindex a, uint offs)
- {
- eptr ep = eaddr(p,a);
-
- if (offs<0 || offs >= eplen(ep))
- return 0;
-
- if (epattr(ep)&A_SUB)
- return array_get(p, ep->V.sub.e, ep->V.sub.offset + offs);
-
- return ep->V.arr.a[offs];
- }
-
-
- retcode
- array_put(mproc p, eindex a, uint offs, eindex e)
- {
- eptr ap = eaddr(p,a);
-
- if (offs<0 || offs >= eplen(ap))
- return ERR_RANGE_CHECK;
-
- if (epattr(ap)&A_SUB)
- return array_put(p, ap->V.sub.e, ap->V.sub.offset + offs, e);
-
- if (a < 0) {
- eindex e2 = make_global(p, e);
- decref(p, e);
- e = e2;
- }
- decref(p, ap->V.arr.a[offs]);
- ap->V.arr.a[offs] = e;
- return OK;
- }
-
- /* make_array does NOT increment the refcount of the included members */
- eindex
- make_array(mproc p, eindex *ip, uint len)
- {
- eindex ei = new_element(p, T_ARRAY), *ip2;
- eptr ep;
-
- if (!ei )
- return 0;
-
- ep = eaddr(p,ei);
- if (len) {
- int i;
- ep->V.arr.a = (eindex*) malloc(len * sizeof(eindex));
- if (!ep->V.arr.a) {
- free_element(p,ei);
- return 0;
- }
- for (i=len, ip2 = ep->V.arr.a; i > 0; i--)
- *ip2++ = *ip++;
- eplen(ep) = ep->V.arr.alen = len;
- }
- return ei;
- }
-
-
- /* should be called by free_element() only! */
- void
- array_free(mproc p, eindex ei)
- {
- eindex *ea;
- eptr ep = eaddr(p, ei);
- int i;
-
- eptype(ep) = T_EMPTY;
- for (i=eplen(ep), ea = ep->V.arr.a; i>0; i--, ea++)
- if (*ea) {
- eindex e = *ea;
- *ea = 0;
- decref(p, e);
- }
- free(ep->V.arr.a);
- }
-
-
- retcode
- array_copy(mproc p, eindex e, eptr from, eptr to)
- {
- int i = eplen(from);
- eindex *ip = to->V.arr.a = (eindex*) malloc(i * sizeof(eindex));
- int offs = 0;
-
- if (!ip)
- return ERR_MALLOC_FAILED;
-
- while (epattr(from) & A_SUB) {
- offs += from->V.sub.offset;
- from = eaddr(p, from->V.sub.e);
- }
-
- memcpy(ip, from->V.arr.a + offs, i * sizeof(eindex));
-
- for (; i > 0; i--, ip++)
- incref(p,*ip);
-
- epattr(to) = A_ALL;
- return OK;
- }
-
-