PageRenderTime 41ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/tags/rel-1.3.39/Source/DOH/list.c

#
C | 377 lines | 259 code | 40 blank | 78 comment | 40 complexity | fe5dd29b2f76e509bf6224cdc6d21657 MD5 | raw file
Possible License(s): LGPL-2.1, Cube, GPL-3.0, 0BSD, GPL-2.0
  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[] = "$Id: list.c 10926 2008-11-11 22:17:40Z wsfulton $";
  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 *CopyList(DOH *lo) {
  34. List *l, *nl;
  35. int i;
  36. l = (List *) ObjData(lo);
  37. nl = (List *) DohMalloc(sizeof(List));
  38. nl->nitems = l->nitems;
  39. nl->maxitems = l->maxitems;
  40. nl->items = (void **) DohMalloc(l->maxitems * sizeof(void *));
  41. for (i = 0; i < l->nitems; i++) {
  42. nl->items[i] = l->items[i];
  43. Incref(nl->items[i]);
  44. }
  45. nl->file = l->file;
  46. if (nl->file)
  47. 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 DelList(DOH *lo) {
  57. List *l = (List *) ObjData(lo);
  58. int i;
  59. for (i = 0; i < l->nitems; i++)
  60. Delete(l->items[i]);
  61. DohFree(l->items);
  62. DohFree(l);
  63. }
  64. /* -----------------------------------------------------------------------------
  65. * List_clear()
  66. *
  67. * Remove all of the list entries, but keep the list object intact.
  68. * ----------------------------------------------------------------------------- */
  69. static void List_clear(DOH *lo) {
  70. List *l = (List *) ObjData(lo);
  71. int i;
  72. for (i = 0; i < l->nitems; i++) {
  73. Delete(l->items[i]);
  74. }
  75. l->nitems = 0;
  76. }
  77. /* -----------------------------------------------------------------------------
  78. * List_insert()
  79. *
  80. * Insert an item into the list. If the item is not a DOH object, it is assumed
  81. * to be a 'char *' and is used to construct an equivalent string object.
  82. * ----------------------------------------------------------------------------- */
  83. static int List_insert(DOH *lo, int pos, DOH *item) {
  84. List *l = (List *) ObjData(lo);
  85. int i;
  86. if (!item)
  87. return -1;
  88. if (!DohCheck(item)) {
  89. item = NewString(item);
  90. Decref(item);
  91. }
  92. if (pos == DOH_END)
  93. pos = l->nitems;
  94. if (pos < 0)
  95. pos = 0;
  96. if (pos > l->nitems)
  97. pos = l->nitems;
  98. if (l->nitems == l->maxitems)
  99. more(l);
  100. for (i = l->nitems; i > pos; i--) {
  101. l->items[i] = l->items[i - 1];
  102. }
  103. l->items[pos] = item;
  104. Incref(item);
  105. l->nitems++;
  106. return 0;
  107. }
  108. /* -----------------------------------------------------------------------------
  109. * List_remove()
  110. *
  111. * Remove an item from a list.
  112. * ----------------------------------------------------------------------------- */
  113. static int List_remove(DOH *lo, int pos) {
  114. List *l = (List *) ObjData(lo);
  115. int i;
  116. if (pos == DOH_END)
  117. pos = l->nitems - 1;
  118. if (pos == DOH_BEGIN)
  119. pos = 0;
  120. assert(!((pos < 0) || (pos >= l->nitems)));
  121. Delete(l->items[pos]);
  122. for (i = pos; i < l->nitems - 1; i++) {
  123. l->items[i] = l->items[i + 1];
  124. }
  125. l->nitems--;
  126. return 0;
  127. }
  128. /* -----------------------------------------------------------------------------
  129. * List_len()
  130. *
  131. * Return the number of elements in the list
  132. * ----------------------------------------------------------------------------- */
  133. static int List_len(DOH *lo) {
  134. List *l = (List *) ObjData(lo);
  135. return l->nitems;
  136. }
  137. /* -----------------------------------------------------------------------------
  138. * List_get()
  139. *
  140. * Get the nth item from the list.
  141. * ----------------------------------------------------------------------------- */
  142. static DOH *List_get(DOH *lo, int n) {
  143. List *l = (List *) ObjData(lo);
  144. if (n == DOH_END)
  145. n = l->nitems - 1;
  146. if (n == DOH_BEGIN)
  147. n = 0;
  148. assert(!((n < 0) || (n >= l->nitems)));
  149. return l->items[n];
  150. }
  151. /* -----------------------------------------------------------------------------
  152. * List_set()
  153. *
  154. * Set the nth item in the list replacing any previous item.
  155. * ----------------------------------------------------------------------------- */
  156. static int List_set(DOH *lo, int n, DOH *val) {
  157. List *l = (List *) ObjData(lo);
  158. if (!val)
  159. return -1;
  160. assert(!((n < 0) || (n >= l->nitems)));
  161. if (!DohCheck(val)) {
  162. val = NewString(val);
  163. Decref(val);
  164. }
  165. Delete(l->items[n]);
  166. l->items[n] = val;
  167. Incref(val);
  168. Delete(val);
  169. return 0;
  170. }
  171. /* -----------------------------------------------------------------------------
  172. * List_first()
  173. *
  174. * Return the first item in the list.
  175. * ----------------------------------------------------------------------------- */
  176. static DohIterator List_first(DOH *lo) {
  177. DohIterator iter;
  178. List *l = (List *) ObjData(lo);
  179. iter.object = lo;
  180. iter._index = 0;
  181. iter._current = 0;
  182. iter.key = 0;
  183. if (l->nitems > 0) {
  184. iter.item = l->items[0];
  185. } else {
  186. iter.item = 0;
  187. }
  188. return iter;
  189. }
  190. /* -----------------------------------------------------------------------------
  191. * List_next()
  192. *
  193. * Return the next item in the list.
  194. * ----------------------------------------------------------------------------- */
  195. static DohIterator List_next(DohIterator iter) {
  196. List *l = (List *) ObjData(iter.object);
  197. iter._index = iter._index + 1;
  198. if (iter._index >= l->nitems) {
  199. iter.item = 0;
  200. iter.key = 0;
  201. } else {
  202. iter.item = l->items[iter._index];
  203. }
  204. return iter;
  205. }
  206. /* -----------------------------------------------------------------------------
  207. * List_str()
  208. *
  209. * Create a string representation of the list.
  210. * ----------------------------------------------------------------------------- */
  211. static DOH *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 List_dump(DOH *lo, DOH *out) {
  237. int nsent = 0;
  238. int i, ret;
  239. List *l = (List *) ObjData(lo);
  240. for (i = 0; i < l->nitems; i++) {
  241. ret = Dump(l->items[i], out);
  242. if (ret < 0)
  243. return -1;
  244. nsent += ret;
  245. }
  246. return nsent;
  247. }
  248. static void List_setfile(DOH *lo, DOH *file) {
  249. DOH *fo;
  250. List *l = (List *) ObjData(lo);
  251. if (!DohCheck(file)) {
  252. fo = NewString(file);
  253. Decref(fo);
  254. } else
  255. fo = file;
  256. Incref(fo);
  257. Delete(l->file);
  258. l->file = fo;
  259. }
  260. static DOH *List_getfile(DOH *lo) {
  261. List *l = (List *) ObjData(lo);
  262. return l->file;
  263. }
  264. static void List_setline(DOH *lo, int line) {
  265. List *l = (List *) ObjData(lo);
  266. l->line = line;
  267. }
  268. static int List_getline(DOH *lo) {
  269. List *l = (List *) ObjData(lo);
  270. return l->line;
  271. }
  272. static DohListMethods ListListMethods = {
  273. List_get,
  274. List_set,
  275. List_remove,
  276. List_insert,
  277. 0, /* delslice */
  278. };
  279. DohObjInfo DohListType = {
  280. "List", /* objname */
  281. DelList, /* doh_del */
  282. CopyList, /* doh_copy */
  283. List_clear, /* doh_clear */
  284. List_str, /* doh_str */
  285. 0, /* doh_data */
  286. List_dump, /* doh_dump */
  287. List_len, /* doh_len */
  288. 0, /* doh_hash */
  289. 0, /* doh_cmp */
  290. 0, /* doh_equal */
  291. List_first, /* doh_first */
  292. List_next, /* doh_next */
  293. List_setfile, /* doh_setfile */
  294. List_getfile, /* doh_getfile */
  295. List_setline, /* doh_setline */
  296. List_getline, /* doh_getline */
  297. 0, /* doh_mapping */
  298. &ListListMethods, /* doh_sequence */
  299. 0, /* doh_file */
  300. 0, /* doh_string */
  301. 0, /* doh_callable */
  302. 0, /* doh_position */
  303. };
  304. /* -----------------------------------------------------------------------------
  305. * NewList()
  306. *
  307. * Create a new list.
  308. * ----------------------------------------------------------------------------- */
  309. #define MAXLISTITEMS 8
  310. DOH *DohNewList(void) {
  311. List *l;
  312. int i;
  313. l = (List *) DohMalloc(sizeof(List));
  314. l->nitems = 0;
  315. l->maxitems = MAXLISTITEMS;
  316. l->items = (void **) DohMalloc(l->maxitems * sizeof(void *));
  317. for (i = 0; i < MAXLISTITEMS; i++) {
  318. l->items[i] = 0;
  319. }
  320. l->file = 0;
  321. l->line = 0;
  322. return DohObjMalloc(&DohListType, l);
  323. }
  324. static int (*List_sort_compare_func) (const DOH *, const DOH *);
  325. static int List_qsort_compare(const void *a, const void *b) {
  326. return List_sort_compare_func(*((DOH **) a), *((DOH **) b));
  327. }
  328. /* Sort a list */
  329. void DohSortList(DOH *lo, int (*cmp) (const DOH *, const DOH *)) {
  330. List *l = (List *) ObjData(lo);
  331. if (cmp) {
  332. List_sort_compare_func = cmp;
  333. } else {
  334. List_sort_compare_func = DohCmp;
  335. }
  336. qsort(l->items, l->nitems, sizeof(DOH *), List_qsort_compare);
  337. }