/* Custom CLI command completion. * * Copyright (c) 1992, 1993 Simmule Turner and Rich Salz. All rights reserved. * * This software is not subject to any license of the American Telephone * and Telegraph Company or of the Regents of the University of California. * * Permission is granted to anyone to use this software for any purpose on * any computer system, and to alter it and redistribute it freely, subject * to the following restrictions: * 1. The authors are not responsible for the consequences of use of this * software, no matter how awful, even if they arise from flaws in it. * 2. The origin of this software must not be misrepresented, either by * explicit claim or by omission. Since few users ever read sources, * credits must appear in the documentation. * 3. Altered versions must be plainly marked as such, and must not be * misrepresented as being the original software. Since few users * ever read sources, credits must appear in the documentation. * 4. This notice may not be removed or altered. */ #include "editline.h" #include #include #define HISTORY "/tmp/.cli-history" static char *list[] = { "foo ", "bar ", "bsd ", "cli ", "ls ", "cd ", "malloc ", "tee ", NULL }; /* Attempt to complete the pathname, returning an allocated copy. * Fill in *unique if we completed it, or set it to 0 if ambiguous. */ static char *my_rl_complete(char *token, int *match) { int i; int index = -1; int matchlen = 0; int count = 0; for (i = 0; list[i]; i++) { int partlen = strlen (token); /* Part of token */ if (!strncmp (list[i], token, partlen)) { index = i; matchlen = partlen; count ++; } } if (count == 1) { *match = 1; return strdup (list[index] + matchlen); } return NULL; } /* Return all possible completions. */ static int my_rl_list_possib(char *token, char ***av) { int i, num, total = 0; char **copy; for (num = 0; list[num]; num++) ; copy = (char **) malloc (num * sizeof(char *)); for (i = 0; i < num; i++) { if (!strncmp (list[i], token, strlen (token))) { copy[total] = strdup (list[i]); total ++; } } *av = copy; return total; } el_status_t list_possible(void) { char **av; char *word; int ac; word = el_find_word(); ac = rl_list_possib(word, &av); if (word) free(word); if (ac) { el_print_columns(ac, av); while (--ac >= 0) free(av[ac]); free(av); return CSmove; } return el_ring_bell(); } el_status_t do_break(void) { puts("Breakout!"); return CSeof; } el_status_t do_exit(void) { puts("Bye bye!"); return CSeof; } el_status_t do_suspend(void) { puts("Abort!"); return CSstay; } static int my_rl_check_secret(const char *line) { const char *pattern = (char *)"^unlock\\s"; regex_t regex; int rc = 0; if (!line || regcomp(®ex, pattern, 0)) return 0; if (!regexec(®ex, line, 0, NULL, 0)) rc = 1; regfree(®ex); return rc; } int main(void) { char *line; char *prompt = "cli> "; /* Setup callbacks */ rl_set_complete_func(&my_rl_complete); rl_set_list_possib_func(&my_rl_list_possib); rl_set_check_secret_func(&my_rl_check_secret); el_bind_key('?', list_possible); el_bind_key(CTL('C'), do_break); el_bind_key(CTL('D'), do_exit); el_bind_key(CTL('Z'), do_suspend); read_history(HISTORY); while ((line = readline(prompt)) != NULL) { printf("\t\t\t|%s|\n", line); free(line); } write_history(HISTORY); return 0; } /** * Local Variables: * c-file-style: "k&r" * c-basic-offset: 4 * End: */