/tags/rel-1-3-28/SWIG/Source/DOH/list.c

# · C · 380 lines · 262 code · 40 blank · 78 comment · 41 complexity · 890032ea5681e4730692949b96f1573c MD5 · raw file

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