PageRenderTime 44ms CodeModel.GetById 21ms 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
Possible License(s): LGPL-2.1, Cube, GPL-3.0, 0BSD, GPL-2.0
  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. char cvsroot_list_c[] = "$Id: list.c 12221 2010-09-15 20:17:11Z wsfulton $";
  14. #include "dohint.h"
  15. typedef struct List {
  16. int maxitems; /* Max size */
  17. int nitems; /* Num items */
  18. DOH *file;
  19. int line;
  20. DOH **items;
  21. } List;
  22. extern DohObjInfo DohListType;
  23. /* Doubles amount of memory in a list */
  24. static
  25. void more(List *l) {
  26. l->items = (void **) DohRealloc(l->items, l->maxitems * 2 * sizeof(void *));
  27. assert(l->items);
  28. l->maxitems *= 2;
  29. }
  30. /* -----------------------------------------------------------------------------
  31. * CopyList()
  32. *
  33. * Make a shallow copy of a list.
  34. * ----------------------------------------------------------------------------- */
  35. static DOH *CopyList(DOH *lo) {
  36. List *l, *nl;
  37. int i;
  38. l = (List *) ObjData(lo);
  39. nl = (List *) DohMalloc(sizeof(List));
  40. nl->nitems = l->nitems;
  41. nl->maxitems = l->maxitems;
  42. nl->items = (void **) DohMalloc(l->maxitems * sizeof(void *));
  43. for (i = 0; i < l->nitems; i++) {
  44. nl->items[i] = l->items[i];
  45. Incref(nl->items[i]);
  46. }
  47. nl->file = l->file;
  48. if (nl->file)
  49. Incref(nl->file);
  50. nl->line = l->line;
  51. return DohObjMalloc(&DohListType, nl);
  52. }
  53. /* -----------------------------------------------------------------------------
  54. * DelList()
  55. *
  56. * Delete a list.
  57. * ----------------------------------------------------------------------------- */
  58. static void DelList(DOH *lo) {
  59. List *l = (List *) ObjData(lo);
  60. int i;
  61. for (i = 0; i < l->nitems; i++)
  62. Delete(l->items[i]);
  63. DohFree(l->items);
  64. DohFree(l);
  65. }
  66. /* -----------------------------------------------------------------------------
  67. * List_clear()
  68. *
  69. * Remove all of the list entries, but keep the list object intact.
  70. * ----------------------------------------------------------------------------- */
  71. static void 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 List_insert(DOH *lo, int pos, DOH *item) {
  86. List *l = (List *) ObjData(lo);
  87. int i;
  88. if (!item)
  89. return -1;
  90. if (!DohCheck(item)) {
  91. item = NewString(item);
  92. Decref(item);
  93. }
  94. if (pos == DOH_END)
  95. pos = l->nitems;
  96. if (pos < 0)
  97. pos = 0;
  98. if (pos > l->nitems)
  99. pos = l->nitems;
  100. if (l->nitems == l->maxitems)
  101. more(l);
  102. for (i = l->nitems; i > pos; i--) {
  103. l->items[i] = l->items[i - 1];
  104. }
  105. l->items[pos] = item;
  106. Incref(item);
  107. l->nitems++;
  108. return 0;
  109. }
  110. /* -----------------------------------------------------------------------------
  111. * List_remove()
  112. *
  113. * Remove an item from a list.
  114. * ----------------------------------------------------------------------------- */
  115. static int List_remove(DOH *lo, int pos) {
  116. List *l = (List *) ObjData(lo);
  117. int i;
  118. if (pos == DOH_END)
  119. pos = l->nitems - 1;
  120. if (pos == DOH_BEGIN)
  121. pos = 0;
  122. assert(!((pos < 0) || (pos >= l->nitems)));
  123. Delete(l->items[pos]);
  124. for (i = pos; i < l->nitems - 1; i++) {
  125. l->items[i] = l->items[i + 1];
  126. }
  127. l->nitems--;
  128. return 0;
  129. }
  130. /* -----------------------------------------------------------------------------
  131. * List_len()
  132. *
  133. * Return the number of elements in the list
  134. * ----------------------------------------------------------------------------- */
  135. static int List_len(DOH *lo) {
  136. List *l = (List *) ObjData(lo);
  137. return l->nitems;
  138. }
  139. /* -----------------------------------------------------------------------------
  140. * List_get()
  141. *
  142. * Get the nth item from the list.
  143. * ----------------------------------------------------------------------------- */
  144. static DOH *List_get(DOH *lo, int n) {
  145. List *l = (List *) ObjData(lo);
  146. if (n == DOH_END)
  147. n = l->nitems - 1;
  148. if (n == DOH_BEGIN)
  149. n = 0;
  150. assert(!((n < 0) || (n >= l->nitems)));
  151. return l->items[n];
  152. }
  153. /* -----------------------------------------------------------------------------
  154. * List_set()
  155. *
  156. * Set the nth item in the list replacing any previous item.
  157. * ----------------------------------------------------------------------------- */
  158. static int List_set(DOH *lo, int n, DOH *val) {
  159. List *l = (List *) ObjData(lo);
  160. if (!val)
  161. return -1;
  162. assert(!((n < 0) || (n >= l->nitems)));
  163. if (!DohCheck(val)) {
  164. val = NewString(val);
  165. Decref(val);
  166. }
  167. Delete(l->items[n]);
  168. l->items[n] = val;
  169. Incref(val);
  170. Delete(val);
  171. return 0;
  172. }
  173. /* -----------------------------------------------------------------------------
  174. * List_first()
  175. *
  176. * Return the first item in the list.
  177. * ----------------------------------------------------------------------------- */
  178. static DohIterator List_first(DOH *lo) {
  179. DohIterator iter;
  180. List *l = (List *) ObjData(lo);
  181. iter.object = lo;
  182. iter._index = 0;
  183. iter._current = 0;
  184. iter.key = 0;
  185. if (l->nitems > 0) {
  186. iter.item = l->items[0];
  187. } else {
  188. iter.item = 0;
  189. }
  190. return iter;
  191. }
  192. /* -----------------------------------------------------------------------------
  193. * List_next()
  194. *
  195. * Return the next item in the list.
  196. * ----------------------------------------------------------------------------- */
  197. static DohIterator List_next(DohIterator iter) {
  198. List *l = (List *) ObjData(iter.object);
  199. iter._index = iter._index + 1;
  200. if (iter._index >= l->nitems) {
  201. iter.item = 0;
  202. iter.key = 0;
  203. } else {
  204. iter.item = l->items[iter._index];
  205. }
  206. return iter;
  207. }
  208. /* -----------------------------------------------------------------------------
  209. * List_str()
  210. *
  211. * Create a string representation of the list.
  212. * ----------------------------------------------------------------------------- */
  213. static DOH *List_str(DOH *lo) {
  214. DOH *s;
  215. int i;
  216. List *l = (List *) ObjData(lo);
  217. s = NewStringEmpty();
  218. if (ObjGetMark(lo)) {
  219. Printf(s, "List(%x)", lo);
  220. return s;
  221. }
  222. ObjSetMark(lo, 1);
  223. Printf(s, "List[ ");
  224. for (i = 0; i < l->nitems; i++) {
  225. Printf(s, "%s", l->items[i]);
  226. if ((i + 1) < l->nitems)
  227. Printf(s, ", ");
  228. }
  229. Printf(s, " ]");
  230. ObjSetMark(lo, 0);
  231. return s;
  232. }
  233. /* -----------------------------------------------------------------------------
  234. * List_dump()
  235. *
  236. * Dump the items to an output stream.
  237. * ----------------------------------------------------------------------------- */
  238. static int List_dump(DOH *lo, DOH *out) {
  239. int nsent = 0;
  240. int i, ret;
  241. List *l = (List *) ObjData(lo);
  242. for (i = 0; i < l->nitems; i++) {
  243. ret = Dump(l->items[i], out);
  244. if (ret < 0)
  245. return -1;
  246. nsent += ret;
  247. }
  248. return nsent;
  249. }
  250. static void List_setfile(DOH *lo, DOH *file) {
  251. DOH *fo;
  252. List *l = (List *) ObjData(lo);
  253. if (!DohCheck(file)) {
  254. fo = NewString(file);
  255. Decref(fo);
  256. } else
  257. fo = file;
  258. Incref(fo);
  259. Delete(l->file);
  260. l->file = fo;
  261. }
  262. static DOH *List_getfile(DOH *lo) {
  263. List *l = (List *) ObjData(lo);
  264. return l->file;
  265. }
  266. static void 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 *DohNewList(void) {
  313. List *l;
  314. int i;
  315. l = (List *) DohMalloc(sizeof(List));
  316. l->nitems = 0;
  317. l->maxitems = MAXLISTITEMS;
  318. l->items = (void **) DohMalloc(l->maxitems * sizeof(void *));
  319. for (i = 0; i < MAXLISTITEMS; i++) {
  320. l->items[i] = 0;
  321. }
  322. l->file = 0;
  323. l->line = 0;
  324. return DohObjMalloc(&DohListType, l);
  325. }
  326. static int (*List_sort_compare_func) (const DOH *, const DOH *);
  327. static int List_qsort_compare(const void *a, const void *b) {
  328. return List_sort_compare_func(*((DOH **) a), *((DOH **) b));
  329. }
  330. /* Sort a list */
  331. void DohSortList(DOH *lo, int (*cmp) (const DOH *, const DOH *)) {
  332. List *l = (List *) ObjData(lo);
  333. if (cmp) {
  334. List_sort_compare_func = cmp;
  335. } else {
  336. List_sort_compare_func = DohCmp;
  337. }
  338. qsort(l->items, l->nitems, sizeof(DOH *), List_qsort_compare);
  339. }