list.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. /* list.c - grub list function */
  2. /*
  3. * GRUB -- GRand Unified Bootloader
  4. * Copyright (C) 2009 Free Software Foundation, Inc.
  5. *
  6. * GRUB is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * GRUB is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include <grub/list.h>
  20. #include <grub/misc.h>
  21. #include <grub/mm.h>
  22. GRUB_EXPORT(grub_list_push);
  23. GRUB_EXPORT(grub_list_pop);
  24. GRUB_EXPORT(grub_list_remove);
  25. GRUB_EXPORT(grub_list_iterate);
  26. GRUB_EXPORT(grub_list_insert);
  27. GRUB_EXPORT(grub_prio_list_insert);
  28. GRUB_EXPORT(grub_named_list_find);
  29. void
  30. grub_list_push (grub_list_t *head, grub_list_t item)
  31. {
  32. item->next = *head;
  33. *head = item;
  34. }
  35. void *
  36. grub_list_pop (grub_list_t *head)
  37. {
  38. grub_list_t item;
  39. item = *head;
  40. if (item)
  41. *head = item->next;
  42. return item;
  43. }
  44. void
  45. grub_list_remove (grub_list_t *head, grub_list_t item)
  46. {
  47. grub_list_t *p, q;
  48. for (p = head, q = *p; q; p = &(q->next), q = q->next)
  49. if (q == item)
  50. {
  51. *p = q->next;
  52. break;
  53. }
  54. }
  55. int
  56. grub_list_iterate (grub_list_t head, grub_list_hook_t hook, void *closure)
  57. {
  58. grub_list_t p;
  59. for (p = head; p; p = p->next)
  60. if (hook (p, closure))
  61. return 1;
  62. return 0;
  63. }
  64. void
  65. grub_list_insert (grub_list_t *head, grub_list_t item,
  66. grub_list_test_t test, void *closure)
  67. {
  68. grub_list_t *p, q;
  69. for (p = head, q = *p; q; p = &(q->next), q = q->next)
  70. if (test (item, q, closure))
  71. break;
  72. *p = item;
  73. item->next = q;
  74. }
  75. void *
  76. grub_named_list_find (grub_named_list_t head, const char *name)
  77. {
  78. while (head)
  79. {
  80. if (! grub_strcmp (head->name, name))
  81. return head;
  82. head = head->next;
  83. }
  84. return 0;
  85. }
  86. struct grub_prio_list_insert_closure
  87. {
  88. int inactive;
  89. };
  90. static int
  91. grub_prio_list_insert_test (grub_prio_list_t new_item, grub_prio_list_t item,
  92. void *closure)
  93. {
  94. struct grub_prio_list_insert_closure *c = closure;
  95. int r;
  96. r = grub_strcmp (new_item->name, item->name);
  97. if (r)
  98. return (r < 0);
  99. if (new_item->prio >= (item->prio & GRUB_PRIO_LIST_PRIO_MASK))
  100. {
  101. item->prio &= ~GRUB_PRIO_LIST_FLAG_ACTIVE;
  102. return 1;
  103. }
  104. c->inactive = 1;
  105. return 0;
  106. }
  107. void
  108. grub_prio_list_insert (grub_prio_list_t *head, grub_prio_list_t nitem)
  109. {
  110. struct grub_prio_list_insert_closure c;
  111. c.inactive = 0;
  112. grub_list_insert (GRUB_AS_LIST_P (head), GRUB_AS_LIST (nitem),
  113. (grub_list_test_t) grub_prio_list_insert_test, &c);
  114. if (! c.inactive)
  115. nitem->prio |= GRUB_PRIO_LIST_FLAG_ACTIVE;
  116. }