strlist.c
上传用户:ig0539
上传日期:2022-05-21
资源大小:181k
文件大小:4k
源码类别:

Ftp客户端

开发平台:

C/C++

  1. /*
  2.  * Part of Very Secure FTPd
  3.  * Licence: GPL v2
  4.  * Author: Chris Evans
  5.  * strlist.c
  6.  */
  7. /* Anti-lamer measures deployed, sir! */
  8. #define PRIVATE_HANDS_OFF_alloc_len alloc_len
  9. #define PRIVATE_HANDS_OFF_list_len list_len
  10. #define PRIVATE_HANDS_OFF_p_nodes p_nodes
  11. #include "strlist.h"
  12. #include "str.h"
  13. #include "utility.h"
  14. #include "sysutil.h"
  15. struct mystr_list_node
  16. {
  17.   struct mystr str;
  18.   struct mystr sort_key_str;
  19. };
  20. /* File locals */
  21. static struct mystr s_null_str;
  22. static int sort_compare_func(const void* p1, const void* p2);
  23. static int sort_compare_func_reverse(const void* p1, const void* p2);
  24. static int sort_compare_common(const void* p1, const void* p2, int reverse);
  25. void
  26. str_list_free(struct mystr_list* p_list)
  27. {
  28.   unsigned int i;
  29.   for (i=0; i < p_list->list_len; ++i)
  30.   {
  31.     str_free(&p_list->p_nodes[i].str);
  32.     str_free(&p_list->p_nodes[i].sort_key_str);
  33.   }
  34.   p_list->list_len = 0;
  35.   p_list->alloc_len = 0;
  36.   if (p_list->p_nodes)
  37.   {
  38.     vsf_sysutil_free(p_list->p_nodes);
  39.     p_list->p_nodes = 0;
  40.   }
  41. }
  42. int
  43. str_list_get_length(const struct mystr_list* p_list)
  44. {
  45.   return p_list->list_len;
  46. }
  47. int
  48. str_list_contains_str(const struct mystr_list* p_list,
  49.                       const struct mystr* p_str)
  50. {
  51.   unsigned int i;
  52.   for (i=0; i < p_list->list_len; ++i)
  53.   {
  54.     if (str_equal(p_str, &p_list->p_nodes[i].str))
  55.     {
  56.       return 1;
  57.     }
  58.   }
  59.   return 0;
  60. }
  61. void
  62. str_list_add(struct mystr_list* p_list, const struct mystr* p_str,
  63.              const struct mystr* p_sort_key_str)
  64. {
  65.   struct mystr_list_node* p_node;
  66.   /* Expand the node allocation if we have to */
  67.   if (p_list->list_len == p_list->alloc_len)
  68.   {
  69.     if (p_list->alloc_len == 0)
  70.     {
  71.       p_list->alloc_len = 32;
  72.       p_list->p_nodes = vsf_sysutil_malloc(p_list->alloc_len *
  73.                                            sizeof(struct mystr_list_node));
  74.     }
  75.     else
  76.     {
  77.       p_list->alloc_len *= 2;
  78.       p_list->p_nodes = vsf_sysutil_realloc(p_list->p_nodes,
  79.                                             p_list->alloc_len *
  80.                                             sizeof(struct mystr_list_node));
  81.     }
  82.   }
  83.   p_node = &p_list->p_nodes[p_list->list_len];
  84.   p_node->str = s_null_str;
  85.   p_node->sort_key_str = s_null_str;
  86.   str_copy(&p_node->str, p_str);
  87.   if (p_sort_key_str)
  88.   {
  89.     str_copy(&p_node->sort_key_str, p_sort_key_str);
  90.   }
  91.   p_list->list_len++;
  92. }
  93. void
  94. str_list_sort(struct mystr_list* p_list, int reverse)
  95. {
  96.   if (!reverse)
  97.   {
  98.     vsf_sysutil_qsort(p_list->p_nodes, p_list->list_len,
  99.                       sizeof(struct mystr_list_node), sort_compare_func);
  100.   }
  101.   else
  102.   {
  103.     vsf_sysutil_qsort(p_list->p_nodes, p_list->list_len,
  104.                       sizeof(struct mystr_list_node),
  105.                       sort_compare_func_reverse);
  106.   }
  107. }
  108. static int
  109. sort_compare_func(const void* p1, const void* p2)
  110. {
  111.   return sort_compare_common(p1, p2, 0);
  112. }
  113. static int
  114. sort_compare_func_reverse(const void* p1, const void* p2)
  115. {
  116.   return sort_compare_common(p1, p2, 1);
  117. }
  118. static int
  119. sort_compare_common(const void* p1, const void* p2, int reverse)
  120. {
  121.   const struct mystr* p_cmp1;
  122.   const struct mystr* p_cmp2;
  123.   const struct mystr_list_node* p_node1 = (const struct mystr_list_node*) p1;
  124.   const struct mystr_list_node* p_node2 = (const struct mystr_list_node*) p2;
  125.   if (!str_isempty(&p_node1->sort_key_str))
  126.   {
  127.     p_cmp1 = &p_node1->sort_key_str;
  128.   }
  129.   else
  130.   {
  131.     p_cmp1 = &p_node1->str;
  132.   }
  133.   if (!str_isempty(&p_node2->sort_key_str))
  134.   {
  135.     p_cmp2 = &p_node2->sort_key_str;
  136.   }
  137.   else
  138.   {
  139.     p_cmp2 = &p_node2->str;
  140.   }
  141.   if (reverse)
  142.   {
  143.     return str_strcmp(p_cmp2, p_cmp1);
  144.   }
  145.   else
  146.   {
  147.     return str_strcmp(p_cmp1, p_cmp2);
  148.   }
  149. }
  150. const struct mystr*
  151. str_list_get_pstr(const struct mystr_list* p_list, unsigned int indexx)
  152. {
  153.   if (indexx >= p_list->list_len)
  154.   {
  155.     bug("indexx out of range in str_list_get_str");
  156.   }
  157.   return &p_list->p_nodes[indexx].str;
  158. }