+/*
+ * Copyright (c) 2003 Nikodemus Siivola
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include <readline/readline.h>
+
+typedef struct {
+ char * str;
+ void * next;
+}
+node_t;
+
+node_t * collection = NULL;
+
+int
+add_completion (char * str)
+{
+ node_t * tmp = collection;
+ node_t * pre = NULL;
+ node_t * node;
+ while (tmp)
+ {
+ int cmp = strcmp (str, tmp->str);
+ if (0 == cmp)
+ return 1;
+
+ if (0 < cmp)
+ break;
+
+ /* printf ("-skip- (%s)\n", tmp->str);*/
+
+ pre = tmp;
+ tmp = tmp->next;
+ }
+
+ node = malloc (sizeof (node_t));
+ if (!node)
+ return 0;
+
+ node->next = tmp;
+ node->str = strdup (str);
+
+ if (! pre)
+ collection = node;
+ else
+ pre->next = node;
+
+ return 1;
+}
+
+node_t * root = NULL;
+
+char *
+custom_completer (const char * str, int target)
+{
+ size_t len = strlen (str);
+ if (0 == target)
+ {
+ root = NULL;
+ node_t * tmp = collection;
+ while (len && tmp)
+ {
+ if (0 == strncmp (str, tmp->str, len))
+ {
+ root = tmp;
+ return strdup (root->str);
+ }
+ else
+ tmp = tmp->next;
+ }
+ return (char *)NULL;
+ }
+ else if (root && (0 == strncmp (str, root->str, len)))
+ {
+ node_t * tmp = root;
+ root = root->next;
+ return strdup (tmp->str);
+ }
+ else
+ return (char *)NULL;
+}
+
+void
+clear_completions ()
+{
+ node_t * tmp;
+ while (collection)
+ {
+ /* printf ("-del- (%s)\n", collection->str); */
+ tmp = collection->next;
+ free (collection->str);
+ free (collection);
+ collection = tmp;
+ }
+}
+
+void
+use_custom_complete (void)
+{
+ rl_completion_entry_function = custom_completer;
+}
+
+void
+use_filename_complete (void)
+{
+ rl_completion_entry_function = rl_filename_completion_function;
+}