Cleanup: style, use braces for blenlib
[blender.git] / source / blender / blenlib / intern / listbase.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  */
19
20 /** \file
21  * \ingroup bli
22  *
23  * Manipulations on double-linked list (#ListBase structs).
24  *
25  * For single linked lists see 'BLI_linklist.h'
26  */
27
28 #include <string.h>
29 #include <stdlib.h>
30
31
32 #include "MEM_guardedalloc.h"
33
34 #include "DNA_listBase.h"
35
36 #include "BLI_listbase.h"
37
38 #include "BLI_strict_flags.h"
39
40 /* implementation */
41
42 /**
43  * moves the entire contents of \a src onto the end of \a dst.
44  */
45 void BLI_movelisttolist(ListBase *dst, ListBase *src)
46 {
47         if (src->first == NULL) {
48                 return;
49         }
50
51         if (dst->first == NULL) {
52                 dst->first = src->first;
53                 dst->last = src->last;
54         }
55         else {
56                 ((Link *)dst->last)->next = src->first;
57                 ((Link *)src->first)->prev = dst->last;
58                 dst->last = src->last;
59         }
60         src->first = src->last = NULL;
61 }
62
63 /**
64  * moves the entire contents of \a src at the begining of \a dst.
65  */
66 void BLI_movelisttolist_reverse(ListBase *dst, ListBase *src)
67 {
68         if (src->first == NULL) {
69                 return;
70         }
71
72         if (dst->first == NULL) {
73                 dst->first = src->first;
74                 dst->last = src->last;
75         }
76         else {
77                 ((Link *)src->last)->next = dst->first;
78                 ((Link *)dst->first)->prev = src->last;
79                 dst->first = src->first;
80         }
81
82         src->first = src->last = NULL;
83 }
84
85 /**
86  * Prepends \a vlink (assumed to begin with a Link) onto listbase.
87  */
88 void BLI_addhead(ListBase *listbase, void *vlink)
89 {
90         Link *link = vlink;
91
92         if (link == NULL) {
93                 return;
94         }
95
96         link->next = listbase->first;
97         link->prev = NULL;
98
99         if (listbase->first) {
100                 ((Link *)listbase->first)->prev = link;
101         }
102         if (listbase->last == NULL) {
103                 listbase->last = link;
104         }
105         listbase->first = link;
106 }
107
108
109 /**
110  * Appends \a vlink (assumed to begin with a Link) onto listbase.
111  */
112 void BLI_addtail(ListBase *listbase, void *vlink)
113 {
114         Link *link = vlink;
115
116         if (link == NULL) {
117                 return;
118         }
119
120         link->next = NULL;
121         link->prev = listbase->last;
122
123         if (listbase->last) {
124                 ((Link *)listbase->last)->next = link;
125         }
126         if (listbase->first == NULL) {
127                 listbase->first = link;
128         }
129         listbase->last = link;
130 }
131
132
133 /**
134  * Removes \a vlink from \a listbase. Assumes it is linked into there!
135  */
136 void BLI_remlink(ListBase *listbase, void *vlink)
137 {
138         Link *link = vlink;
139
140         if (link == NULL) {
141                 return;
142         }
143
144         if (link->next) {
145                 link->next->prev = link->prev;
146         }
147         if (link->prev) {
148                 link->prev->next = link->next;
149         }
150
151         if (listbase->last == link) {
152                 listbase->last = link->prev;
153         }
154         if (listbase->first == link) {
155                 listbase->first = link->next;
156         }
157 }
158
159 /**
160  * Checks that \a vlink is linked into listbase, removing it from there if so.
161  */
162 bool BLI_remlink_safe(ListBase *listbase, void *vlink)
163 {
164         if (BLI_findindex(listbase, vlink) != -1) {
165                 BLI_remlink(listbase, vlink);
166                 return true;
167         }
168         else {
169                 return false;
170         }
171 }
172
173 /**
174  * Swaps \a vlinka and \a vlinkb in the list. Assumes they are both already in the list!
175  */
176 void BLI_listbase_swaplinks(ListBase *listbase, void *vlinka, void *vlinkb)
177 {
178         Link *linka = vlinka;
179         Link *linkb = vlinkb;
180
181         if (!linka || !linkb) {
182                 return;
183         }
184
185         if (linkb->next == linka) {
186                 SWAP(Link *, linka, linkb);
187         }
188
189         if (linka->next == linkb) {
190                 linka->next = linkb->next;
191                 linkb->prev = linka->prev;
192                 linka->prev = linkb;
193                 linkb->next = linka;
194         }
195         else {  /* Non-contiguous items, we can safely swap. */
196                 SWAP(Link *, linka->prev, linkb->prev);
197                 SWAP(Link *, linka->next, linkb->next);
198         }
199
200         /* Update neighbors of linka and linkb. */
201         if (linka->prev) {
202                 linka->prev->next = linka;
203         }
204         if (linka->next) {
205                 linka->next->prev = linka;
206         }
207         if (linkb->prev) {
208                 linkb->prev->next = linkb;
209         }
210         if (linkb->next) {
211                 linkb->next->prev = linkb;
212         }
213
214         if (listbase->last == linka) {
215                 listbase->last = linkb;
216         }
217         else if (listbase->last == linkb) {
218                 listbase->last = linka;
219         }
220
221         if (listbase->first == linka) {
222                 listbase->first = linkb;
223         }
224         else if (listbase->first == linkb) {
225                 listbase->first = linka;
226         }
227 }
228
229 /**
230  * Swaps \a vlinka and \a vlinkb from their respective lists. Assumes they are both already in their lista!
231  */
232 void BLI_listbases_swaplinks(ListBase *listbasea, ListBase *listbaseb, void *vlinka, void *vlinkb)
233 {
234         Link *linka = vlinka;
235         Link *linkb = vlinkb;
236         Link linkc = {NULL};
237
238         if (!linka || !linkb) {
239                 return;
240         }
241
242         /* Temporary link to use as placeholder of the links positions */
243         BLI_insertlinkafter(listbasea, linka, &linkc);
244
245         /* Bring linka into linkb position */
246         BLI_remlink(listbasea, linka);
247         BLI_insertlinkafter(listbaseb, linkb, linka);
248
249         /* Bring linkb into linka position */
250         BLI_remlink(listbaseb, linkb);
251         BLI_insertlinkafter(listbasea, &linkc, linkb);
252
253         /* Remove temporary link */
254         BLI_remlink(listbasea, &linkc);
255 }
256
257 /**
258  * Removes the head from \a listbase and returns it.
259  */
260 void *BLI_pophead(ListBase *listbase)
261 {
262         Link *link;
263         if ((link = listbase->first)) {
264                 BLI_remlink(listbase, link);
265         }
266         return link;
267 }
268
269
270 /**
271  * Removes the tail from \a listbase and returns it.
272  */
273 void *BLI_poptail(ListBase *listbase)
274 {
275         Link *link;
276         if ((link = listbase->last)) {
277                 BLI_remlink(listbase, link);
278         }
279         return link;
280 }
281
282 /**
283  * Removes \a vlink from listbase and disposes of it. Assumes it is linked into there!
284  */
285 void BLI_freelinkN(ListBase *listbase, void *vlink)
286 {
287         Link *link = vlink;
288
289         if (link == NULL) {
290                 return;
291         }
292
293         BLI_remlink(listbase, link);
294         MEM_freeN(link);
295 }
296
297 /**
298  * Assigns all #Link.prev pointers from #Link.next
299  */
300 static void listbase_double_from_single(Link *iter, ListBase *listbase)
301 {
302         Link *prev = NULL;
303         listbase->first = iter;
304         do {
305                 iter->prev = prev;
306                 prev = iter;
307         } while ((iter = iter->next));
308         listbase->last = prev;
309 }
310
311 #define SORT_IMPL_LINKTYPE Link
312
313 /* regular call */
314 #define SORT_IMPL_FUNC listbase_sort_fn
315 #include "list_sort_impl.h"
316 #undef SORT_IMPL_FUNC
317
318 /* reentrant call */
319 #define SORT_IMPL_USE_THUNK
320 #define SORT_IMPL_FUNC listbase_sort_fn_r
321 #include "list_sort_impl.h"
322 #undef SORT_IMPL_FUNC
323 #undef SORT_IMPL_USE_THUNK
324
325 #undef SORT_IMPL_LINKTYPE
326
327 /**
328  * Sorts the elements of listbase into the order defined by cmp
329  * (which should return 1 if its first arg should come after its second arg).
330  * This uses insertion sort, so NOT ok for large list.
331  */
332 void BLI_listbase_sort(ListBase *listbase, int (*cmp)(const void *, const void *))
333 {
334         if (listbase->first != listbase->last) {
335                 Link *head = listbase->first;
336                 head = listbase_sort_fn(head, cmp);
337                 listbase_double_from_single(head, listbase);
338         }
339 }
340
341 void BLI_listbase_sort_r(ListBase *listbase, int (*cmp)(void *, const void *, const void *), void *thunk)
342 {
343         if (listbase->first != listbase->last) {
344                 Link *head = listbase->first;
345                 head = listbase_sort_fn_r(head, cmp, thunk);
346                 listbase_double_from_single(head, listbase);
347         }
348 }
349
350 /**
351  * Inserts \a vnewlink immediately following \a vprevlink in \a listbase.
352  * Or, if \a vprevlink is NULL, puts \a vnewlink at the front of the list.
353  */
354 void BLI_insertlinkafter(ListBase *listbase, void *vprevlink, void *vnewlink)
355 {
356         Link *prevlink = vprevlink;
357         Link *newlink = vnewlink;
358
359         /* newlink before nextlink */
360         if (newlink == NULL) {
361                 return;
362         }
363
364         /* empty list */
365         if (listbase->first == NULL) {
366                 listbase->first = newlink;
367                 listbase->last = newlink;
368                 return;
369         }
370
371         /* insert at head of list */
372         if (prevlink == NULL) {
373                 newlink->prev = NULL;
374                 newlink->next = listbase->first;
375                 newlink->next->prev = newlink;
376                 listbase->first = newlink;
377                 return;
378         }
379
380         /* at end of list */
381         if (listbase->last == prevlink) {
382                 listbase->last = newlink;
383         }
384
385         newlink->next = prevlink->next;
386         newlink->prev = prevlink;
387         prevlink->next = newlink;
388         if (newlink->next) {
389                 newlink->next->prev = newlink;
390         }
391 }
392
393 /**
394  * Inserts \a vnewlink immediately preceding \a vnextlink in listbase.
395  * Or, if \a vnextlink is NULL, puts \a vnewlink at the end of the list.
396  */
397 void BLI_insertlinkbefore(ListBase *listbase, void *vnextlink, void *vnewlink)
398 {
399         Link *nextlink = vnextlink;
400         Link *newlink = vnewlink;
401
402         /* newlink before nextlink */
403         if (newlink == NULL) {
404                 return;
405         }
406
407         /* empty list */
408         if (listbase->first == NULL) {
409                 listbase->first = newlink;
410                 listbase->last = newlink;
411                 return;
412         }
413
414         /* insert at end of list */
415         if (nextlink == NULL) {
416                 newlink->prev = listbase->last;
417                 newlink->next = NULL;
418                 ((Link *)listbase->last)->next = newlink;
419                 listbase->last = newlink;
420                 return;
421         }
422
423         /* at beginning of list */
424         if (listbase->first == nextlink) {
425                 listbase->first = newlink;
426         }
427
428         newlink->next = nextlink;
429         newlink->prev = nextlink->prev;
430         nextlink->prev = newlink;
431         if (newlink->prev) {
432                 newlink->prev->next = newlink;
433         }
434 }
435
436
437 /**
438  * Insert a link in place of another, without changing it's position in the list.
439  *
440  * Puts `vnewlink` in the position of `vreplacelink`, removing `vreplacelink`.
441  * - `vreplacelink` *must* be in the list.
442  * - `vnewlink` *must not* be in the list.
443  */
444 void BLI_insertlinkreplace(ListBase *listbase, void *vreplacelink, void *vnewlink)
445 {
446         Link *l_old = vreplacelink;
447         Link *l_new = vnewlink;
448
449         /* update adjacent links */
450         if (l_old->next != NULL) {
451                 l_old->next->prev = l_new;
452         }
453         if (l_old->prev != NULL) {
454                 l_old->prev->next = l_new;
455         }
456
457         /* set direct links */
458         l_new->next = l_old->next;
459         l_new->prev = l_old->prev;
460
461          /* update list */
462         if (listbase->first == l_old) {
463                 listbase->first = l_new;
464         }
465         if (listbase->last == l_old) {
466                 listbase->last = l_new;
467         }
468 }
469
470 /**
471  * Reinsert \a vlink relative to its current position but offset by \a step. Doesn't move
472  * item if new position would exceed list (could optionally move to head/tail).
473  *
474  * \param step: Absolute value defines step size, sign defines direction. E.g pass -1
475  *              to move \a vlink before previous, or 1 to move behind next.
476  * \return If position of \a vlink has changed.
477  */
478 bool BLI_listbase_link_move(ListBase *listbase, void *vlink, int step)
479 {
480         Link *link = vlink;
481         Link *hook = link;
482         const bool is_up = step < 0;
483
484         if (step == 0) {
485                 return false;
486         }
487         BLI_assert(BLI_findindex(listbase, link) != -1);
488
489         /* find link to insert before/after */
490         for (int i = 0; i < ABS(step); i++) {
491                 hook = is_up ? hook->prev : hook->next;
492                 if (!hook) {
493                         return false;
494                 }
495         }
496
497         /* reinsert link */
498         BLI_remlink(listbase, vlink);
499         if (is_up) {
500                 BLI_insertlinkbefore(listbase, hook, vlink);
501         }
502         else {
503                 BLI_insertlinkafter(listbase, hook, vlink);
504         }
505         return true;
506 }
507
508
509 /**
510  * Removes and disposes of the entire contents of listbase using direct free(3).
511  */
512 void BLI_freelist(ListBase *listbase)
513 {
514         Link *link, *next;
515
516         link = listbase->first;
517         while (link) {
518                 next = link->next;
519                 free(link);
520                 link = next;
521         }
522
523         BLI_listbase_clear(listbase);
524 }
525
526 /**
527  * Removes and disposes of the entire contents of \a listbase using guardedalloc.
528  */
529 void BLI_freelistN(ListBase *listbase)
530 {
531         Link *link, *next;
532
533         link = listbase->first;
534         while (link) {
535                 next = link->next;
536                 MEM_freeN(link);
537                 link = next;
538         }
539
540         BLI_listbase_clear(listbase);
541 }
542
543 /**
544  * Returns the number of elements in \a listbase, up until (and including count_max)
545  *
546  * \note Use to avoid redundant looping.
547  */
548 int BLI_listbase_count_at_most(const ListBase *listbase, const int count_max)
549 {
550         Link *link;
551         int count = 0;
552
553         for (link = listbase->first; link && count != count_max; link = link->next) {
554                 count++;
555         }
556
557         return count;
558 }
559
560 /**
561  * Returns the number of elements in \a listbase.
562  */
563 int BLI_listbase_count(const ListBase *listbase)
564 {
565         Link *link;
566         int count = 0;
567
568         for (link = listbase->first; link; link = link->next) {
569                 count++;
570         }
571
572         return count;
573 }
574
575 /**
576  * Returns the nth element of \a listbase, numbering from 0.
577  */
578 void *BLI_findlink(const ListBase *listbase, int number)
579 {
580         Link *link = NULL;
581
582         if (number >= 0) {
583                 link = listbase->first;
584                 while (link != NULL && number != 0) {
585                         number--;
586                         link = link->next;
587                 }
588         }
589
590         return link;
591 }
592
593 /**
594  * Returns the nth-last element of \a listbase, numbering from 0.
595  */
596 void *BLI_rfindlink(const ListBase *listbase, int number)
597 {
598         Link *link = NULL;
599
600         if (number >= 0) {
601                 link = listbase->last;
602                 while (link != NULL && number != 0) {
603                         number--;
604                         link = link->prev;
605                 }
606         }
607
608         return link;
609 }
610
611 /**
612  * Returns the position of \a vlink within \a listbase, numbering from 0, or -1 if not found.
613  */
614 int BLI_findindex(const ListBase *listbase, const void *vlink)
615 {
616         Link *link = NULL;
617         int number = 0;
618
619         if (vlink == NULL) {
620                 return -1;
621         }
622
623         link = listbase->first;
624         while (link) {
625                 if (link == vlink) {
626                         return number;
627                 }
628
629                 number++;
630                 link = link->next;
631         }
632
633         return -1;
634 }
635
636 /**
637  * Finds the first element of \a listbase which contains the null-terminated
638  * string \a id at the specified offset, returning NULL if not found.
639  */
640 void *BLI_findstring(const ListBase *listbase, const char *id, const int offset)
641 {
642         Link *link = NULL;
643         const char *id_iter;
644
645         if (id == NULL) {
646                 return NULL;
647         }
648
649         for (link = listbase->first; link; link = link->next) {
650                 id_iter = ((const char *)link) + offset;
651
652                 if (id[0] == id_iter[0] && STREQ(id, id_iter)) {
653                         return link;
654                 }
655         }
656
657         return NULL;
658 }
659 /* same as above but find reverse */
660 /**
661  * Finds the last element of \a listbase which contains the
662  * null-terminated string \a id at the specified offset, returning NULL if not found.
663  */
664 void *BLI_rfindstring(const ListBase *listbase, const char *id, const int offset)
665 {
666         Link *link = NULL;
667         const char *id_iter;
668
669         for (link = listbase->last; link; link = link->prev) {
670                 id_iter = ((const char *)link) + offset;
671
672                 if (id[0] == id_iter[0] && STREQ(id, id_iter)) {
673                         return link;
674                 }
675         }
676
677         return NULL;
678 }
679
680 /**
681  * Finds the first element of \a listbase which contains a pointer to the
682  * null-terminated string \a id at the specified offset, returning NULL if not found.
683  */
684 void *BLI_findstring_ptr(const ListBase *listbase, const char *id, const int offset)
685 {
686         Link *link = NULL;
687         const char *id_iter;
688
689         for (link = listbase->first; link; link = link->next) {
690                 /* exact copy of BLI_findstring(), except for this line */
691                 id_iter = *((const char **)(((const char *)link) + offset));
692
693                 if (id[0] == id_iter[0] && STREQ(id, id_iter)) {
694                         return link;
695                 }
696         }
697
698         return NULL;
699 }
700 /* same as above but find reverse */
701 /**
702  * Finds the last element of \a listbase which contains a pointer to the
703  * null-terminated string \a id at the specified offset, returning NULL if not found.
704  */
705 void *BLI_rfindstring_ptr(const ListBase *listbase, const char *id, const int offset)
706 {
707         Link *link = NULL;
708         const char *id_iter;
709
710         for (link = listbase->last; link; link = link->prev) {
711                 /* exact copy of BLI_rfindstring(), except for this line */
712                 id_iter = *((const char **)(((const char *)link) + offset));
713
714                 if (id[0] == id_iter[0] && STREQ(id, id_iter)) {
715                         return link;
716                 }
717         }
718
719         return NULL;
720 }
721
722 /**
723  * Finds the first element of listbase which contains the specified pointer value
724  * at the specified offset, returning NULL if not found.
725  */
726 void *BLI_findptr(const ListBase *listbase, const void *ptr, const int offset)
727 {
728         Link *link = NULL;
729         const void *ptr_iter;
730
731         for (link = listbase->first; link; link = link->next) {
732                 /* exact copy of BLI_findstring(), except for this line */
733                 ptr_iter = *((const void **)(((const char *)link) + offset));
734
735                 if (ptr == ptr_iter) {
736                         return link;
737                 }
738         }
739
740         return NULL;
741 }
742 /* same as above but find reverse */
743 /**
744  * Finds the last element of listbase which contains the specified pointer value
745  * at the specified offset, returning NULL if not found.
746  */
747 void *BLI_rfindptr(const ListBase *listbase, const void *ptr, const int offset)
748 {
749         Link *link = NULL;
750         const void *ptr_iter;
751
752         for (link = listbase->last; link; link = link->prev) {
753                 /* exact copy of BLI_rfindstring(), except for this line */
754                 ptr_iter = *((const void **)(((const char *)link) + offset));
755
756                 if (ptr == ptr_iter) {
757                         return link;
758                 }
759         }
760
761         return NULL;
762 }
763
764 /**
765  * Finds the first element of listbase which contains the specified bytes
766  * at the specified offset, returning NULL if not found.
767  */
768 void *BLI_listbase_bytes_find(const ListBase *listbase, const void *bytes, const size_t bytes_size, const int offset)
769 {
770         Link *link = NULL;
771         const void *ptr_iter;
772
773         for (link = listbase->first; link; link = link->next) {
774                 ptr_iter = (const void *)(((const char *)link) + offset);
775
776                 if (memcmp(bytes, ptr_iter, bytes_size) == 0) {
777                         return link;
778                 }
779         }
780
781         return NULL;
782 }
783 /* same as above but find reverse */
784 /**
785  * Finds the last element of listbase which contains the specified bytes
786  * at the specified offset, returning NULL if not found.
787  */
788 void *BLI_listbase_bytes_rfind(const ListBase *listbase, const void *bytes, const size_t bytes_size, const int offset)
789 {
790         Link *link = NULL;
791         const void *ptr_iter;
792
793         for (link = listbase->last; link; link = link->prev) {
794                 ptr_iter = (const void *)(((const char *)link) + offset);
795
796                 if (memcmp(bytes, ptr_iter, bytes_size) == 0) {
797                         return link;
798                 }
799         }
800
801         return NULL;
802 }
803
804 /**
805  * Returns the 0-based index of the first element of listbase which contains the specified
806  * null-terminated string at the specified offset, or -1 if not found.
807  */
808 int BLI_findstringindex(const ListBase *listbase, const char *id, const int offset)
809 {
810         Link *link = NULL;
811         const char *id_iter;
812         int i = 0;
813
814         link = listbase->first;
815         while (link) {
816                 id_iter = ((const char *)link) + offset;
817
818                 if (id[0] == id_iter[0] && STREQ(id, id_iter)) {
819                         return i;
820                 }
821                 i++;
822                 link = link->next;
823         }
824
825         return -1;
826 }
827
828 /**
829  * Sets dst to a duplicate of the entire contents of src. dst may be the same as src.
830  */
831 void BLI_duplicatelist(ListBase *dst, const ListBase *src)
832 {
833         struct Link *dst_link, *src_link;
834
835         /* in this order, to ensure it works if dst == src */
836         src_link = src->first;
837         dst->first = dst->last = NULL;
838
839         while (src_link) {
840                 dst_link = MEM_dupallocN(src_link);
841                 BLI_addtail(dst, dst_link);
842
843                 src_link = src_link->next;
844         }
845 }
846
847 void BLI_listbase_reverse(ListBase *lb)
848 {
849         struct Link *curr = lb->first;
850         struct Link *prev = NULL;
851         struct Link *next = NULL;
852         while (curr) {
853                 next = curr->next;
854                 curr->next = prev;
855                 curr->prev = next;
856                 prev = curr;
857                 curr = next;
858         }
859
860         /* swap first/last */
861         curr = lb->first;
862         lb->first = lb->last;
863         lb->last = curr;
864 }
865
866 /**
867  * \param vlink: Link to make first.
868  */
869 void BLI_listbase_rotate_first(ListBase *lb, void *vlink)
870 {
871         /* make circular */
872         ((Link *)lb->first)->prev = lb->last;
873         ((Link *)lb->last)->next = lb->first;
874
875         lb->first = vlink;
876         lb->last = ((Link *)vlink)->prev;
877
878         ((Link *)lb->first)->prev = NULL;
879         ((Link *)lb->last)->next = NULL;
880 }
881
882 /**
883  * \param vlink: Link to make last.
884  */
885 void BLI_listbase_rotate_last(ListBase *lb, void *vlink)
886 {
887         /* make circular */
888         ((Link *)lb->first)->prev = lb->last;
889         ((Link *)lb->last)->next = lb->first;
890
891         lb->first = ((Link *)vlink)->next;
892         lb->last = vlink;
893
894         ((Link *)lb->first)->prev = NULL;
895         ((Link *)lb->last)->next = NULL;
896 }
897
898 /* create a generic list node containing link to provided data */
899 LinkData *BLI_genericNodeN(void *data)
900 {
901         LinkData *ld;
902
903         if (data == NULL) {
904                 return NULL;
905         }
906
907         /* create new link, and make it hold the given data */
908         ld = MEM_callocN(sizeof(LinkData), __func__);
909         ld->data = data;
910
911         return ld;
912 }