You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

llist.c 16KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634
  1. /* This file is part of Netsukuku
  2. * (c) Copyright 2005 Andrea Lo Pumo aka AlpT <alpt@freaknet.org>
  3. *
  4. * This source code is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License as published
  6. * by the Free Software Foundation; either version 2 of the License,
  7. * or (at your option) any later version.
  8. *
  9. * This source code is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12. * Please refer to the GNU Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Public License along with
  15. * this source code; if not, write to:
  16. * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. *
  18. * --
  19. *
  20. * llist.c: Various functions to handle (doubled) linked lists
  21. *
  22. * Why did I used macros for all these functions?
  23. * Well, I just love the blue-smurf-like syntax highlighting of Vim ^_-
  24. *
  25. * Moreover using `typeof' and other nice tricks each macro can recognize the
  26. * size of the arguments, in this way we can have functions like `list_copy',
  27. * `list_init'.
  28. * Finally, performance is optimised. I don't trust gcc and its -O2, (and they
  29. * don't trust me).
  30. */
  31. #ifndef LLIST_C
  32. #define LLIST_C
  33. /*
  34. * This struct is used as a header to handle all the linked list struct.
  35. * The only limitation is to put _EXACTLY_
  36. * struct bla_bla *next;
  37. * struct bla_bla *prev;
  38. * at the beginning.
  39. * You can also use the LLIST_HDR() macro.
  40. */
  41. #define LLIST_HDR(_struct) _struct *next, *prev
  42. struct linked_list {
  43. LLIST_HDR(struct linked_list);
  44. } linked_list;
  45. typedef struct linked_list l_list;
  46. #define is_list_zero(list) \
  47. ({ \
  48. int _iz, _rz=1; \
  49. char *_a=(char *)(list); \
  50. for(_iz=0; _iz<sizeof(typeof(*(list))); _iz++, _a++) \
  51. if(*_a) { \
  52. _rz=0; \
  53. break; \
  54. } \
  55. _rz; \
  56. })
  57. /*
  58. * list_copy
  59. *
  60. * It copies just the contents of `new' in `list' without overwriting the
  61. * ->prev and ->next pointers.
  62. */
  63. #define list_copy(list, new) \
  64. do{ \
  65. l_list _oc, *_lc=(l_list *)(list); \
  66. if((new)) { \
  67. _oc.prev=_lc->prev; \
  68. _oc.next=_lc->next; \
  69. memcpy((list), (new), sizeof(typeof(*(new)))); \
  70. _lc->prev=_oc.prev; \
  71. _lc->next=_oc.next; \
  72. } \
  73. } while(0)
  74. /*
  75. * list_dup
  76. *
  77. * the strdup equivalent of a single llist
  78. */
  79. #define list_dup(list) \
  80. ({ \
  81. l_list *_dd; \
  82. _dd=xmalloc(sizeof(typeof(*(list)))); \
  83. memset(_dd, 0, sizeof(typeof(*(list)))); \
  84. list_copy(_dd, (list)); \
  85. (typeof((list)))_dd; \
  86. })
  87. /*
  88. * list_init
  89. *
  90. * If `new' is 0, it stores in `list' a pointer to a newly mallocated
  91. * and zeroed struct.
  92. * Its type is the same of `list'.
  93. * If `new' is non zero, then `list' is simply set to `new'.
  94. * The ->prev and ->next pointers are always set to zero.
  95. */
  96. #define list_init(list, new) \
  97. do { \
  98. l_list *_li; \
  99. if((new)) \
  100. (list)=(new); \
  101. else \
  102. (list)=(typeof (list))xmalloc(sizeof(typeof(*(list)))); \
  103. _li=(l_list *)(list); \
  104. _li->prev=0; \
  105. _li->next=0; \
  106. if(!(new)) \
  107. memset((list), 0, sizeof(typeof(*(list)))); \
  108. } while (0)
  109. /*
  110. * list_last
  111. *
  112. * It returns the last element of the `list' llist
  113. */
  114. #define list_last(list) \
  115. ({ \
  116. l_list *_il=(l_list *)(list); \
  117. for(; _il && _il->next; _il=(l_list *)_il->next); \
  118. _il; \
  119. })
  120. /*
  121. * list_head
  122. *
  123. * Returns the head of the linked list.
  124. */
  125. #define list_head(tail) \
  126. ({ \
  127. l_list *_ih=(l_list *)(list); \
  128. for(; _ih && _ih->prev; _ih=(l_list *)_ih->prev); \
  129. (typeof((list)))_ih; \
  130. })
  131. /*
  132. * list_append
  133. *
  134. * It appends the `_new' struct at the end of the `_head' llist.
  135. * If `_tail' is not 0, then it is considered as the end of the llist and the
  136. * `_head' argument isn't required.
  137. * If `_tail' is 0, the end will be reached by traversing the entire llist,
  138. * starting from `_head'.
  139. * If both `_tail' and `_head' are 0, `new->next' and `new->prev' will be set
  140. * to 0.
  141. * The new tail is always returned.
  142. * Example: tail=list_append(0, tail, new);
  143. * or
  144. * list_append(head, 0, new);
  145. */
  146. #define list_append(_head, _tail, _new) \
  147. ({ \
  148. l_list *_tt, *_na; \
  149. _tt=(_tail) ? (l_list *)(_tail) : (l_list *)list_last((_head)); \
  150. _na=(l_list *)(_new); \
  151. if(_na != _tt) { \
  152. if(_tt) \
  153. _tt->next=_na; \
  154. if(_na) { \
  155. _na->prev=_tt; \
  156. _na->next=0; \
  157. } \
  158. } \
  159. _new; \
  160. })
  161. /*
  162. * list_add
  163. *
  164. * It adds the `_new' struct at the start of the `_head' llist.
  165. * The new head of the llist is returned.
  166. *
  167. * Example:
  168. * head=list_add(head, new);
  169. */
  170. #define list_add(_head, _new) \
  171. ({ \
  172. l_list *_hd, *_nd; \
  173. _hd=(l_list *)(_head); \
  174. _nd=(l_list *)(_new); \
  175. if(_hd != _nd) { \
  176. _nd->next=_hd; \
  177. _nd->prev=0; \
  178. if(_hd) \
  179. _hd->prev=_nd; \
  180. } \
  181. (typeof((_head)))_nd; \
  182. })
  183. /*
  184. * list_join:
  185. * before list_join(list):
  186. * ... <-> A <-> list <-> C <-> ...
  187. * after:
  188. * ... <-> A <-> C <-> ...
  189. * Note that `list' is not freed!
  190. * It returns the head of the list, so call it in this way:
  191. * head=list_join(head, list);
  192. */
  193. #define list_join(head, list) \
  194. ({ \
  195. l_list *_lj=(l_list *)(list), *_hj=(l_list *)(head), *_ret; \
  196. if(_lj->next) \
  197. _lj->next->prev=_lj->prev; \
  198. if(_lj->prev) \
  199. _lj->prev->next=_lj->next; \
  200. _ret = _lj == _hj ? _lj->next : _hj; \
  201. (typeof((head)))_ret; \
  202. })
  203. #define list_free(list) \
  204. do { \
  205. memset((list), 0, sizeof(typeof(*(list)))); \
  206. xfree((list)); \
  207. } while(0)
  208. /*
  209. * list_del
  210. *
  211. * It's the same of list_join() but it frees the `list'.
  212. * It returns the new head of the linked list, so it must be called in
  213. * this way: head=list_del(head, list);
  214. */
  215. #define list_del(head, list) \
  216. ({ \
  217. l_list *_lid=(l_list *)(list), *_hed=(l_list *)(head); \
  218. \
  219. _hed=(l_list *)list_join((head), _lid); \
  220. list_free(_lid); \
  221. (typeof((head)))_hed; \
  222. })
  223. /*
  224. * list_ins
  225. *
  226. * It inserts the `new' struct between the `list' and `list'->next
  227. * structs.
  228. */
  229. #define list_ins(list, new) \
  230. do { \
  231. l_list *_lin=(l_list *)(list), *_n=(l_list *)(new); \
  232. if(_lin->next) \
  233. _lin->next->prev=_n; \
  234. _n->next=_lin->next; \
  235. _lin->next=_n; \
  236. _n->prev=_lin; \
  237. } while (0)
  238. /*
  239. * list_substitute
  240. *
  241. * It removes from the llist the `old_list' struct and inserts in its
  242. * position the `new_list' struct
  243. * Note that `old_list' isn't freed, it is just unlinked from the llist.
  244. */
  245. #define list_substitute(old_list, new_list) \
  246. do{ \
  247. l_list *_ns, *_os; \
  248. _ns=(l_list *)(new_list); \
  249. _os=(l_list *)(old_list); \
  250. if(_os->next != _ns) \
  251. _ns->next=_os->next; \
  252. if(_os->prev != _ns) \
  253. _ns->prev=_os->prev; \
  254. if(_ns->next) \
  255. _ns->next->prev=_ns; \
  256. if(_ns->prev) \
  257. _ns->prev->next=_ns; \
  258. }while(0)
  259. /*
  260. * list_swap
  261. *
  262. * Before: H -> Y <-> [A] <-> I <-> [B] <-> P <-> T
  263. * list_swap(A, B);
  264. * After: H -> Y <-> [B] <-> I <-> [A] <-> P <-> T
  265. */
  266. #define list_swap(a, b) \
  267. do{ \
  268. l_list _ltmp, *_aa, *_bb; \
  269. _aa=(l_list *)(a); \
  270. _bb=(l_list *)(b); \
  271. if(_aa->next == _bb) { \
  272. list_substitute(_aa, _bb); \
  273. list_ins(_bb, _aa); \
  274. } else if(_aa->prev == _bb) { \
  275. list_substitute(_bb, _aa); \
  276. list_ins(_aa, _bb); \
  277. } else { \
  278. _ltmp.next=(l_list *)_bb->next; \
  279. _ltmp.prev=(l_list *)_bb->prev; \
  280. list_substitute(_aa, _bb); \
  281. list_substitute(&_ltmp, _aa); \
  282. } \
  283. }while(0)
  284. /*
  285. * list_moveback
  286. *
  287. * It swaps `list' with its previous struct
  288. */
  289. #define list_moveback(list) \
  290. do{ \
  291. l_list *_lm=(l_list *)(list); \
  292. if(_lm->prev) \
  293. list_swap(_lm->prev, _lm); \
  294. }while(0)
  295. /*
  296. * list_movefwd
  297. *
  298. * It swaps `list' with its next struct
  299. */
  300. #define list_movefwd(list) \
  301. do{ \
  302. l_list *_lmf=(l_list *)(list); \
  303. if(_lmf->next) \
  304. list_swap(_lmf->next, _lmf); \
  305. }while(0)
  306. /*
  307. * list_moveontop
  308. *
  309. * `_list' must be already present in the `_head' llist, otherwise this
  310. * function is just equal to list_add().
  311. *
  312. * list_moveontop() moves `_list' on top of the `_head' llist, thus:
  313. * - `_list' is joined (see list_join() above)
  314. * - `_list' becomes the new head
  315. * - `_head' goes in `_list'->next
  316. * The new head of the llist is returned.
  317. *
  318. * Example: head=list_moveontop(head, list);
  319. */
  320. #define list_moveontop(_head, _list) \
  321. ({ \
  322. l_list *_hmt=(l_list *)(_head), *_lmt=(l_list *)(_list); \
  323. \
  324. if(_hmt != _lmt) { \
  325. _hmt=(l_list *)list_join((typeof((_head)))_hmt, _lmt); \
  326. _hmt=(l_list *)list_add((typeof((_head)))_hmt, _lmt); \
  327. } \
  328. (typeof((_head)))_hmt; \
  329. })
  330. /*
  331. * list_for
  332. *
  333. * Pretty simple, use it in this way:
  334. * my_llist_ptr *index;
  335. * index=head_of_the_llist;
  336. * list_for(index) {
  337. * do_something_with(index);
  338. * }
  339. *
  340. * WARNING: do not use expressions!! For example:
  341. * DO NOT THIS
  342. * list_for(index=head_of_the_llist) {
  343. * ...
  344. * }
  345. * DO NOT THIS
  346. * In this case `index' will be set to `head_of_the_llist' each time and
  347. * you'll get an infinite loop;
  348. */
  349. #define list_for(i) for(; (i); (i)=(typeof (i))(i)->next)
  350. /*
  351. * list_count
  352. *
  353. * Returns the number of structs present in the llist
  354. */
  355. #define list_count(_head) \
  356. ({ \
  357. l_list *_lc=(l_list *)(_head); \
  358. int _ic=0; \
  359. \
  360. list_for(_lc) \
  361. _ic++; \
  362. _ic; \
  363. })
  364. /*
  365. * list_safe_for
  366. *
  367. * Use this for if you want to do something like:
  368. * list_for(list)
  369. * list_del(list);
  370. * If you are trying to do that, the normal list_for isn't safe! That's
  371. * because when list_del will free the current `list', list_for will use a
  372. * wrong list->next pointer, which doesn't exist at all.
  373. * list_for_del is the same as list_for but it takes a second parameter, which
  374. * is a list pointer. This pointer will be used to store, before executing the
  375. * code inside the for, the list->next pointer.
  376. * So this is a safe for. Example:
  377. *
  378. * l_list *ptr;
  379. * list_safe_for(list, ptr) {
  380. * ... do stuff ...
  381. * }
  382. *
  383. * WARNING: do not use expressions in the arguments, (see the warning above
  384. * for the normal list_for)
  385. */
  386. #define list_safe_for(_ii, _next_ptr) \
  387. for((_ii) ? (_next_ptr)=(typeof (_ii))(_ii)->next : 0; (_ii); \
  388. (_ii)=(_next_ptr), (_ii) ? (_next_ptr)=(typeof (_ii))(_ii)->next : 0)
  389. /*
  390. * list_pos: returns the `pos'-th struct present in `list'
  391. */
  392. #define list_pos(list, pos) \
  393. ({ \
  394. int _ip=0; \
  395. l_list *_xp=(l_list *)(list); \
  396. list_for(_xp) { \
  397. if(_ip==(pos)) \
  398. break; \
  399. else \
  400. _ip++; \
  401. } \
  402. (typeof((list)))_xp; \
  403. })
  404. /*
  405. * list_get_pos: returns the position of the `list' struct in the `head'
  406. * linked list, so that list_pos(head, list_get_pos(head, list)) == list
  407. * If `list' is not present in the linked list, -1 is returned.
  408. */
  409. #define list_get_pos(head, list) \
  410. ({ \
  411. int _igp=0, _egp=0; \
  412. l_list *_xgp=(l_list *)(head); \
  413. \
  414. list_for(_xgp) { \
  415. if(_xgp == (l_list *)(list)) { \
  416. _egp=1; \
  417. break; \
  418. } else \
  419. _igp++; \
  420. } \
  421. _egp ? _igp : -1; \
  422. })
  423. /*
  424. * list_destroy
  425. *
  426. * It traverse the entire `list' llist and calls list_del() on each
  427. * struct.
  428. */
  429. #define list_destroy(list) \
  430. do{ \
  431. l_list *_xd=(l_list *)(list), *_id, *_nextd; \
  432. _id=_xd; \
  433. list_safe_for(_id, _nextd) \
  434. _xd=list_del(_xd, _id); \
  435. (list)=0; \
  436. }while(0)
  437. /*
  438. * list_copy_some
  439. *
  440. * It calls the `check_func' function for each struct of the `list' llist,
  441. * passing to it, as first argument, a pointer to the struct itself.
  442. * The other parameters to list_copy_some are passed to `check_func', for
  443. * example by calling:
  444. * list_copy_some(list, my_check_func, arg1, arg2, arg3);
  445. * the `my_check_func' will be called in this way:
  446. * my_check_func(arg1, arg2, arg3);
  447. *
  448. * If the `check_func' function returns a non zero value, the struct is
  449. * copied in a new allocated space.
  450. * All the copied structs form the replicated llist.
  451. * Its head is returned.
  452. *
  453. * The `list' llist is not modified.
  454. */
  455. #define list_copy_some(list, check_func, func_args...) \
  456. ({ \
  457. l_list *_ncs=0, *_hcs=0, *_tcs=0, *_lcs=(l_list *)(list); \
  458. \
  459. list_for(_lcs) { \
  460. if(!check_func(((typeof((list)))_lcs), ## func_args )) \
  461. continue; \
  462. \
  463. _ncs=(l_list *)list_dup(((typeof((list)))_lcs)); \
  464. if(!_hcs) _hcs=_ncs; \
  465. \
  466. _tcs=list_append(0, _tcs, _ncs); \
  467. } \
  468. \
  469. (typeof((list)))_hcs; \
  470. })
  471. /*
  472. * list_copy_all
  473. *
  474. * It copies the entire `list' llist in a new allocated one.
  475. * It returns the head to the replicated llist.
  476. * The `list' llist is not modified.
  477. */
  478. #define list_copy_all_yes(_nil) (1)
  479. #define list_copy_all(list) list_copy_some((list), list_copy_all_yes)
  480. /*
  481. * Here below there are the definitions for the linked list with a counter.
  482. * The arguments format is:
  483. * l_list **_head, int *_counter, l_list *list
  484. */
  485. #define clist_add(_head, _counter, _list) \
  486. do{ \
  487. if(!(*(_counter)) || !(*(_head))) \
  488. list_init(*(_head), (_list)); \
  489. else \
  490. *((_head))=list_add(*(_head), (_list)); \
  491. (*(_counter))++; \
  492. }while(0)
  493. #define clist_append(_head, _tail, _counter, _list) \
  494. do{ \
  495. l_list *_tca=0, **_targv=(l_list **)(_tail); \
  496. if((_tail)) \
  497. _tca=*_targv; \
  498. if(!(*(_counter)) || !(*(_head))) \
  499. list_init(*(_head), (_list)); \
  500. else { \
  501. _tca=(l_list *)list_append(*(_head), _tca, (_list)); \
  502. if(_targv) \
  503. (*_targv)=_tca; \
  504. } \
  505. (*(_counter))++; \
  506. }while(0)
  507. #define clist_del(_head, _counter, _list) \
  508. do{ \
  509. if((*(_counter)) > 0) { \
  510. *((_head))=list_del(*(_head), (_list)); \
  511. (*(_counter))--; \
  512. } \
  513. }while(0)
  514. #define clist_ins(_head, _counter, _list) \
  515. do{ \
  516. if(!(*(_counter)) || !(*(_head))) \
  517. clist_add((_head), (_counter), (_list)); \
  518. else { \
  519. list_ins(*(_head), (_list)); \
  520. (*(_counter))++; \
  521. } \
  522. }while(0)
  523. #define clist_join(_head, _counter, _list) \
  524. do{ \
  525. if((*(_counter)) > 0) { \
  526. *((_head))=list_join((*(_head)), _list); \
  527. (*(_counter))--; \
  528. } \
  529. } while(0)
  530. /*
  531. * Zeros the `counter' and set the head pointer to 0.
  532. * usage: head=clist_init(&counter);
  533. */
  534. #define clist_init(_counter) \
  535. ({ \
  536. *(_counter)=0; \
  537. (uintptr_t)0; \
  538. })
  539. #define clist_destroy(_head, _counter) \
  540. ({ \
  541. list_destroy(*((_head))); \
  542. (*(_head))=0; \
  543. (*(_counter))=0; \
  544. 0; \
  545. })
  546. /*
  547. * clist_qsort
  548. *
  549. * It qsorts the `_head' llist, which has `_counter' elements.
  550. * The `_cmp_func' function will be used to compare two llist.
  551. * The new head of the llist is returned. Example:
  552. * head=clist_qsort(head, counter, my_cmp_func);
  553. * `counter' can be also 0, but it's better if you've counted already.
  554. *
  555. * Btw, this function just calls qsort(3), this is how it works:
  556. * - first of all it counts how many elements there are in the llist.
  557. * This is done only if `_counter' is 0.
  558. * - it uses a temporary callocated array to store all the pointers to the
  559. * elements of the llist.
  560. * tmp[0]=_head; tmp[1]=_head->next; tmp[..]=_head->next->..
  561. * - it calls qsort(3) on the tmp array. Note that qsort gives the
  562. * address of &tmp[x] and &tmp[y] to `_cmp_func()', thus `_cmp_func()'
  563. * should be aware of this.
  564. * - it follows the new order of `tmp' and appends each array element in
  565. * a new llist.
  566. * - the head of the new llist is assigned to _new_head
  567. */
  568. #define clist_qsort(_new_head, _head, _counter, _cmp_func) \
  569. ({ \
  570. l_list *_hcq=(l_list *)(_head), *_ncq, *_hecq, *_tcq; \
  571. int _icq=0, _ccq; \
  572. \
  573. _ccq = !(_counter) ? list_count(_hcq) : (_counter); \
  574. l_list *_tmp_list[_ccq]; \
  575. \
  576. _ncq=_hcq; \
  577. list_for(_ncq) { \
  578. _tmp_list[_icq]=_ncq; \
  579. _icq++; \
  580. } \
  581. \
  582. qsort(_tmp_list, _ccq, sizeof(l_list *), (_cmp_func)); \
  583. \
  584. _tcq=0; \
  585. _hecq=_tmp_list[0]; \
  586. for(_icq=0; _icq<_ccq; _icq++) \
  587. _tcq=(l_list *)list_append(0, _tcq, _tmp_list[_icq]); \
  588. \
  589. _new_head = (typeof((_head)))_hecq; \
  590. }) \
  591. #endif /*LLIST_C */