intlist.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. /*
  2. * Based on intlist.c by:
  3. * (c) 2009 Arnaldo Carvalho de Melo <acme@redhat.com>
  4. *
  5. * Licensed under the GPLv2.
  6. */
  7. #include <errno.h>
  8. #include <stdlib.h>
  9. #include <linux/compiler.h>
  10. #include "intlist.h"
  11. static struct rb_node *intlist__node_new(struct rblist *rblist __maybe_unused,
  12. const void *entry)
  13. {
  14. int i = (int)((long)entry);
  15. struct rb_node *rc = NULL;
  16. struct int_node *node = malloc(sizeof(*node));
  17. if (node != NULL) {
  18. node->i = i;
  19. node->priv = NULL;
  20. rc = &node->rb_node;
  21. }
  22. return rc;
  23. }
  24. static void int_node__delete(struct int_node *ilist)
  25. {
  26. free(ilist);
  27. }
  28. static void intlist__node_delete(struct rblist *rblist __maybe_unused,
  29. struct rb_node *rb_node)
  30. {
  31. struct int_node *node = container_of(rb_node, struct int_node, rb_node);
  32. int_node__delete(node);
  33. }
  34. static int intlist__node_cmp(struct rb_node *rb_node, const void *entry)
  35. {
  36. int i = (int)((long)entry);
  37. struct int_node *node = container_of(rb_node, struct int_node, rb_node);
  38. return node->i - i;
  39. }
  40. int intlist__add(struct intlist *ilist, int i)
  41. {
  42. return rblist__add_node(&ilist->rblist, (void *)((long)i));
  43. }
  44. void intlist__remove(struct intlist *ilist, struct int_node *node)
  45. {
  46. rblist__remove_node(&ilist->rblist, &node->rb_node);
  47. }
  48. static struct int_node *__intlist__findnew(struct intlist *ilist,
  49. int i, bool create)
  50. {
  51. struct int_node *node = NULL;
  52. struct rb_node *rb_node;
  53. if (ilist == NULL)
  54. return NULL;
  55. if (create)
  56. rb_node = rblist__findnew(&ilist->rblist, (void *)((long)i));
  57. else
  58. rb_node = rblist__find(&ilist->rblist, (void *)((long)i));
  59. if (rb_node)
  60. node = container_of(rb_node, struct int_node, rb_node);
  61. return node;
  62. }
  63. struct int_node *intlist__find(struct intlist *ilist, int i)
  64. {
  65. return __intlist__findnew(ilist, i, false);
  66. }
  67. struct int_node *intlist__findnew(struct intlist *ilist, int i)
  68. {
  69. return __intlist__findnew(ilist, i, true);
  70. }
  71. static int intlist__parse_list(struct intlist *ilist, const char *s)
  72. {
  73. char *sep;
  74. int err;
  75. do {
  76. long value = strtol(s, &sep, 10);
  77. err = -EINVAL;
  78. if (*sep != ',' && *sep != '\0')
  79. break;
  80. err = intlist__add(ilist, value);
  81. if (err)
  82. break;
  83. s = sep + 1;
  84. } while (*sep != '\0');
  85. return err;
  86. }
  87. struct intlist *intlist__new(const char *slist)
  88. {
  89. struct intlist *ilist = malloc(sizeof(*ilist));
  90. if (ilist != NULL) {
  91. rblist__init(&ilist->rblist);
  92. ilist->rblist.node_cmp = intlist__node_cmp;
  93. ilist->rblist.node_new = intlist__node_new;
  94. ilist->rblist.node_delete = intlist__node_delete;
  95. if (slist && intlist__parse_list(ilist, slist))
  96. goto out_delete;
  97. }
  98. return ilist;
  99. out_delete:
  100. intlist__delete(ilist);
  101. return NULL;
  102. }
  103. void intlist__delete(struct intlist *ilist)
  104. {
  105. if (ilist != NULL)
  106. rblist__delete(&ilist->rblist);
  107. }
  108. struct int_node *intlist__entry(const struct intlist *ilist, unsigned int idx)
  109. {
  110. struct int_node *node = NULL;
  111. struct rb_node *rb_node;
  112. rb_node = rblist__entry(&ilist->rblist, idx);
  113. if (rb_node)
  114. node = container_of(rb_node, struct int_node, rb_node);
  115. return node;
  116. }