#include #include #include #include #include int com_cd (char *); int com_help PARAMS((char *)); int com_list PARAMS((char *)); int com_quit PARAMS((char *)); enum node_type { ROOT = 1, CONFIG = 2, }; typedef struct { char *name; rl_icpfunc_t *func; char *doc; } COMMAND; typedef struct { int node; char *prompt; COMMAND *cmd_list; } NODES; COMMAND root_commands[] = { { "config", com_cd, "configure mode" }, { "help", com_help, "Display this text" }, { "?", com_help, "Synonym for `help'" }, { "quit", com_quit, "exit" }, { "exit", com_quit, "exit" }, { (char *)NULL, (rl_icpfunc_t *)NULL, (char *)NULL } }; COMMAND config_commands[] = { { "help", com_help, "Display this text" }, { "?", com_help, "Synonym for `help'" }, { "exit", com_list, "exit configure mode" }, { (char *)NULL, (rl_icpfunc_t *)NULL, (char *)NULL } }; NODES nodes_list[] = { { 0, (char *)NULL, (COMMAND *)NULL }, { ROOT, "knet> ", root_commands }, { CONFIG, "config> ", config_commands }, { 0, (char *)NULL, (COMMAND *)NULL } }; /* The name of this program, as taken from argv[0]. */ char *progname; int done = 0; int node = ROOT; static char * command_generator (const char *text, int state) { int list_index, len; char *name; if (!state) { list_index = 0; len = strlen(text); } while ((name = nodes_list[node].cmd_list[list_index].name)) { list_index++; if (strncmp (name, text, len) == 0) { return strdup(name); } } return ((char *)NULL); } static char **fileman_completion(const char *text, int start, int end) { char **matches; matches = (char **)NULL; if (start == 0) matches = rl_completion_matches (text, command_generator); return matches; } static int com_describe(void) { printf("describe me\n"); rl_on_new_line(); return 0; } static char *completion_entry_function (const char *ignore, int invoking_key) { return NULL; } static void initialize_readline(void) { /* Allow conditional parsing of the ~/.inputrc file. */ rl_readline_name = "FileMan"; /* Tell the completer that we want a crack first. */ rl_attempted_completion_function = fileman_completion; rl_bind_key('?', (Function *) com_describe); rl_completion_entry_function = completion_entry_function; } static char *stripwhite(char *string) { register char *s, *t; for (s = string; whitespace (*s); s++) ; if (*s == 0) return s; t = s + strlen (s) - 1; while (t > s && whitespace (*t)) t--; *++t = '\0'; return s; } static COMMAND *find_command(char *name) { register int i; for (i = 0; nodes_list[node].cmd_list[i].name; i++) if (strcmp (name, nodes_list[node].cmd_list[i].name) == 0) return (&nodes_list[node].cmd_list[i]); return ((COMMAND *)NULL); } static int execute_line(char *line) { register int i; COMMAND *command; char *word; /* Isolate the command word. */ i = 0; while (line[i] && whitespace (line[i])) i++; word = line + i; while (line[i] && !whitespace (line[i])) i++; if (line[i]) line[i++] = '\0'; command = find_command (word); if (!command) { fprintf (stderr, "%s: No such command for FileMan.\n", word); return -1; } while (whitespace (line[i])) i++; word = line + i; return ((*(command->func)) (word)); } int main(int argc, char **argv) { char *line, *s; progname = argv[0]; initialize_readline(); while (!done) { line = readline (nodes_list[node].prompt); if (!line) break; s = stripwhite (line); if (*s) { add_history(s); execute_line(s); } free(line); } return 0; } int com_help (char *arg) { register int i; int printed = 0; for (i = 0; nodes_list[node].cmd_list[i].name; i++) { if (!*arg || (strcmp (arg, nodes_list[node].cmd_list[i].name) == 0)) { printf ("%s\t\t%s.\n", nodes_list[node].cmd_list[i].name, nodes_list[node].cmd_list[i].doc); printed++; } } if (!printed) { printf ("No commands match `%s'. Possibilties are:\n", arg); for (i = 0; nodes_list[node].cmd_list[i].name; i++) { if (printed == 1) { printed = 0; printf ("\n"); } printf ("%s\t", nodes_list[node].cmd_list[i].name); printed++; } if (printed) printf ("\n"); } return 0; } int com_list (char *arg) { node = ROOT; return 0; } int com_cd (char *arg) { node = CONFIG; return 0; } int com_quit (char *arg) { done = 1; return 0; }