dictionary.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. /**
  2. * Copyright (C) 2011 Anders Sundman <anders@4zm.org>
  3. *
  4. * This file is part of mfterm.
  5. *
  6. * mfterm 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. * mfterm 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 mfterm. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include <stdio.h>
  20. #include <string.h>
  21. #include <stdlib.h>
  22. #include "dictionary.h"
  23. static key_list_t* key_list = NULL;
  24. key_list_t* kl_add(key_list_t** list, const uint8_t* key);
  25. void kl_clear(key_list_t** list);
  26. key_list_t* kl_make_node(const uint8_t* key);
  27. int key_cmp(const uint8_t* k1, const uint8_t* k2);
  28. void dictionary_clear() {
  29. kl_clear(&key_list);
  30. }
  31. int dictionary_add(const uint8_t* key) {
  32. return kl_add(&key_list, key) != NULL;
  33. }
  34. key_list_t* dictionary_get() {
  35. return key_list;
  36. }
  37. // Append a node to the list. Don't append duplicates, O(n) operation.
  38. key_list_t* kl_add(key_list_t** list, const uint8_t* key) {
  39. if (list == NULL)
  40. return NULL;
  41. // A new list
  42. if (*list == NULL)
  43. return *list = kl_make_node(key);
  44. // Append (but no duplicates)
  45. key_list_t* it = *list;
  46. key_list_t* last = NULL;
  47. while(it) {
  48. // Don't add duplicates, but move the key first in the list
  49. if (key_cmp(it->key, key) == 0) {
  50. if (last) {
  51. last->next = it->next; // disconnect it
  52. it->next = *list; // move it fisrt
  53. *list = it; // re-point the head
  54. }
  55. return NULL; // Return null on duplicates
  56. }
  57. last = it;
  58. it = it->next;
  59. }
  60. return last->next = kl_make_node(key);
  61. }
  62. void kl_clear(key_list_t** list) {
  63. if (list == NULL || *list == NULL)
  64. return;
  65. // Free the list nodes
  66. key_list_t* it = *list;
  67. do {
  68. key_list_t* next = it->next;
  69. free(it);
  70. it = next;
  71. } while(it);
  72. *list = 0;
  73. }
  74. key_list_t* kl_make_node(const uint8_t* key) {
  75. // Create the list node
  76. key_list_t* new_node = (key_list_t*) malloc(sizeof(key_list_t));
  77. memcpy((void*)new_node, key, 6);
  78. new_node->next = NULL;
  79. return new_node;
  80. }
  81. int key_cmp(const uint8_t* k1, const uint8_t* k2) {
  82. for (int i = 0; i < 6; ++i) {
  83. if (k1[i] != k2[i])
  84. return -1;
  85. }
  86. return 0;
  87. }