PageRenderTime 33ms CodeModel.GetById 13ms app.highlight 17ms RepoModel.GetById 1ms app.codeStats 0ms

/trunk/Source/DOH/list.c

#
C | 379 lines | 259 code | 40 blank | 80 comment | 40 complexity | 6f8c83d95e033d1b0fbb8e74f820b315 MD5 | raw file
  1/* ----------------------------------------------------------------------------- 
  2 * This file is part of SWIG, which is licensed as a whole under version 3 
  3 * (or any later version) of the GNU General Public License. Some additional
  4 * terms also apply to certain portions of SWIG. The full details of the SWIG
  5 * license and copyrights can be found in the LICENSE and COPYRIGHT files
  6 * included with the SWIG source code as distributed by the SWIG developers
  7 * and at http://www.swig.org/legal.html.
  8 *
  9 * list.c
 10 *
 11 *     Implements a simple list object.
 12 * ----------------------------------------------------------------------------- */
 13
 14char cvsroot_list_c[] = "$Id: list.c 12221 2010-09-15 20:17:11Z wsfulton $";
 15
 16#include "dohint.h"
 17
 18typedef struct List {
 19  int maxitems;			/* Max size  */
 20  int nitems;			/* Num items */
 21  DOH *file;
 22  int line;
 23  DOH **items;
 24} List;
 25
 26extern DohObjInfo DohListType;
 27
 28/* Doubles amount of memory in a list */
 29static
 30void more(List *l) {
 31  l->items = (void **) DohRealloc(l->items, l->maxitems * 2 * sizeof(void *));
 32  assert(l->items);
 33  l->maxitems *= 2;
 34}
 35
 36/* -----------------------------------------------------------------------------
 37 * CopyList()
 38 *
 39 * Make a shallow copy of a list.
 40 * ----------------------------------------------------------------------------- */
 41static DOH *CopyList(DOH *lo) {
 42  List *l, *nl;
 43  int i;
 44  l = (List *) ObjData(lo);
 45  nl = (List *) DohMalloc(sizeof(List));
 46  nl->nitems = l->nitems;
 47  nl->maxitems = l->maxitems;
 48  nl->items = (void **) DohMalloc(l->maxitems * sizeof(void *));
 49  for (i = 0; i < l->nitems; i++) {
 50    nl->items[i] = l->items[i];
 51    Incref(nl->items[i]);
 52  }
 53  nl->file = l->file;
 54  if (nl->file)
 55    Incref(nl->file);
 56  nl->line = l->line;
 57  return DohObjMalloc(&DohListType, nl);
 58}
 59
 60/* -----------------------------------------------------------------------------
 61 * DelList()
 62 *
 63 * Delete a list.
 64 * ----------------------------------------------------------------------------- */
 65
 66static void DelList(DOH *lo) {
 67  List *l = (List *) ObjData(lo);
 68  int i;
 69  for (i = 0; i < l->nitems; i++)
 70    Delete(l->items[i]);
 71  DohFree(l->items);
 72  DohFree(l);
 73}
 74
 75/* -----------------------------------------------------------------------------
 76 * List_clear()
 77 *
 78 * Remove all of the list entries, but keep the list object intact.
 79 * ----------------------------------------------------------------------------- */
 80
 81static void List_clear(DOH *lo) {
 82  List *l = (List *) ObjData(lo);
 83  int i;
 84  for (i = 0; i < l->nitems; i++) {
 85    Delete(l->items[i]);
 86  }
 87  l->nitems = 0;
 88}
 89
 90/* -----------------------------------------------------------------------------
 91 * List_insert()
 92 *
 93 * Insert an item into the list. If the item is not a DOH object, it is assumed
 94 * to be a 'char *' and is used to construct an equivalent string object.
 95 * ----------------------------------------------------------------------------- */
 96
 97static int List_insert(DOH *lo, int pos, DOH *item) {
 98  List *l = (List *) ObjData(lo);
 99  int i;
100
101  if (!item)
102    return -1;
103  if (!DohCheck(item)) {
104    item = NewString(item);
105    Decref(item);
106  }
107  if (pos == DOH_END)
108    pos = l->nitems;
109  if (pos < 0)
110    pos = 0;
111  if (pos > l->nitems)
112    pos = l->nitems;
113  if (l->nitems == l->maxitems)
114    more(l);
115  for (i = l->nitems; i > pos; i--) {
116    l->items[i] = l->items[i - 1];
117  }
118  l->items[pos] = item;
119  Incref(item);
120  l->nitems++;
121  return 0;
122}
123
124/* -----------------------------------------------------------------------------
125 * List_remove()
126 *
127 * Remove an item from a list.
128 * ----------------------------------------------------------------------------- */
129
130static int List_remove(DOH *lo, int pos) {
131  List *l = (List *) ObjData(lo);
132  int i;
133  if (pos == DOH_END)
134    pos = l->nitems - 1;
135  if (pos == DOH_BEGIN)
136    pos = 0;
137  assert(!((pos < 0) || (pos >= l->nitems)));
138  Delete(l->items[pos]);
139  for (i = pos; i < l->nitems - 1; i++) {
140    l->items[i] = l->items[i + 1];
141  }
142  l->nitems--;
143  return 0;
144}
145
146/* -----------------------------------------------------------------------------
147 * List_len()
148 *
149 * Return the number of elements in the list
150 * ----------------------------------------------------------------------------- */
151
152static int List_len(DOH *lo) {
153  List *l = (List *) ObjData(lo);
154  return l->nitems;
155}
156
157/* -----------------------------------------------------------------------------
158 * List_get()
159 *
160 * Get the nth item from the list.
161 * ----------------------------------------------------------------------------- */
162
163static DOH *List_get(DOH *lo, int n) {
164  List *l = (List *) ObjData(lo);
165  if (n == DOH_END)
166    n = l->nitems - 1;
167  if (n == DOH_BEGIN)
168    n = 0;
169  assert(!((n < 0) || (n >= l->nitems)));
170  return l->items[n];
171}
172
173/* -----------------------------------------------------------------------------
174 * List_set()
175 *
176 * Set the nth item in the list replacing any previous item. 
177 * ----------------------------------------------------------------------------- */
178
179static int List_set(DOH *lo, int n, DOH *val) {
180  List *l = (List *) ObjData(lo);
181  if (!val)
182    return -1;
183  assert(!((n < 0) || (n >= l->nitems)));
184  if (!DohCheck(val)) {
185    val = NewString(val);
186    Decref(val);
187  }
188  Delete(l->items[n]);
189  l->items[n] = val;
190  Incref(val);
191  Delete(val);
192  return 0;
193}
194
195/* -----------------------------------------------------------------------------
196 * List_first()
197 *
198 * Return the first item in the list.
199 * ----------------------------------------------------------------------------- */
200
201static DohIterator List_first(DOH *lo) {
202  DohIterator iter;
203  List *l = (List *) ObjData(lo);
204  iter.object = lo;
205  iter._index = 0;
206  iter._current = 0;
207  iter.key = 0;
208  if (l->nitems > 0) {
209    iter.item = l->items[0];
210  } else {
211    iter.item = 0;
212  }
213  return iter;
214}
215
216/* -----------------------------------------------------------------------------
217 * List_next()
218 * 
219 * Return the next item in the list.
220 * ----------------------------------------------------------------------------- */
221
222static DohIterator List_next(DohIterator iter) {
223  List *l = (List *) ObjData(iter.object);
224  iter._index = iter._index + 1;
225  if (iter._index >= l->nitems) {
226    iter.item = 0;
227    iter.key = 0;
228  } else {
229    iter.item = l->items[iter._index];
230  }
231  return iter;
232}
233
234/* -----------------------------------------------------------------------------
235 * List_str()
236 *
237 * Create a string representation of the list.
238 * ----------------------------------------------------------------------------- */
239static DOH *List_str(DOH *lo) {
240  DOH *s;
241  int i;
242  List *l = (List *) ObjData(lo);
243  s = NewStringEmpty();
244  if (ObjGetMark(lo)) {
245    Printf(s, "List(%x)", lo);
246    return s;
247  }
248  ObjSetMark(lo, 1);
249  Printf(s, "List[ ");
250  for (i = 0; i < l->nitems; i++) {
251    Printf(s, "%s", l->items[i]);
252    if ((i + 1) < l->nitems)
253      Printf(s, ", ");
254  }
255  Printf(s, " ]");
256  ObjSetMark(lo, 0);
257  return s;
258}
259
260/* -----------------------------------------------------------------------------
261 * List_dump()
262 *
263 * Dump the items to an output stream.
264 * ----------------------------------------------------------------------------- */
265
266static int List_dump(DOH *lo, DOH *out) {
267  int nsent = 0;
268  int i, ret;
269  List *l = (List *) ObjData(lo);
270  for (i = 0; i < l->nitems; i++) {
271    ret = Dump(l->items[i], out);
272    if (ret < 0)
273      return -1;
274    nsent += ret;
275  }
276  return nsent;
277}
278
279static void List_setfile(DOH *lo, DOH *file) {
280  DOH *fo;
281  List *l = (List *) ObjData(lo);
282
283  if (!DohCheck(file)) {
284    fo = NewString(file);
285    Decref(fo);
286  } else
287    fo = file;
288  Incref(fo);
289  Delete(l->file);
290  l->file = fo;
291}
292
293static DOH *List_getfile(DOH *lo) {
294  List *l = (List *) ObjData(lo);
295  return l->file;
296}
297
298static void List_setline(DOH *lo, int line) {
299  List *l = (List *) ObjData(lo);
300  l->line = line;
301}
302
303static int List_getline(DOH *lo) {
304  List *l = (List *) ObjData(lo);
305  return l->line;
306}
307
308static DohListMethods ListListMethods = {
309  List_get,
310  List_set,
311  List_remove,
312  List_insert,
313  0,				/* delslice */
314};
315
316DohObjInfo DohListType = {
317  "List",			/* objname */
318  DelList,			/* doh_del */
319  CopyList,			/* doh_copy */
320  List_clear,			/* doh_clear */
321  List_str,			/* doh_str */
322  0,				/* doh_data */
323  List_dump,			/* doh_dump */
324  List_len,			/* doh_len */
325  0,				/* doh_hash    */
326  0,				/* doh_cmp */
327  0,				/* doh_equal    */
328  List_first,			/* doh_first    */
329  List_next,			/* doh_next     */
330  List_setfile,			/* doh_setfile */
331  List_getfile,			/* doh_getfile */
332  List_setline,			/* doh_setline */
333  List_getline,			/* doh_getline */
334  0,				/* doh_mapping */
335  &ListListMethods,		/* doh_sequence */
336  0,				/* doh_file */
337  0,				/* doh_string */
338  0,				/* doh_callable */
339  0,				/* doh_position */
340};
341
342/* -----------------------------------------------------------------------------
343 * NewList()
344 *
345 * Create a new list.
346 * ----------------------------------------------------------------------------- */
347
348#define MAXLISTITEMS 8
349
350DOH *DohNewList(void) {
351  List *l;
352  int i;
353  l = (List *) DohMalloc(sizeof(List));
354  l->nitems = 0;
355  l->maxitems = MAXLISTITEMS;
356  l->items = (void **) DohMalloc(l->maxitems * sizeof(void *));
357  for (i = 0; i < MAXLISTITEMS; i++) {
358    l->items[i] = 0;
359  }
360  l->file = 0;
361  l->line = 0;
362  return DohObjMalloc(&DohListType, l);
363}
364
365static int (*List_sort_compare_func) (const DOH *, const DOH *);
366static int List_qsort_compare(const void *a, const void *b) {
367  return List_sort_compare_func(*((DOH **) a), *((DOH **) b));
368}
369
370/* Sort a list */
371void DohSortList(DOH *lo, int (*cmp) (const DOH *, const DOH *)) {
372  List *l = (List *) ObjData(lo);
373  if (cmp) {
374    List_sort_compare_func = cmp;
375  } else {
376    List_sort_compare_func = DohCmp;
377  }
378  qsort(l->items, l->nitems, sizeof(DOH *), List_qsort_compare);
379}