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.

125 lines
3.0 KiB

1 year ago
  1. /**
  2. * @file labeled_int_list.c
  3. * @brief list structure which binds ints to labels
  4. * @license GNU General Public License 3.0 - see LICENSE.txt
  5. */
  6. #include <stdbool.h>
  7. #include <stdlib.h>
  8. #include <assert.h>
  9. #include <string.h>
  10. #include "platform.h"
  11. #include "labeled_int_list.h"
  12. DYNAMIC_API labeled_int_list_t *new_labeled_int_list(int value, const char* label)
  13. {
  14. assert(label);
  15. if (!label)
  16. return NULL;
  17. labeled_int_list_t * labeled_int_list = calloc(1, sizeof(labeled_int_list_t));
  18. assert(labeled_int_list);
  19. if (labeled_int_list == NULL)
  20. return NULL;
  21. labeled_int_list->value = value;
  22. labeled_int_list->label = strdup(label);
  23. if (!labeled_int_list->label) {
  24. free(labeled_int_list);
  25. labeled_int_list = NULL;
  26. }
  27. return labeled_int_list;
  28. }
  29. DYNAMIC_API void free_labeled_int_list(labeled_int_list_t *labeled_int_list)
  30. {
  31. labeled_int_list_t *curr = labeled_int_list;
  32. while (curr) {
  33. labeled_int_list_t *next = curr->next;
  34. free(curr->label);
  35. free(curr);
  36. curr = next;
  37. }
  38. }
  39. DYNAMIC_API labeled_int_list_t *labeled_int_list_dup(const labeled_int_list_t *src)
  40. {
  41. assert(src);
  42. if (src == NULL)
  43. return NULL;
  44. labeled_int_list_t *labeled_int_list = NULL;
  45. labeled_int_list = new_labeled_int_list(src->value, src->label);
  46. if (labeled_int_list == NULL)
  47. goto enomem;
  48. labeled_int_list_t* src_curr = src->next;
  49. labeled_int_list_t** dst_curr_ptr = &labeled_int_list->next;
  50. // list
  51. while (src_curr) {
  52. *dst_curr_ptr = new_labeled_int_list(src_curr->value, src_curr->label);
  53. if (*dst_curr_ptr == NULL)
  54. goto enomem;
  55. src_curr = src_curr->next;
  56. dst_curr_ptr = &((*dst_curr_ptr)->next);
  57. }
  58. return labeled_int_list;
  59. enomem:
  60. free_labeled_int_list(labeled_int_list);
  61. return NULL;
  62. }
  63. DYNAMIC_API labeled_int_list_t *labeled_int_list_add(labeled_int_list_t *labeled_int_list, int value, const char* label)
  64. {
  65. if (!label)
  66. return NULL;
  67. if (!labeled_int_list)
  68. return new_labeled_int_list(value, label);
  69. if (!labeled_int_list->label) { // empty list
  70. assert(!labeled_int_list->next);
  71. if (labeled_int_list->next)
  72. return NULL; // invalid list
  73. labeled_int_list->value = value;
  74. labeled_int_list->label = strdup(label);
  75. if (!labeled_int_list->label) {
  76. free(labeled_int_list);
  77. labeled_int_list = NULL;
  78. }
  79. return labeled_int_list;
  80. }
  81. labeled_int_list_t* list_curr = labeled_int_list;
  82. while (list_curr->next)
  83. list_curr = list_curr->next;
  84. list_curr->next = new_labeled_int_list(value, label);
  85. assert(list_curr->next);
  86. if (!list_curr->next)
  87. return NULL;
  88. return list_curr->next;
  89. }
  90. DYNAMIC_API int labeled_int_list_length(const labeled_int_list_t *labeled_int_list)
  91. {
  92. int len = 0;
  93. for (const labeled_int_list_t *_li = labeled_int_list; _li && _li->label; _li = _li->next)
  94. len++;
  95. return len;
  96. }