Rizin
unix-like reverse engineering framework and cli tools
list.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2007-2019 pancake <pancake@nopcode.org>
2 // SPDX-FileCopyrightText: 2007-2019 alvarofe <alvaro.felipe91@gmail.com>
3 // SPDX-License-Identifier: LGPL-3.0-only
4 
5 #include <stdio.h>
6 #include "rz_util.h"
7 
8 inline RzListIter *rz_list_iter_new(void) {
9  return calloc(1, sizeof(RzListIter));
10 }
11 
13  /* do nothing? */
14 }
15 
22  return list->n;
23 }
24 
31  RzListIter *n = list->n;
32  if (!n) {
33  return NULL;
34  }
35  return n->data;
36 }
37 
44  return list->data;
45 }
46 
53  return list->head;
54 }
55 
61  return rz_list_append(list, item);
62 }
63 
70  return list->n;
71 }
72 
79  return list->head ? list->head->data : NULL;
80 }
81 
88  return list->tail ? list->tail->data : NULL;
89 }
90 
97 
98  list->head = NULL;
99  list->tail = NULL;
100  list->free = NULL;
101  list->length = 0;
102  list->sorted = false;
103 }
104 
110  if (!list) {
111  return 0;
112  }
113  return list->length;
114 }
115 
122 
123  RzListIter *it = list->head;
124  while (it) {
125  RzListIter *next = it->n;
126  rz_list_delete(list, it);
127  it = next;
128  }
129  list->length = 0;
130  list->head = list->tail = NULL;
131 }
132 
138  if (list) {
140  free(list);
141  }
142 }
143 
149  rz_return_val_if_fail(list, false);
151  if (!iter) {
152  return false;
153  }
155  return true;
156 }
157 
165  if (list->free && iter->data) {
166  list->free(iter->data);
167  }
168  iter->data = NULL;
169  free(iter);
170 }
171 
174 
176  while (iter) {
177  void *item = iter->data;
178  if (ptr == item) {
180  free(iter);
181  break;
182  }
183  iter = iter->n;
184  }
185 }
186 
189 
190  if (list->head == iter) {
191  list->head = iter->n;
192  }
193  if (list->tail == iter) {
194  list->tail = iter->p;
195  }
196  if (iter->p) {
197  iter->p->n = iter->n;
198  }
199  if (iter->n) {
200  iter->n->p = iter->p;
201  }
202  list->length--;
203 }
204 
210  rz_return_val_if_fail(list1 && list2, 0);
211 
212  if (!(list2->length)) {
213  return false;
214  }
215  if (!(list1->length)) {
216  list1->head = list2->head;
217  list1->tail = list2->tail;
218  } else {
219  list1->tail->n = list2->head;
220  list2->head->p = list1->tail;
221  list1->tail = list2->tail;
222  list1->tail->n = NULL;
223  list1->sorted = false;
224  }
225  list1->length += list2->length;
226  list2->length = 0;
227  list2->head = list2->tail = NULL;
228  return true;
229 }
230 
237  if (!list) {
238  return NULL;
239  }
241  return list;
242 }
243 
249  RzList *l = rz_list_new();
250  if (l) {
251  l->free = f;
252  }
253  return l;
254 }
255 
260 RZ_API RZ_OWN RzList *rz_list_new_from_array(RZ_NONNULL const void **arr, size_t arr_size) {
261  RzList *l = rz_list_new();
262  if (!l) {
263  return NULL;
264  }
265  size_t i;
266  for (i = 0; i < arr_size; i++) {
267  rz_list_append(l, (void *)arr[i]);
268  }
269  return l;
270 }
271 
277  RzListIter *item = RZ_NEW0(RzListIter);
278  if (item) {
279  item->data = data;
280  }
281  return item;
282 }
283 
289  RzListIter *item = NULL;
290 
292 
293  item = RZ_NEW(RzListIter);
294  if (!item) {
295  return item;
296  }
297  if (list->tail) {
298  list->tail->n = item;
299  }
300  item->data = data;
301  item->p = list->tail;
302  item->n = NULL;
303  list->tail = item;
304  if (!list->head) {
305  list->head = item;
306  }
307  list->length++;
308  list->sorted = false;
309  return item;
310 }
311 
318 
319  RzListIter *item = RZ_NEW0(RzListIter);
320  if (!item) {
321  return NULL;
322  }
323  if (list->head) {
324  list->head->p = item;
325  }
326  item->data = data;
327  item->n = list->head;
328  item->p = NULL;
329  list->head = item;
330  if (!list->tail) {
331  list->tail = item;
332  }
333  list->length++;
334  list->sorted = true;
335  return item;
336 }
337 
343  RzListIter *it, *item;
344  ut32 i;
345 
347 
348  if (!list->head || !n) {
349  return rz_list_prepend(list, data);
350  }
351  for (it = list->head, i = 0; it && it->data; it = it->n, i++) {
352  if (i == n) {
353  item = RZ_NEW(RzListIter);
354  if (!item) {
355  return NULL;
356  }
357  item->data = data;
358  item->n = it;
359  item->p = it->p;
360  if (it->p) {
361  it->p->n = item;
362  }
363  it->p = item;
364  list->length++;
365  list->sorted = true;
366  return item;
367  }
368  }
369  return rz_list_append(list, data);
370 }
371 
377  void *data = NULL;
378  RzListIter *iter;
379 
381 
382  if (list->tail) {
383  iter = list->tail;
384  if (list->head == list->tail) {
385  list->head = list->tail = NULL;
386  } else {
387  list->tail = iter->p;
388  list->tail->n = NULL;
389  }
390  data = iter->data;
391  free(iter);
392  list->length--;
393  }
394  return data;
395 }
396 
402  void *data = NULL;
403 
405 
406  if (list->head) {
407  RzListIter *iter = list->head;
408  if (list->head == list->tail) {
409  list->head = list->tail = NULL;
410  } else {
411  list->head = iter->n;
412  list->head->p = NULL;
413  }
414  data = iter->data;
415  free(iter);
416  list->length--;
417  }
418  return data;
419 }
420 
426  RzListIter *it;
427  ut32 i;
428 
429  rz_return_val_if_fail(list, false);
430 
431  for (it = list->head, i = 0; it && it->data; it = it->n, i++) {
432  if (i == n) {
433  if (!it->p && !it->n) {
434  list->head = list->tail = NULL;
435  } else if (!it->p) {
436  it->n->p = NULL;
437  list->head = it->n;
438  } else if (!it->n) {
439  it->p->n = NULL;
440  list->tail = it->p;
441  } else {
442  it->p->n = it->n;
443  it->n->p = it->p;
444  }
445  free(it);
446  list->length--;
447  return true;
448  }
449  }
450  return false;
451 }
452 
459 
460  return list->tail ? list->tail->data : NULL;
461 }
462 
469 
470  return list->head ? list->head->data : NULL;
471 }
472 
478  RzListIter *it, *tmp;
479 
481 
482  for (it = list->head; it && it->data; it = it->p) {
483  tmp = it->p;
484  it->p = it->n;
485  it->n = tmp;
486  }
487  tmp = list->head;
488  list->head = list->tail;
489  list->tail = tmp;
490 }
491 
497  RzListIter *iter;
498  void *data;
499 
501 
502  RzList *l = rz_list_new();
503  if (!l) {
504  return NULL;
505  }
506  l->free = NULL;
507  rz_list_foreach (list, iter, data) {
508  rz_list_append(l, data);
509  }
510  l->sorted = list->sorted;
511  return l;
512 }
513 
519  RzListIter *it, *item = NULL;
520 
521  rz_return_val_if_fail(list && data && cmp, NULL);
522 
523  for (it = list->head; it && it->data && cmp(data, it->data) > 0; it = it->n) {
524  ;
525  }
526  if (it) {
527  item = RZ_NEW0(RzListIter);
528  if (!item) {
529  return NULL;
530  }
531  item->n = it;
532  item->p = it->p;
533  item->data = data;
534  item->n->p = item;
535  if (!item->p) {
536  list->head = item;
537  } else {
538  item->p->n = item;
539  }
540  list->length++;
541  } else {
542  rz_list_append(list, data);
543  }
544  list->sorted = true;
545  return item;
546 }
547 
553  RzListIter *it;
554  ut32 i;
555 
556  rz_return_val_if_fail(list, false);
557  for (it = list->head, i = 0; it; it = it->n, i++) {
558  if (i == n) {
559  if (list->free) {
560  list->free(it->data);
561  }
562  it->data = p;
563  list->sorted = false;
564  return true;
565  }
566  }
567  return false;
568 }
569 
575  RzListIter *it;
576  ut32 i;
577 
579 
580  for (it = list->head, i = 0; it && it->data; it = it->n, i++) {
581  if (i == n) {
582  return it->data;
583  }
584  }
585  return NULL;
586 }
587 
593  return rz_list_find_ptr(list, ptr);
594 }
595 
602  void *p;
603  RzListIter *iter;
604  rz_list_foreach (list, iter, p) {
605  if (ptr == p) {
606  return iter;
607  }
608  }
609  return NULL;
610 }
611 
621  void *q;
622  RzListIter *iter;
623 
625 
626  rz_list_foreach (list, iter, q) {
627  if (!cmp(p, q)) {
628  return iter;
629  }
630  }
631  return NULL;
632 }
633 
635  RzListIter *next = NULL, *result = NULL, *head = NULL;
636  while (first || second) {
637  if (!second) {
638  next = first;
639  first = first->n;
640  } else if (!first) {
641  next = second;
642  second = second->n;
643  } else if (cmp(first->data, second->data) <= 0) {
644  next = first;
645  first = first->n;
646  } else {
647  next = second;
648  second = second->n;
649  }
650  if (!head) {
651  result = next;
652  head = result;
653  head->p = NULL;
654  } else {
655  result->n = next;
656  next->p = result;
657  result = result->n;
658  }
659  }
660  head->p = NULL;
661  next->n = NULL;
662  return head;
663 }
664 
666  RzListIter *tmp;
667  RzListIter *fast;
668  RzListIter *slow;
669  if (!head || !head->n) {
670  return head;
671  }
672  slow = head;
673  fast = head;
674  while (fast && fast->n && fast->n->n) {
675  fast = fast->n->n;
676  slow = slow->n;
677  }
678  tmp = slow->n;
679  slow->n = NULL;
680  return tmp;
681 }
682 
684  RzListIter *second;
685  if (!head || !head->n) {
686  return head;
687  }
688  second = _r_list_half_split(head);
689  head = _merge_sort(head, cmp);
690  second = _merge_sort(second, cmp);
691  return _merge(head, second, cmp);
692 }
693 
700 
701  if (!list->sorted && list->head && cmp) {
702  RzListIter *iter;
703  list->head = _merge_sort(list->head, cmp);
704  // update tail reference
705  iter = list->head;
706  while (iter && iter->n) {
707  iter = iter->n;
708  }
709  list->tail = iter;
710  }
711  list->sorted = true;
712 }
713 
720 
721  if (!list->sorted) {
722  RzListIter *it;
723  RzListIter *it2;
724  if (cmp) {
725  for (it = list->head; it && it->data; it = it->n) {
726  for (it2 = it->n; it2 && it2->data; it2 = it2->n) {
727  if (cmp(it->data, it2->data) > 0) {
728  void *t = it->data;
729  it->data = it2->data;
730  it2->data = t;
731  }
732  }
733  }
734  }
735  list->sorted = true;
736  }
737 }
738 
745  if (list->length > 43) {
747  } else {
749  }
750 }
751 
757  RzListIter *iter, *iter2;
758  void *item, *item2;
759 
761 
762  RzList *nl = rz_list_newf(NULL);
763  if (!nl) {
764  return NULL;
765  }
766  rz_list_foreach (list, iter, item) {
767  bool found = false;
768  rz_list_foreach (nl, iter2, item2) {
769  if (cmp(item, item2) == 0) {
770  found = true;
771  break;
772  }
773  }
774  if (!found) {
775  rz_list_append(nl, item);
776  }
777  }
778  return nl;
779 }
780 
786  RzListIter *iter;
787  RzStrBuf *buf = rz_strbuf_new("");
788  if (!buf) {
789  return NULL;
790  }
791  char *item;
792  rz_list_foreach (list, iter, item) {
793  rz_strbuf_appendf(buf, "%s%c", item, ch);
794  }
795  return rz_strbuf_drain(buf);
796 }
797 
803  RzList *l = rz_list_newf(free);
804  SdbKv *kv;
805  SdbListIter *iter;
806  ls_foreach (sl, iter, kv) {
808  }
809  return l;
810 }
lzma_index ** i
Definition: index.h:629
static RzILOpEffect * cmp(cs_insn *insn, bool is_thumb)
Definition: arm_il32.c:942
#define RZ_API
#define NULL
Definition: cris-opc.c:27
uint32_t ut32
static char * slow(struct match *, char *, char *, sopno, sopno)
Definition: engine.c:806
static char * fast(struct match *, char *, char *, sopno, sopno)
Definition: engine.c:717
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
RZ_API const KEY_TYPE bool * found
Definition: ht_inc.h:130
voidpf void * buf
Definition: ioapi.h:138
void * p
Definition: libc.cpp:67
static void list(RzEgg *egg)
Definition: rz-gg.c:52
RZ_API RZ_BORROW RzListIter * rz_list_iter_get_next(RzListIter *list)
returns the next RzList iterator in the list
Definition: list.c:20
static RzListIter * _r_list_half_split(RzListIter *head)
Definition: list.c:665
RZ_API void rz_list_insertion_sort(RZ_NONNULL RzList *list, RZ_NONNULL RzListComparator cmp)
Insertion sorts the list via the RzListComparator.
Definition: list.c:718
RZ_API RZ_BORROW void * rz_list_iter_get_next_data(RzListIter *list)
returns the value stored in the next RzList iterator
Definition: list.c:29
RZ_API RZ_BORROW RzListIter * rz_list_find(RZ_NONNULL const RzList *list, const void *p, RZ_NONNULL RzListComparator cmp)
Returns RzListIter element which matches via the RzListComparator.
Definition: list.c:620
RZ_API RZ_BORROW RzListIter * rz_list_contains(RZ_NONNULL const RzList *list, RZ_NONNULL const void *ptr)
Returns the RzListIter of the given pointer, if found.
Definition: list.c:592
RZ_API RZ_OWN RzList * rz_list_uniq(RZ_NONNULL const RzList *list, RZ_NONNULL RzListComparator cmp)
Returns a new RzList which contains only unique values.
Definition: list.c:756
RZ_API RZ_BORROW RzListIter * rz_list_prepend(RZ_NONNULL RzList *list, void *data)
Appends at the beginning of the list a new element.
Definition: list.c:316
RZ_API void rz_list_split(RZ_NONNULL RzList *list, void *ptr)
Definition: list.c:172
RZ_API RZ_BORROW RzListIter * rz_list_iterator(const RzList *list)
returns the first RzList iterator int the list
Definition: list.c:51
RZ_API RZ_BORROW RzListIter * rz_list_insert(RZ_NONNULL RzList *list, ut32 n, void *data)
Inserts a new element at the N-th position.
Definition: list.c:342
RZ_API void rz_list_iter_free(RzListIter *list)
Definition: list.c:12
RZ_API void rz_list_reverse(RZ_NONNULL RzList *list)
Reverses the list.
Definition: list.c:477
RZ_API RZ_OWN RzList * rz_list_newf(RzListFree f)
Returns a new initialized RzList pointer and sets the free method.
Definition: list.c:248
RZ_API RZ_BORROW RzListIter * rz_list_find_ptr(RZ_NONNULL const RzList *list, RZ_NONNULL const void *ptr)
Returns the RzListIter of the given pointer, if found.
Definition: list.c:600
RZ_API void rz_list_merge_sort(RZ_NONNULL RzList *list, RZ_NONNULL RzListComparator cmp)
Merge sorts the list via the RzListComparator.
Definition: list.c:698
RZ_API RZ_BORROW void * rz_list_get_bottom(RZ_NONNULL const RzList *list)
Returns the first element of the list.
Definition: list.c:467
RZ_API void rz_list_delete(RZ_NONNULL RzList *list, RZ_NONNULL RzListIter *iter)
Removes an entry in the list by using the RzListIter pointer.
Definition: list.c:162
RZ_API RZ_OWN RzList * rz_list_clone(RZ_NONNULL const RzList *list)
Shallow copies of the list (but doesn't free its elements)
Definition: list.c:496
RZ_API RZ_OWN RzList * rz_list_new_from_array(RZ_NONNULL const void **arr, size_t arr_size)
Allocates a new RzList and adds an array elements to it.
Definition: list.c:260
RZ_API void * rz_list_iter_get_data(RzListIter *list)
returns the value stored in the list element
Definition: list.c:42
RZ_API bool rz_list_delete_data(RZ_NONNULL RzList *list, void *ptr)
Deletes an entry in the list by searching for a pointer.
Definition: list.c:148
RZ_API RZ_BORROW void * rz_list_get_top(RZ_NONNULL const RzList *list)
Returns the last element of the list.
Definition: list.c:457
RZ_API RZ_OWN void * rz_list_pop(RZ_NONNULL RzList *list)
Removes and returns the last element of the list.
Definition: list.c:376
RZ_API RZ_OWN RzList * rz_list_new(void)
Returns a new initialized RzList pointer (free method is not initialized)
Definition: list.c:235
static RzListIter * _merge(RzListIter *first, RzListIter *second, RzListComparator cmp)
Definition: list.c:634
RZ_API RZ_OWN RzList * rz_list_of_sdblist(SdbList *sl)
Converts a SdbList into a RzList.
Definition: list.c:802
RZ_API void rz_list_sort(RZ_NONNULL RzList *list, RZ_NONNULL RzListComparator cmp)
Sorts via merge sort or via insertion sort a list.
Definition: list.c:743
RZ_API RZ_OWN char * rz_list_to_str(RZ_NONNULL RzList *list, char ch)
Casts a RzList containg strings into a concatenated string.
Definition: list.c:785
RZ_API ut32 rz_list_del_n(RZ_NONNULL RzList *list, ut32 n)
Removes the N-th element of the list.
Definition: list.c:425
RZ_API RZ_OWN RzListIter * rz_list_item_new(void *data)
Creates a RzListIter element that can be inserted into a RzList.
Definition: list.c:276
RZ_API ut32 rz_list_set_n(RZ_NONNULL RzList *list, ut32 n, void *p)
Sets the N-th element of the list.
Definition: list.c:552
RZ_API bool rz_list_join(RZ_NONNULL RzList *list1, RZ_NONNULL RzList *list2)
Joins 2 list into one (list2 pointer needs to be freed by the user)
Definition: list.c:209
RZ_API RZ_BORROW void * rz_list_first(RZ_NONNULL const RzList *list)
Returns the first element of the list.
Definition: list.c:77
RZ_API RZ_BORROW void * rz_list_last(RZ_NONNULL const RzList *list)
Returns the last element of the list.
Definition: list.c:86
RZ_API RZ_BORROW void * rz_list_get_n(RZ_NONNULL const RzList *list, ut32 n)
Returns the N-th element of the list.
Definition: list.c:574
RZ_API RZ_BORROW RzListIter * rz_list_push(RZ_NONNULL RzList *list, void *item)
Alias for rz_list_append.
Definition: list.c:60
RZ_API ut32 rz_list_length(RZ_NONNULL const RzList *list)
Returns the length of the list.
Definition: list.c:109
RzListIter * rz_list_iter_new(void)
Definition: list.c:8
RZ_API RZ_OWN void * rz_list_pop_head(RZ_NONNULL RzList *list)
Removes and returns the first element of the list.
Definition: list.c:401
RZ_API void rz_list_split_iter(RZ_NONNULL RzList *list, RZ_NONNULL RzListIter *iter)
Definition: list.c:187
RZ_API RzListIter * rz_list_get_next(RzListIter *list)
Returns the next element of the list.
Definition: list.c:68
RZ_API void rz_list_init(RZ_NONNULL RzList *list)
Initializes the RzList pointer.
Definition: list.c:95
RZ_API RZ_BORROW RzListIter * rz_list_append(RZ_NONNULL RzList *list, void *data)
Appends at the end of the list a new element.
Definition: list.c:288
static RzListIter * _merge_sort(RzListIter *head, RzListComparator cmp)
Definition: list.c:683
RZ_API RZ_BORROW RzListIter * rz_list_add_sorted(RZ_NONNULL RzList *list, void *data, RZ_NONNULL RzListComparator cmp)
Adds an element to a sorted list via the RzListComparator.
Definition: list.c:518
RZ_API void rz_list_free(RZ_NONNULL RzList *list)
Empties the list and frees the list pointer.
Definition: list.c:137
RZ_API void rz_list_purge(RZ_NONNULL RzList *list)
Empties the list without freeing the list pointer.
Definition: list.c:120
void * calloc(size_t number, size_t size)
Definition: malloc.c:102
return strdup("=SP r13\n" "=LR r14\n" "=PC r15\n" "=A0 r0\n" "=A1 r1\n" "=A2 r2\n" "=A3 r3\n" "=ZF zf\n" "=SF nf\n" "=OF vf\n" "=CF cf\n" "=SN or0\n" "gpr lr .32 56 0\n" "gpr pc .32 60 0\n" "gpr cpsr .32 64 0 ____tfiae_________________qvczn\n" "gpr or0 .32 68 0\n" "gpr tf .1 64.5 0 thumb\n" "gpr ef .1 64.9 0 endian\n" "gpr jf .1 64.24 0 java\n" "gpr qf .1 64.27 0 sticky_overflow\n" "gpr vf .1 64.28 0 overflow\n" "gpr cf .1 64.29 0 carry\n" "gpr zf .1 64.30 0 zero\n" "gpr nf .1 64.31 0 negative\n" "gpr itc .4 64.10 0 if_then_count\n" "gpr gef .4 64.16 0 great_or_equal\n" "gpr r0 .32 0 0\n" "gpr r1 .32 4 0\n" "gpr r2 .32 8 0\n" "gpr r3 .32 12 0\n" "gpr r4 .32 16 0\n" "gpr r5 .32 20 0\n" "gpr r6 .32 24 0\n" "gpr r7 .32 28 0\n" "gpr r8 .32 32 0\n" "gpr r9 .32 36 0\n" "gpr r10 .32 40 0\n" "gpr r11 .32 44 0\n" "gpr r12 .32 48 0\n" "gpr r13 .32 52 0\n" "gpr r14 .32 56 0\n" "gpr r15 .32 60 0\n" "gpr r16 .32 64 0\n" "gpr r17 .32 68 0\n")
#define ls_foreach(list, it, pos)
Definition: ls.h:31
int n
Definition: mipsasm.c:19
#define rz_return_if_fail(expr)
Definition: rz_assert.h:100
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
void(* RzListFree)(void *ptr)
Definition: rz_list.h:11
int(* RzListComparator)(const void *value, const void *list_data)
Definition: rz_list.h:33
RZ_API RZ_OWN char * rz_strbuf_drain(RzStrBuf *sb)
Definition: strbuf.c:342
RZ_API RzStrBuf * rz_strbuf_new(const char *s)
Definition: strbuf.c:8
RZ_API bool rz_strbuf_appendf(RzStrBuf *sb, const char *fmt,...) RZ_PRINTF_CHECK(2
#define RZ_OWN
Definition: rz_types.h:62
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define RZ_NONNULL
Definition: rz_types.h:64
#define RZ_NEW(x)
Definition: rz_types.h:285
#define RZ_BORROW
Definition: rz_types.h:63
static char * sdbkv_key(const SdbKv *kv)
Definition: sdbht.h:21
#define f(i)
Definition: sha256.c:46
Definition: ls.h:17
Definition: ls.h:22
struct rz_list_iter_t * n
Definition: rz_list.h:15
void * data
Definition: rz_list.h:14
struct rz_list_iter_t * p
Definition: rz_list.h:15
RzListFree free
Definition: rz_list.h:21
bool sorted
Definition: rz_list.h:23
Definition: sdbht.h:14