123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371 |
- /* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at https://www.swig.org/legal.html.
- *
- * list.c
- *
- * Implements a simple list object.
- * ----------------------------------------------------------------------------- */
- #include "dohint.h"
- typedef struct List {
- int maxitems; /* Max size */
- int nitems; /* Num items */
- DOH *file;
- int line;
- DOH **items;
- } List;
- extern DohObjInfo DohListType;
- /* Doubles amount of memory in a list */
- static
- void more(List *l) {
- l->items = (void **) DohRealloc(l->items, l->maxitems * 2 * sizeof(void *));
- l->maxitems *= 2;
- }
- /* -----------------------------------------------------------------------------
- * CopyList()
- *
- * Make a shallow copy of a list.
- * ----------------------------------------------------------------------------- */
- static DOH *CopyList(DOH *lo) {
- List *l, *nl;
- int i;
- l = (List *) ObjData(lo);
- nl = (List *) DohMalloc(sizeof(List));
- nl->nitems = l->nitems;
- nl->maxitems = l->maxitems;
- nl->items = (void **) DohMalloc(l->maxitems * sizeof(void *));
- for (i = 0; i < l->nitems; i++) {
- nl->items[i] = l->items[i];
- Incref(nl->items[i]);
- }
- nl->file = l->file;
- if (nl->file)
- Incref(nl->file);
- nl->line = l->line;
- return DohObjMalloc(&DohListType, nl);
- }
- /* -----------------------------------------------------------------------------
- * DelList()
- *
- * Delete a list.
- * ----------------------------------------------------------------------------- */
- static void DelList(DOH *lo) {
- List *l = (List *) ObjData(lo);
- int i;
- for (i = 0; i < l->nitems; i++)
- Delete(l->items[i]);
- DohFree(l->items);
- DohFree(l);
- }
- /* -----------------------------------------------------------------------------
- * List_clear()
- *
- * Remove all of the list entries, but keep the list object intact.
- * ----------------------------------------------------------------------------- */
- static void List_clear(DOH *lo) {
- List *l = (List *) ObjData(lo);
- int i;
- for (i = 0; i < l->nitems; i++) {
- Delete(l->items[i]);
- }
- l->nitems = 0;
- }
- /* -----------------------------------------------------------------------------
- * List_insert()
- *
- * Insert an item into the list. If the item is not a DOH object, it is assumed
- * to be a 'char *' and is used to construct an equivalent string object.
- * ----------------------------------------------------------------------------- */
- static int List_insert(DOH *lo, int pos, DOH *item) {
- List *l = (List *) ObjData(lo);
- int i;
- if (!item)
- return -1;
- if (!DohCheck(item)) {
- item = NewString(item);
- Decref(item);
- }
- if (pos == DOH_END)
- pos = l->nitems;
- if (pos < 0)
- pos = 0;
- if (pos > l->nitems)
- pos = l->nitems;
- if (l->nitems == l->maxitems)
- more(l);
- for (i = l->nitems; i > pos; i--) {
- l->items[i] = l->items[i - 1];
- }
- l->items[pos] = item;
- Incref(item);
- l->nitems++;
- return 0;
- }
- /* -----------------------------------------------------------------------------
- * List_remove()
- *
- * Remove an item from a list.
- * ----------------------------------------------------------------------------- */
- static int List_remove(DOH *lo, int pos) {
- List *l = (List *) ObjData(lo);
- int i;
- if (pos == DOH_END)
- pos = l->nitems - 1;
- if (pos == DOH_BEGIN)
- pos = 0;
- assert(!((pos < 0) || (pos >= l->nitems)));
- Delete(l->items[pos]);
- for (i = pos; i < l->nitems - 1; i++) {
- l->items[i] = l->items[i + 1];
- }
- l->nitems--;
- return 0;
- }
- /* -----------------------------------------------------------------------------
- * List_len()
- *
- * Return the number of elements in the list
- * ----------------------------------------------------------------------------- */
- static int List_len(DOH *lo) {
- List *l = (List *) ObjData(lo);
- return l->nitems;
- }
- /* -----------------------------------------------------------------------------
- * List_get()
- *
- * Get the nth item from the list.
- * ----------------------------------------------------------------------------- */
- static DOH *List_get(DOH *lo, int n) {
- List *l = (List *) ObjData(lo);
- if (n == DOH_END)
- n = l->nitems - 1;
- if (n == DOH_BEGIN)
- n = 0;
- assert(!((n < 0) || (n >= l->nitems)));
- return l->items[n];
- }
- /* -----------------------------------------------------------------------------
- * List_set()
- *
- * Set the nth item in the list replacing any previous item.
- * ----------------------------------------------------------------------------- */
- static int List_set(DOH *lo, int n, DOH *val) {
- List *l = (List *) ObjData(lo);
- if (!val)
- return -1;
- assert(!((n < 0) || (n >= l->nitems)));
- if (!DohCheck(val)) {
- val = NewString(val);
- Decref(val);
- }
- Delete(l->items[n]);
- l->items[n] = val;
- Incref(val);
- Delete(val);
- return 0;
- }
- /* -----------------------------------------------------------------------------
- * List_first()
- *
- * Return the first item in the list.
- * ----------------------------------------------------------------------------- */
- static DohIterator List_first(DOH *lo) {
- DohIterator iter;
- List *l = (List *) ObjData(lo);
- iter.object = lo;
- iter._index = 0;
- iter._current = 0;
- iter.key = 0;
- if (l->nitems > 0) {
- iter.item = l->items[0];
- } else {
- iter.item = 0;
- }
- return iter;
- }
- /* -----------------------------------------------------------------------------
- * List_next()
- *
- * Return the next item in the list.
- * ----------------------------------------------------------------------------- */
- static DohIterator List_next(DohIterator iter) {
- List *l = (List *) ObjData(iter.object);
- iter._index = iter._index + 1;
- if (iter._index >= l->nitems) {
- iter.item = 0;
- iter.key = 0;
- } else {
- iter.item = l->items[iter._index];
- }
- return iter;
- }
- /* -----------------------------------------------------------------------------
- * List_str()
- *
- * Create a string representation of the list.
- * ----------------------------------------------------------------------------- */
- static DOH *List_str(DOH *lo) {
- DOH *s;
- int i;
- List *l = (List *) ObjData(lo);
- s = NewStringEmpty();
- if (ObjGetMark(lo)) {
- Printf(s, "List(%p)", lo);
- return s;
- }
- ObjSetMark(lo, 1);
- Printf(s, "List[ ");
- for (i = 0; i < l->nitems; i++) {
- Printf(s, "%s", l->items[i]);
- if ((i + 1) < l->nitems)
- Printf(s, ", ");
- }
- Printf(s, " ]");
- ObjSetMark(lo, 0);
- return s;
- }
- /* -----------------------------------------------------------------------------
- * List_dump()
- *
- * Dump the items to an output stream.
- * ----------------------------------------------------------------------------- */
- static int List_dump(DOH *lo, DOH *out) {
- int nsent = 0;
- int i, ret;
- List *l = (List *) ObjData(lo);
- for (i = 0; i < l->nitems; i++) {
- ret = Dump(l->items[i], out);
- if (ret < 0)
- return -1;
- nsent += ret;
- }
- return nsent;
- }
- static void List_setfile(DOH *lo, DOH *file) {
- DOH *fo;
- List *l = (List *) ObjData(lo);
- if (!DohCheck(file)) {
- fo = NewString(file);
- Decref(fo);
- } else
- fo = file;
- Incref(fo);
- Delete(l->file);
- l->file = fo;
- }
- static DOH *List_getfile(DOH *lo) {
- List *l = (List *) ObjData(lo);
- return l->file;
- }
- static void List_setline(DOH *lo, int line) {
- List *l = (List *) ObjData(lo);
- l->line = line;
- }
- static int List_getline(DOH *lo) {
- List *l = (List *) ObjData(lo);
- return l->line;
- }
- static DohListMethods ListListMethods = {
- List_get,
- List_set,
- List_remove,
- List_insert,
- 0, /* delslice */
- };
- DohObjInfo DohListType = {
- "List", /* objname */
- DelList, /* doh_del */
- CopyList, /* doh_copy */
- List_clear, /* doh_clear */
- List_str, /* doh_str */
- 0, /* doh_data */
- List_dump, /* doh_dump */
- List_len, /* doh_len */
- 0, /* doh_hash */
- 0, /* doh_cmp */
- 0, /* doh_equal */
- List_first, /* doh_first */
- List_next, /* doh_next */
- List_setfile, /* doh_setfile */
- List_getfile, /* doh_getfile */
- List_setline, /* doh_setline */
- List_getline, /* doh_getline */
- 0, /* doh_mapping */
- &ListListMethods, /* doh_sequence */
- 0, /* doh_file */
- 0, /* doh_string */
- 0, /* doh_callable */
- 0, /* doh_position */
- };
- /* -----------------------------------------------------------------------------
- * NewList()
- *
- * Create a new list.
- * ----------------------------------------------------------------------------- */
- #define MAXLISTITEMS 8
- DOH *DohNewList(void) {
- List *l = (List *) DohMalloc(sizeof(List));
- l->nitems = 0;
- l->maxitems = MAXLISTITEMS;
- l->items = (void **) DohCalloc(l->maxitems, sizeof(void *));
- l->file = 0;
- l->line = 0;
- return DohObjMalloc(&DohListType, l);
- }
- static int (*List_sort_compare_func) (const DOH *, const DOH *);
- static int List_qsort_compare(const void *a, const void *b) {
- return List_sort_compare_func(*((DOH **) a), *((DOH **) b));
- }
- /* Sort a list */
- void DohSortList(DOH *lo, int (*cmp) (const DOH *, const DOH *)) {
- List *l = (List *) ObjData(lo);
- if (cmp) {
- List_sort_compare_func = cmp;
- } else {
- List_sort_compare_func = DohCmp;
- }
- qsort(l->items, l->nitems, sizeof(DOH *), List_qsort_compare);
- }
|