2 * Part of Very Secure FTPd
8 /* Anti-lamer measures deployed, sir! */
9 #define PRIVATE_HANDS_OFF_alloc_len alloc_len
10 #define PRIVATE_HANDS_OFF_list_len list_len
11 #define PRIVATE_HANDS_OFF_p_nodes p_nodes
18 struct mystr_list_node
21 struct mystr sort_key_str
;
25 static const unsigned int kMaxStrlist
= 10 * 1000 * 1000;
27 static struct mystr s_null_str
;
29 static int sort_compare_func(const void* p1
, const void* p2
);
30 static int sort_compare_func_reverse(const void* p1
, const void* p2
);
31 static int sort_compare_common(const void* p1
, const void* p2
, int reverse
);
34 str_list_free(struct mystr_list
* p_list
)
37 for (i
=0; i
< p_list
->list_len
; ++i
)
39 str_free(&p_list
->p_nodes
[i
].str
);
40 str_free(&p_list
->p_nodes
[i
].sort_key_str
);
43 p_list
->alloc_len
= 0;
46 vsf_sysutil_free(p_list
->p_nodes
);
52 str_list_get_length(const struct mystr_list
* p_list
)
54 return p_list
->list_len
;
58 str_list_contains_str(const struct mystr_list
* p_list
,
59 const struct mystr
* p_str
)
62 for (i
=0; i
< p_list
->list_len
; ++i
)
64 if (str_equal(p_str
, &p_list
->p_nodes
[i
].str
))
73 str_list_add(struct mystr_list
* p_list
, const struct mystr
* p_str
,
74 const struct mystr
* p_sort_key_str
)
76 struct mystr_list_node
* p_node
;
77 /* Expand the node allocation if we have to */
78 if (p_list
->list_len
== p_list
->alloc_len
)
80 if (p_list
->alloc_len
== 0)
82 p_list
->alloc_len
= 32;
83 p_list
->p_nodes
= vsf_sysutil_malloc(
84 p_list
->alloc_len
* (unsigned int) sizeof(struct mystr_list_node
));
88 p_list
->alloc_len
*= 2;
89 if (p_list
->alloc_len
> kMaxStrlist
)
91 die("excessive strlist");
93 p_list
->p_nodes
= vsf_sysutil_realloc(
95 p_list
->alloc_len
* (unsigned int) sizeof(struct mystr_list_node
));
98 p_node
= &p_list
->p_nodes
[p_list
->list_len
];
99 p_node
->str
= s_null_str
;
100 p_node
->sort_key_str
= s_null_str
;
101 str_copy(&p_node
->str
, p_str
);
104 str_copy(&p_node
->sort_key_str
, p_sort_key_str
);
110 str_list_sort(struct mystr_list
* p_list
, int reverse
)
114 vsf_sysutil_qsort(p_list
->p_nodes
, p_list
->list_len
,
115 sizeof(struct mystr_list_node
), sort_compare_func
);
119 vsf_sysutil_qsort(p_list
->p_nodes
, p_list
->list_len
,
120 sizeof(struct mystr_list_node
),
121 sort_compare_func_reverse
);
126 sort_compare_func(const void* p1
, const void* p2
)
128 return sort_compare_common(p1
, p2
, 0);
132 sort_compare_func_reverse(const void* p1
, const void* p2
)
134 return sort_compare_common(p1
, p2
, 1);
138 sort_compare_common(const void* p1
, const void* p2
, int reverse
)
140 const struct mystr
* p_cmp1
;
141 const struct mystr
* p_cmp2
;
142 const struct mystr_list_node
* p_node1
= (const struct mystr_list_node
*) p1
;
143 const struct mystr_list_node
* p_node2
= (const struct mystr_list_node
*) p2
;
144 if (!str_isempty(&p_node1
->sort_key_str
))
146 p_cmp1
= &p_node1
->sort_key_str
;
150 p_cmp1
= &p_node1
->str
;
152 if (!str_isempty(&p_node2
->sort_key_str
))
154 p_cmp2
= &p_node2
->sort_key_str
;
158 p_cmp2
= &p_node2
->str
;
163 return str_strcmp(p_cmp2
, p_cmp1
);
167 return str_strcmp(p_cmp1
, p_cmp2
);
172 str_list_get_pstr(const struct mystr_list
* p_list
, unsigned int indexx
)
174 if (indexx
>= p_list
->list_len
)
176 bug("indexx out of range in str_list_get_str");
178 return &p_list
->p_nodes
[indexx
].str
;