(alias_iterate_first,alias_iterate_next,alias_iterate_end): New functions for re…
…adline completion support.
Showing
1 changed file
with
87 additions
and
38 deletions
1 | /* GNU Mailutils -- a suite of utilities for electronic mail | 1 | /* GNU Mailutils -- a suite of utilities for electronic mail |
2 | Copyright (C) 1999, 2001, 2002 Free Software Foundation, Inc. | 2 | Copyright (C) 1999, 2001, 2002, 2005 Free Software Foundation, Inc. |
3 | 3 | ||
4 | GNU Mailutils is free software; you can redistribute it and/or modify | 4 | GNU Mailutils is free software; you can redistribute it and/or modify |
5 | it under the terms of the GNU General Public License as published by | 5 | it under the terms of the GNU General Public License as published by |
... | @@ -32,20 +32,20 @@ int | ... | @@ -32,20 +32,20 @@ int |
32 | mail_alias (int argc, char **argv) | 32 | mail_alias (int argc, char **argv) |
33 | { | 33 | { |
34 | if (argc == 1) | 34 | if (argc == 1) |
35 | alias_print(NULL); | 35 | alias_print (NULL); |
36 | else if (argc == 2) | 36 | else if (argc == 2) |
37 | alias_print(argv[1]); | 37 | alias_print (argv[1]); |
38 | else | 38 | else |
39 | { | 39 | { |
40 | list_t list; | 40 | list_t list; |
41 | 41 | ||
42 | if (alias_create(argv[1], &list)) | 42 | if (alias_create (argv[1], &list)) |
43 | return 1; | 43 | return 1; |
44 | 44 | ||
45 | argc --; | 45 | argc --; |
46 | argv ++; | 46 | argv ++; |
47 | while (--argc) | 47 | while (--argc) |
48 | util_slist_add(&list, *++argv); | 48 | util_slist_add (&list, *++argv); |
49 | } | 49 | } |
50 | return 0; | 50 | return 0; |
51 | } | 51 | } |
... | @@ -77,7 +77,7 @@ static alias_t *alias_lookup_or_install __P((char *name, int install)); | ... | @@ -77,7 +77,7 @@ static alias_t *alias_lookup_or_install __P((char *name, int install)); |
77 | static void alias_print_group __P((char *name, list_t list)); | 77 | static void alias_print_group __P((char *name, list_t list)); |
78 | 78 | ||
79 | unsigned | 79 | unsigned |
80 | hash(char *name) | 80 | hash (char *name) |
81 | { | 81 | { |
82 | unsigned i; | 82 | unsigned i; |
83 | 83 | ||
... | @@ -89,7 +89,7 @@ hash(char *name) | ... | @@ -89,7 +89,7 @@ hash(char *name) |
89 | } | 89 | } |
90 | 90 | ||
91 | int | 91 | int |
92 | alias_rehash() | 92 | alias_rehash () |
93 | { | 93 | { |
94 | alias_t *old_aliases = aliases; | 94 | alias_t *old_aliases = aliases; |
95 | alias_t *ap; | 95 | alias_t *ap; |
... | @@ -97,18 +97,18 @@ alias_rehash() | ... | @@ -97,18 +97,18 @@ alias_rehash() |
97 | 97 | ||
98 | if (++hash_num >= max_rehash) | 98 | if (++hash_num >= max_rehash) |
99 | { | 99 | { |
100 | util_error("alias hash table full"); | 100 | util_error (_("alias hash table full")); |
101 | return 1; | 101 | return 1; |
102 | } | 102 | } |
103 | 103 | ||
104 | aliases = xcalloc(hash_size[hash_num], sizeof (aliases[0])); | 104 | aliases = xcalloc (hash_size[hash_num], sizeof (aliases[0])); |
105 | if (old_aliases) | 105 | if (old_aliases) |
106 | { | 106 | { |
107 | for (i = 0; i < hash_size[hash_num-1]; i++) | 107 | for (i = 0; i < hash_size[hash_num-1]; i++) |
108 | { | 108 | { |
109 | if (old_aliases[i].name) | 109 | if (old_aliases[i].name) |
110 | { | 110 | { |
111 | ap = alias_lookup_or_install(old_aliases[i].name, 1); | 111 | ap = alias_lookup_or_install (old_aliases[i].name, 1); |
112 | ap->name = old_aliases[i].name; | 112 | ap->name = old_aliases[i].name; |
113 | ap->list = old_aliases[i].list; | 113 | ap->list = old_aliases[i].list; |
114 | } | 114 | } |
... | @@ -119,7 +119,7 @@ alias_rehash() | ... | @@ -119,7 +119,7 @@ alias_rehash() |
119 | } | 119 | } |
120 | 120 | ||
121 | alias_t * | 121 | alias_t * |
122 | alias_lookup_or_install(char *name, int install) | 122 | alias_lookup_or_install (char *name, int install) |
123 | { | 123 | { |
124 | unsigned i, pos; | 124 | unsigned i, pos; |
125 | 125 | ||
... | @@ -127,14 +127,14 @@ alias_lookup_or_install(char *name, int install) | ... | @@ -127,14 +127,14 @@ alias_lookup_or_install(char *name, int install) |
127 | { | 127 | { |
128 | if (install) | 128 | if (install) |
129 | { | 129 | { |
130 | if (alias_rehash()) | 130 | if (alias_rehash ()) |
131 | return NULL; | 131 | return NULL; |
132 | } | 132 | } |
133 | else | 133 | else |
134 | return NULL; | 134 | return NULL; |
135 | } | 135 | } |
136 | 136 | ||
137 | pos = hash(name); | 137 | pos = hash (name); |
138 | 138 | ||
139 | for (i = pos; aliases[i].name;) | 139 | for (i = pos; aliases[i].name;) |
140 | { | 140 | { |
... | @@ -152,16 +152,16 @@ alias_lookup_or_install(char *name, int install) | ... | @@ -152,16 +152,16 @@ alias_lookup_or_install(char *name, int install) |
152 | if (aliases[i].name == NULL) | 152 | if (aliases[i].name == NULL) |
153 | return &aliases[i]; | 153 | return &aliases[i]; |
154 | 154 | ||
155 | if (alias_rehash()) | 155 | if (alias_rehash ()) |
156 | return NULL; | 156 | return NULL; |
157 | 157 | ||
158 | return alias_lookup_or_install(name, install); | 158 | return alias_lookup_or_install (name, install); |
159 | } | 159 | } |
160 | 160 | ||
161 | static int | 161 | static int |
162 | alias_lookup(char *name, list_t *plist) | 162 | alias_lookup (char *name, list_t *plist) |
163 | { | 163 | { |
164 | alias_t *ap = alias_lookup_or_install(name, 0); | 164 | alias_t *ap = alias_lookup_or_install (name, 0); |
165 | if (ap) | 165 | if (ap) |
166 | { | 166 | { |
167 | *plist = ap->list; | 167 | *plist = ap->list; |
... | @@ -171,7 +171,7 @@ alias_lookup(char *name, list_t *plist) | ... | @@ -171,7 +171,7 @@ alias_lookup(char *name, list_t *plist) |
171 | } | 171 | } |
172 | 172 | ||
173 | void | 173 | void |
174 | alias_print(char *name) | 174 | alias_print (char *name) |
175 | { | 175 | { |
176 | if (!name) | 176 | if (!name) |
177 | { | 177 | { |
... | @@ -183,35 +183,35 @@ alias_print(char *name) | ... | @@ -183,35 +183,35 @@ alias_print(char *name) |
183 | for (i = 0; i < hash_size[hash_num]; i++) | 183 | for (i = 0; i < hash_size[hash_num]; i++) |
184 | { | 184 | { |
185 | if (aliases[i].name) | 185 | if (aliases[i].name) |
186 | alias_print_group(aliases[i].name, aliases[i].list); | 186 | alias_print_group (aliases[i].name, aliases[i].list); |
187 | } | 187 | } |
188 | } | 188 | } |
189 | else | 189 | else |
190 | { | 190 | { |
191 | list_t list; | 191 | list_t list; |
192 | 192 | ||
193 | if (!alias_lookup(name, &list)) | 193 | if (!alias_lookup (name, &list)) |
194 | { | 194 | { |
195 | util_error(_("\"%s\": not a group"), name); | 195 | util_error (_("\"%s\": not a group"), name); |
196 | return; | 196 | return; |
197 | } | 197 | } |
198 | alias_print_group(name, list); | 198 | alias_print_group (name, list); |
199 | } | 199 | } |
200 | } | 200 | } |
201 | 201 | ||
202 | int | 202 | int |
203 | alias_create(char *name, list_t *plist) | 203 | alias_create (char *name, list_t *plist) |
204 | { | 204 | { |
205 | alias_t *ap = alias_lookup_or_install(name, 1); | 205 | alias_t *ap = alias_lookup_or_install (name, 1); |
206 | if (!ap) | 206 | if (!ap) |
207 | return 1; | 207 | return 1; |
208 | 208 | ||
209 | if (!ap->name) | 209 | if (!ap->name) |
210 | { | 210 | { |
211 | /* new entry */ | 211 | /* new entry */ |
212 | if (list_create(&ap->list)) | 212 | if (list_create (&ap->list)) |
213 | return 1; | 213 | return 1; |
214 | ap->name = strdup(name); | 214 | ap->name = strdup (name); |
215 | if (!ap->name) | 215 | if (!ap->name) |
216 | return 1; | 216 | return 1; |
217 | } | 217 | } |
... | @@ -222,22 +222,22 @@ alias_create(char *name, list_t *plist) | ... | @@ -222,22 +222,22 @@ alias_create(char *name, list_t *plist) |
222 | } | 222 | } |
223 | 223 | ||
224 | void | 224 | void |
225 | alias_print_group(char *name, list_t list) | 225 | alias_print_group (char *name, list_t list) |
226 | { | 226 | { |
227 | fprintf(ofile, "%s ", name); | 227 | fprintf (ofile, "%s ", name); |
228 | util_slist_print(list, 0); | 228 | util_slist_print (list, 0); |
229 | fprintf(ofile, "\n"); | 229 | fprintf (ofile, "\n"); |
230 | } | 230 | } |
231 | 231 | ||
232 | void | 232 | void |
233 | alias_destroy(char *name) | 233 | alias_destroy (char *name) |
234 | { | 234 | { |
235 | unsigned int i, j, r; | 235 | unsigned int i, j, r; |
236 | alias_t *alias = alias_lookup_or_install(name, 0); | 236 | alias_t *alias = alias_lookup_or_install (name, 0); |
237 | if (!alias) | 237 | if (!alias) |
238 | return; | 238 | return; |
239 | free(alias->name); | 239 | free (alias->name); |
240 | util_slist_destroy(&alias->list); | 240 | util_slist_destroy (&alias->list); |
241 | 241 | ||
242 | for (i = alias - aliases;;) | 242 | for (i = alias - aliases;;) |
243 | { | 243 | { |
... | @@ -251,18 +251,67 @@ alias_destroy(char *name) | ... | @@ -251,18 +251,67 @@ alias_destroy(char *name) |
251 | if (!aliases[i].name) | 251 | if (!aliases[i].name) |
252 | return; | 252 | return; |
253 | r = hash(aliases[i].name); | 253 | r = hash(aliases[i].name); |
254 | } while ((j < r && r <= i) || (i < j && j < r) || (r <= i && i < j)); | 254 | } |
255 | while ((j < r && r <= i) || (i < j && j < r) || (r <= i && i < j)); | ||
255 | 256 | ||
256 | aliases[j] = aliases[i]; | 257 | aliases[j] = aliases[i]; |
257 | } | 258 | } |
258 | } | 259 | } |
259 | 260 | ||
260 | char * | 261 | char * |
261 | alias_expand(char *name) | 262 | alias_expand (char *name) |
262 | { | 263 | { |
263 | list_t list; | 264 | list_t list; |
264 | 265 | ||
265 | if (!alias_lookup(name, &list)) | 266 | if (!alias_lookup (name, &list)) |
266 | return NULL; | 267 | return NULL; |
267 | return util_slist_to_string(list, ","); | 268 | return util_slist_to_string (list, ","); |
269 | } | ||
270 | |||
271 | struct alias_iterator | ||
272 | { | ||
273 | const char *prefix; | ||
274 | int prefixlen; | ||
275 | int pos; | ||
276 | }; | ||
277 | |||
278 | const char * | ||
279 | alias_iterate_next (alias_iterator_t itr) | ||
280 | { | ||
281 | int i; | ||
282 | for (i = itr->pos; i < hash_size[hash_num]; i++) | ||
283 | if (aliases[i].name | ||
284 | && strlen (aliases[i].name) >= itr->prefixlen | ||
285 | && strncmp (aliases[i].name, itr->prefix, itr->prefixlen) == 0) | ||
286 | { | ||
287 | itr->pos = i + 1; | ||
288 | return aliases[i].name; | ||
289 | } | ||
290 | return NULL; | ||
291 | } | ||
292 | |||
293 | const char * | ||
294 | alias_iterate_first (const char *prefix, alias_iterator_t *pc) | ||
295 | { | ||
296 | struct alias_iterator *itr; | ||
297 | |||
298 | if (!aliases) | ||
299 | { | ||
300 | *pc = NULL; | ||
301 | return NULL; | ||
302 | } | ||
303 | |||
304 | itr = xmalloc (sizeof *itr); | ||
305 | itr->prefix = prefix; | ||
306 | itr->prefixlen = strlen (prefix); | ||
307 | itr->pos = 0; | ||
308 | *pc = itr; | ||
309 | return alias_iterate_next (itr); | ||
310 | } | ||
311 | |||
312 | void | ||
313 | alias_iterate_end (alias_iterator_t *pc) | ||
314 | { | ||
315 | free (*pc); | ||
316 | *pc = NULL; | ||
268 | } | 317 | } | ... | ... |
-
Please register or sign in to post a comment