1 /* GLIB - Library of useful routines for C programming
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
23 static void completion_check_cache (GCompletion* cmp, gchar** new_prefix);
26 g_completion_new (GCompletionFunc func) {
29 gcomp = g_new(GCompletion, 1);
41 g_completion_add_items (GCompletion* cmp, GList* items) {
44 g_return_if_fail( cmp != NULL);
45 g_return_if_fail( items != NULL);
47 /* optimize adding to cache? */
49 g_list_free(cmp->cache);
59 cmp->items = g_list_prepend(cmp->items, it->data);
65 g_completion_remove_items (GCompletion* cmp, GList* items) {
68 g_return_if_fail( cmp != NULL);
69 g_return_if_fail( items != NULL);
72 while ( cmp->items && it ) {
73 cmp->items = g_list_remove(cmp->items, it->data);
77 while ( cmp->cache && it ) {
78 cmp->cache = g_list_remove(cmp->cache, it->data);
84 g_completion_clear_items (GCompletion* cmp) {
85 g_return_if_fail(cmp != NULL);
87 g_list_free(cmp->items);
89 g_list_free(cmp->cache);
96 completion_check_cache (GCompletion* cmp, gchar** new_prefix) {
111 len = strlen(cmp->prefix);
113 s = cmp->func?(*cmp->func)(list->data):(gchar*)list->data;
115 plen = strlen(postfix);
118 while (list && plen) {
119 s = cmp->func?(*cmp->func)(list->data):(gchar*)list->data;
121 for (i=0; i < plen; ++i) {
122 if ( postfix[i] != s[i] )
129 *new_prefix = g_new0(gchar, len+plen+1);
130 strncpy(*new_prefix, cmp->prefix, len);
131 strncpy(*new_prefix+len, postfix, plen);
135 g_completion_complete (GCompletion* cmp, gchar* prefix, gchar** new_prefix) {
140 g_return_val_if_fail(cmp != NULL, NULL);
141 g_return_val_if_fail(prefix != NULL, NULL);
143 len = strlen(prefix);
144 if ( cmp->prefix && cmp->cache ) {
145 plen = strlen(cmp->prefix);
146 if ( plen <= len && !strncmp(prefix, cmp->prefix, plen) ) {
150 if ( strncmp(prefix, cmp->func?(*cmp->func)(list->data):(gchar*)list->data, len) ) {
151 list = g_list_remove_link(cmp->cache, list);
152 if ( list != cmp->cache )
161 if (!done) { /* normal code */
162 g_list_free(cmp->cache);
165 while (*prefix && list) {
166 if ( !strncmp(prefix, cmp->func?(*cmp->func)(list->data):(gchar*)list->data, len) )
167 cmp->cache = g_list_prepend(cmp->cache, list->data);
176 cmp->prefix = g_strdup(prefix);
177 completion_check_cache(cmp, new_prefix);
178 return *prefix?cmp->cache:cmp->items;
183 g_completion_free (GCompletion* cmp) {
184 g_return_if_fail(cmp != NULL);
186 g_completion_clear_items(cmp);
190 #ifdef TEST_COMPLETION
194 int main (int argc, char* argv[]) {
206 g_warning("Usage: %s filename prefix1 [prefix2 ...]\n", argv[0]);
210 if ( !(file=fopen(argv[1], "r")) ) {
211 g_warning("Cannot open %s\n", argv[1]);
215 cmp = g_completion_new(NULL);
216 list = g_list_alloc();
217 while (fgets(buf, 1024, file)) {
218 list->data = g_strdup(buf);
219 g_completion_add_items(cmp, list);
223 for ( i= 2; i < argc; ++i) {
224 printf("COMPLETING: %s\n", argv[i]);
225 result = g_completion_complete(cmp, argv[i], &longp);
226 g_list_foreach(result, (GFunc)printf, NULL);
227 printf("LONG MATCH: %s\n", longp);
232 g_list_foreach(cmp->items, (GFunc)g_free, NULL);
233 g_completion_free(cmp);