list.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <sys/time.h>
  4. #include <time.h>
  5. #if 0
  6. #include <dmalloc.h>
  7. #endif
  8. #include <grass/gis.h>
  9. #include <grass/glocale.h>
  10. #include "list.h"
  11. LIST *listitem(size_t size);
  12. LIST *listadd(LIST * head, LIST * elt, cmpfunc cmp);
  13. LIST *listaddnth(LIST * head, LIST * elt, int nth);
  14. LIST *listprep(LIST * head, LIST * elt);
  15. LIST *listapp(LIST * head, LIST * elt);
  16. LIST *listunlink(LIST * head, LIST * elt);
  17. LIST *listunlinknth(LIST * head, int nth);
  18. LIST *listdel(LIST * head, LIST * elt, freefunc func);
  19. LIST *listdelnth(LIST * head, int nth, freefunc func);
  20. int listcnt(LIST * head);
  21. LIST *listdup(LIST * head, cpyfunc cpy, size_t size);
  22. LIST *listsplit(LIST * head, LIST * elt);
  23. LIST *listsplitnth(LIST * head, int nth);
  24. LIST *listjoin(LIST * head, LIST * tail);
  25. LIST *listsort(LIST * head, cmpfunc cmp);
  26. LIST *listrev(LIST * head);
  27. LIST *listshuffle(LIST * head);
  28. LIST *listdelall(LIST * head, freefunc func);
  29. LIST **list2array(LIST * head);
  30. LIST *array2list(LIST ** array);
  31. void listforeach(LIST * head, actfunc action);
  32. int listidx(LIST * head, LIST * elt);
  33. LIST *listlast(LIST * head);
  34. LIST *listnth(LIST * head, int nth);
  35. LIST *listfind(LIST * head, LIST * elt, cmpfunc cmp);
  36. LIST *listfinddatum(LIST * head, void *datum, cmpfunc cmp);
  37. LIST *listbsearch(LIST * head, LIST * elt, cmpfunc cmp);
  38. LIST *listbsearchdatum(LIST * head, const void *data, cmpfunc cmp);
  39. static LIST *_listbsearch(LIST * min, int max, LIST * elt, cmpfunc cmp);
  40. static LIST *_listbsearchdatum(LIST * min, int max, const void *datum,
  41. cmpfunc cmp);
  42. /*
  43. * listitem() allocate memory for a list item
  44. */
  45. LIST *listitem(size_t size)
  46. {
  47. LIST *item;
  48. item = G_calloc(1, size);
  49. if (!item) {
  50. G_fatal_error(_("Out of memory"));
  51. exit(1);
  52. }
  53. return item;
  54. }
  55. /*
  56. * listadd() insert item before first greater
  57. * (cmp == NULL) -> listapp()
  58. * This is VERY slow. Rather than a lineal search, we should
  59. * try to implement a listbapprox() function.
  60. */
  61. LIST *listadd(LIST * head, LIST * elt, cmpfunc cmp)
  62. {
  63. LIST *item, *prev = NULL;
  64. if (elt)
  65. elt->next = NULL;
  66. if (!elt)
  67. return head;
  68. if (!head)
  69. return elt;
  70. if (!cmp)
  71. return listapp(head, elt);
  72. for (item = head; item; item = item->next) {
  73. /*
  74. * cmp (sample, each):
  75. * Answers if each is smaller/equal/greater than sample
  76. */
  77. if ((*cmp) (elt, item) > 0)
  78. break;
  79. prev = item;
  80. }
  81. if (!prev) {
  82. elt->next = head;
  83. head = elt;
  84. }
  85. else {
  86. elt->next = prev->next;
  87. prev->next = elt;
  88. }
  89. return head;
  90. }
  91. /*
  92. * listaddnth() make new item the nth of the list
  93. * (nth <= 0) -> listprep(), (nth > listcnt()) -> listapp()
  94. */
  95. LIST *listaddnth(LIST * head, LIST * elt, int nth)
  96. {
  97. LIST *item, *prev = NULL;
  98. int i;
  99. if (elt)
  100. elt->next = NULL;
  101. if (!head)
  102. return elt;
  103. if (!elt)
  104. return head;
  105. if (nth < 1) {
  106. elt->next = head;
  107. return elt;
  108. }
  109. for (i = 0, item = head; item && i < nth; item = item->next, i++)
  110. prev = item;
  111. elt->next = prev->next;
  112. prev->next = elt;
  113. return head;
  114. }
  115. /*
  116. * listprep() prepend item on list
  117. */
  118. inline LIST *listprep(LIST * head, LIST * elt)
  119. {
  120. if (elt && elt->next)
  121. elt->next = NULL;
  122. if (!head)
  123. return elt;
  124. if (!elt)
  125. return head;
  126. elt->next = head;
  127. return elt;
  128. }
  129. /*
  130. * listapp() append item to list
  131. */
  132. LIST *listapp(LIST * head, LIST * elt)
  133. {
  134. LIST *item;
  135. if (elt)
  136. elt->next = NULL;
  137. if (!head)
  138. return elt;
  139. if (!elt)
  140. return head;
  141. for (item = head; item && item->next; item = item->next) ;
  142. item->next = elt;
  143. return head;
  144. }
  145. /*
  146. * listunlink() unlink item from list
  147. */
  148. LIST *listunlink(LIST * head, LIST * elt)
  149. {
  150. LIST *item;
  151. if (!head)
  152. return NULL;
  153. if (!elt)
  154. return head;
  155. if (head == elt) {
  156. head = elt->next;
  157. elt->next = NULL;
  158. return head;
  159. }
  160. for (item = head; item && item->next != elt; item = item->next) ;
  161. if (item->next == elt) {
  162. item->next = elt->next;
  163. elt->next = NULL;
  164. }
  165. return head;
  166. }
  167. /*
  168. * listunlinknth() unlink nth element from list
  169. * listunlinknth (head, 0) == (car (list))
  170. */
  171. LIST *listunlinknth(LIST * head, int nth)
  172. {
  173. LIST *item, *elt;
  174. int i;
  175. if (!head)
  176. return NULL;
  177. if (nth < 0)
  178. return head;
  179. if (nth == 0) {
  180. item = head->next;
  181. head->next = NULL;
  182. return item;
  183. }
  184. for (i = 0, item = head; item && item->next && i < nth - 1;
  185. item = item->next, i++) ;
  186. if (item->next) {
  187. elt = item->next;
  188. item->next = elt->next;
  189. elt->next = NULL;
  190. }
  191. return head;
  192. }
  193. /*
  194. * listdel() unlink and free element from list
  195. */
  196. LIST *listdel(LIST * head, LIST * elt, freefunc func)
  197. {
  198. if (!elt)
  199. return head;
  200. if (head)
  201. head = listunlink(head, elt);
  202. if (func)
  203. (*func) (elt);
  204. G_free(elt);
  205. return head;
  206. }
  207. /*
  208. * listdelnth() unlink and free nth element from list
  209. */
  210. LIST *listdelnth(LIST * head, int nth, freefunc func)
  211. {
  212. LIST *item, *elt;
  213. int i;
  214. if (!head || nth < 0)
  215. return NULL;
  216. if (nth == 0) {
  217. elt = head;
  218. head = head->next;
  219. listdel(NULL, elt, func);
  220. return head;
  221. }
  222. for (i = 0, item = head; item && item->next && i < nth - 1;
  223. item = item->next, i++) ;
  224. if (item && item->next) {
  225. elt = item->next;
  226. item->next = elt->next;
  227. listdel(NULL, elt, func);
  228. }
  229. return head;
  230. }
  231. /*
  232. * listcnt() cound elements in list
  233. */
  234. inline int listcnt(LIST * head)
  235. {
  236. LIST *item;
  237. int n = 0;
  238. for (item = head; item; item = item->next)
  239. n++;
  240. return n;
  241. }
  242. /*
  243. * listdup() duplicate list
  244. * if cpy is NULL, create same number of empty items
  245. */
  246. LIST *listdup(LIST * head, cpyfunc cpy, size_t size)
  247. {
  248. LIST *newhead = NULL, *last = NULL, *item, *elt;
  249. for (item = head; item; item = item->next) {
  250. elt = listitem(size);
  251. if (cpy)
  252. (*cpy) (elt, item);
  253. if (!newhead)
  254. newhead = last = elt;
  255. else {
  256. last->next = elt;
  257. last = elt;
  258. }
  259. }
  260. return newhead;
  261. }
  262. /*
  263. * listsplit() make elt the head of a taillist
  264. */
  265. LIST *listsplit(LIST * head, LIST * elt)
  266. {
  267. LIST *item;
  268. if (!head || !elt)
  269. return elt;
  270. if (head == elt)
  271. return NULL;
  272. for (item = head; item && item->next != elt; item = item->next) ;
  273. if (item->next == elt)
  274. item->next = NULL;
  275. return elt;
  276. }
  277. /*
  278. * listsplitnth() make nth element the head of a taillist
  279. */
  280. LIST *listsplitnth(LIST * head, int nth)
  281. {
  282. LIST *item, *tail = NULL;
  283. int i;
  284. if (!head || nth < 1)
  285. return NULL;
  286. for (i = 0, item = head; item && i < nth - 1; item = item->next, i++) ;
  287. if (item && item->next) {
  288. tail = item->next;
  289. item->next = NULL;
  290. }
  291. return tail;
  292. }
  293. /*
  294. * listjoin() joint two lists
  295. */
  296. LIST *listjoin(LIST * head, LIST * tail)
  297. {
  298. LIST *item;
  299. if (!head)
  300. return tail;
  301. if (!tail)
  302. return head;
  303. for (item = head; item && item->next; item = item->next) ;
  304. if (item)
  305. item->next = tail;
  306. return head;
  307. }
  308. /*
  309. * listsort() Quick sort on list
  310. */
  311. LIST *listsort(LIST * head, cmpfunc cmp)
  312. {
  313. LIST *high = NULL, *low = NULL, *item, *next;
  314. if (!head || !head->next)
  315. return head;
  316. for (item = head; item;) {
  317. next = item->next;
  318. if ((*cmp) (item, head) < 0) {
  319. item->next = low;
  320. low = item;
  321. }
  322. else {
  323. item->next = high;
  324. high = item;
  325. }
  326. item = next;
  327. }
  328. high = listsort(high, cmp);
  329. low = listsort(low, cmp);
  330. head = listjoin(high, low);
  331. return head;
  332. }
  333. /*
  334. * listrev() reverse order the list
  335. */
  336. LIST *listrev(LIST * head)
  337. {
  338. LIST *newhead = NULL, *item, *next;
  339. for (item = head; item;) {
  340. next = item->next;
  341. newhead = listprep(newhead, item);
  342. item = next;
  343. }
  344. return newhead;
  345. }
  346. /*
  347. * listshuffle()
  348. */
  349. LIST *listshuffle(LIST * head)
  350. {
  351. LIST **array, *newhead = NULL;
  352. int n, i = 0, val;
  353. struct timeval tv;
  354. gettimeofday(&tv, NULL);
  355. srandom(tv.tv_usec);
  356. n = listcnt(head);
  357. array = list2array(head);
  358. while (i < n) {
  359. val = random() % n;
  360. if (array[val]) {
  361. newhead = listprep(newhead, array[val]);
  362. array[val] = NULL;
  363. i++;
  364. }
  365. }
  366. G_free(array);
  367. return newhead;
  368. }
  369. /*
  370. * listdelall() free the whole list
  371. */
  372. LIST *listdelall(LIST * head, freefunc func)
  373. {
  374. LIST *item, *next;
  375. for (item = head; item;) {
  376. next = item->next;
  377. if (func)
  378. (*func) (item);
  379. G_free(item);
  380. item = next;
  381. }
  382. return NULL;
  383. }
  384. /*
  385. * list2array() build an array with members of list
  386. * array is allocated and needs to be G_free ()ed, list not changed.
  387. */
  388. LIST **list2array(LIST * head)
  389. {
  390. LIST **array, *item;
  391. int n, i;
  392. n = listcnt(head);
  393. if (!n)
  394. return NULL;
  395. array = (LIST **) G_calloc(n + 1, sizeof(LIST *));
  396. if (!array) {
  397. G_fatal_error(_("Out of memory"));
  398. exit(1);
  399. }
  400. for (i = 0, item = head; item; item = item->next, i++)
  401. array[i] = item;
  402. return array;
  403. }
  404. /*
  405. * array2list() link the elements of an array in order
  406. */
  407. LIST *array2list(LIST ** array)
  408. {
  409. LIST *head = NULL, *item = NULL;
  410. int i;
  411. if (array)
  412. head = item = array[0];
  413. for (i = 1; array && array[i]; i++) {
  414. item->next = array[i];
  415. item = item->next;
  416. }
  417. item->next = NULL;
  418. return head;
  419. }
  420. /*
  421. * listforeach() execute action on each item
  422. */
  423. inline void listforeach(LIST * head, actfunc action)
  424. {
  425. LIST *item;
  426. if (!head || !action)
  427. return;
  428. for (item = head; item; item = item->next)
  429. (*action) (item);
  430. }
  431. /*
  432. * listidx() find offset of item from head
  433. * head is offset (index) zero.
  434. */
  435. int listidx(LIST * head, LIST * elt)
  436. {
  437. LIST *item;
  438. int i;
  439. if (!elt)
  440. return -1;
  441. for (i = 0, item = head; item; item = item->next, i++)
  442. if (item == elt)
  443. break;
  444. if (!item)
  445. return -1;
  446. return i;
  447. }
  448. /*
  449. * listlast() find last item in list.
  450. */
  451. inline LIST *listlast(LIST * head)
  452. {
  453. LIST *item;
  454. for (item = head; item && item->next; item = item->next) ;
  455. return item;
  456. }
  457. /*
  458. * listnth() find nth item in list.
  459. */
  460. LIST *listnth(LIST * head, int nth)
  461. {
  462. LIST *item;
  463. int i;
  464. if (!head || nth < 0)
  465. return NULL;
  466. for (i = 0, item = head; item; item = item->next, i++)
  467. if (i == nth)
  468. break;
  469. return item;
  470. }
  471. /*
  472. * listfind() linear search giving structure as sample
  473. */
  474. LIST *listfind(LIST * head, LIST * elt, cmpfunc cmp)
  475. {
  476. LIST *item;
  477. for (item = head; item; item = item->next)
  478. if (!(*cmp) (elt, item))
  479. break;
  480. return item;
  481. }
  482. /*
  483. * listfinddatum() linear search giving sample by pointer
  484. */
  485. LIST *listfinddatum(LIST * head, void *datum, cmpfunc cmp)
  486. {
  487. LIST *item;
  488. for (item = head; item; item = item->next)
  489. if (!(*cmp) (datum, item))
  490. break;
  491. return item;
  492. }
  493. static LIST *_listbsearch(LIST * min, int max, LIST * elt, cmpfunc cmp)
  494. {
  495. LIST *item;
  496. int i, n, result;
  497. if (!min)
  498. return NULL;
  499. n = max / 2;
  500. for (i = 0, item = min; item && i < n; item = item->next, i++) ;
  501. result = (*cmp) (item, elt);
  502. if (result == 0)
  503. return item;
  504. if (n == 0) {
  505. if (max == 1 && item->next && !(*cmp) (item->next, elt))
  506. return item->next;
  507. return NULL;
  508. }
  509. if (result < 0)
  510. item = _listbsearch(min, n, elt, cmp);
  511. else
  512. item = _listbsearch(item->next, max - n - 1, elt, cmp);
  513. return item;
  514. }
  515. /*
  516. * listbsearch() binary search with struct as sample
  517. */
  518. LIST *listbsearch(LIST * head, LIST * elt, cmpfunc cmp)
  519. {
  520. LIST *item;
  521. int n, max, result;
  522. if (!head || !elt || !cmp)
  523. return NULL;
  524. max = listcnt(head);
  525. n = max / 2;
  526. item = listnth(head, n);
  527. result = (*cmp) (item, elt);
  528. if (result == 0)
  529. return item;
  530. if (result < 0)
  531. item = _listbsearch(head, n, elt, cmp);
  532. else
  533. item = _listbsearch(item->next, max - n - 1, elt, cmp);
  534. return item;
  535. }
  536. static LIST *_listbsearchdatum(LIST * min, int max, const void *datum,
  537. cmpfunc cmp)
  538. {
  539. LIST *elt;
  540. int i, n, result;
  541. if (!min)
  542. return NULL;
  543. n = max / 2;
  544. for (i = 0, elt = min; elt && i < n; elt = elt->next, i++) ;
  545. result = (*cmp) (datum, elt);
  546. if (result == 0)
  547. return elt;
  548. if (n == 0) {
  549. if (max == 1 && elt->next && !(*cmp) (datum, elt->next))
  550. return elt->next;
  551. return NULL;
  552. }
  553. if (result < 0)
  554. elt = _listbsearchdatum(min, n, datum, cmp);
  555. else
  556. elt = _listbsearchdatum(elt->next, max - n - 1, datum, cmp);
  557. return elt;
  558. }
  559. /*
  560. * listbsearchdatum() binary search for sample by ptr
  561. */
  562. LIST *listbsearchdatum(LIST * head, const void *datum, cmpfunc cmp)
  563. {
  564. LIST *elt;
  565. int n, max, result;
  566. if (!head || !datum || !cmp)
  567. return NULL;
  568. max = listcnt(head);
  569. n = max / 2;
  570. elt = listnth(head, n);
  571. result = (*cmp) (datum, elt);
  572. if (result == 0)
  573. return elt;
  574. if (result < 0)
  575. elt = _listbsearchdatum(head, n, datum, cmp);
  576. else
  577. elt = _listbsearchdatum(elt->next, max - n - 1, datum, cmp);
  578. return elt;
  579. }