--- libaitcli/src/aitcli.c 2010/06/07 11:32:50 1.2.2.6 +++ libaitcli/src/aitcli.c 2010/06/07 13:49:25 1.2.2.10 @@ -3,10 +3,11 @@ * by Michael Pounov * * $Author: misho $ -* $Id: aitcli.c,v 1.2.2.6 2010/06/07 11:32:50 misho Exp $ +* $Id: aitcli.c,v 1.2.2.10 2010/06/07 13:49:25 misho Exp $ * *************************************************************************/ #include "global.h" +#include "cli.h" #pragma GCC visibility push(hidden) @@ -383,6 +384,51 @@ bufDEL(int idx, void * __restrict buffer) return RETCODE_OK; } +static int +bufComp(int idx, void * __restrict buffer) +{ + linebuffer_t *buf = buffer; + char *str, *s, **app, *items[MAX_PROMPT_ITEMS]; + register int i; + + if (!buffer || idx < 0 || idx > MAX_BINDKEY) + return RETCODE_ERR; + + str = strdup(buf->line_buf); + if (!str) + return RETCODE_ERR; + else { + s = str; + io_TrimStr((u_char*) s); + } + + if (*s) { + memset(items, 0, sizeof(char*) * MAX_PROMPT_ITEMS); + for (app = items, i = 0; app < items + MAX_PROMPT_ITEMS - 1 && (*app = strsep(&s, " \t")); + *app ? i++ : i, *app ? app++ : app); + + // todo +// SLIST_FOREACH(cmd, &buf->line_cmds; cmd_next) +// if (!strncmp(cmd->cmd_name, items[i - 1], strlen(items[i - 1]))) + } + + free(str); + return RETCODE_OK; +} + +static int +bufHelp(int idx, void * __restrict buffer) +{ + linebuffer_t *buf = buffer; + + if (!buffer || idx < 0 || idx > MAX_BINDKEY) + return RETCODE_ERR; + + cli_Cmd_Help(buf, -1, NULL); + printfCR(buf, 1); + return RETCODE_OK; +} + // --------------------------------------------------------------- /* @@ -447,11 +493,12 @@ cli_BindKey(bindkey_t * __restrict key, linebuffer_t * * @funcCmd = Callback function when user call command * @csInfo = Inline information for command * @csHelp = Help line when call help + * @anComp = Completion array terminated with NULL element, -1 complete commands, NULL nothing * return: RETCODE_ERR error, RETCODE_OK ok */ int cli_addCommand(linebuffer_t * __restrict buffer, const char *csCmd, int cliLevel, cmd_func_t funcCmd, - const char *csInfo, const char *csHelp) + const char *csInfo, const char *csHelp, const char **anComp) { struct tagCommand *cmd; @@ -469,6 +516,7 @@ cli_addCommand(linebuffer_t * __restrict buffer, const cmd->cmd_level = cliLevel; cmd->cmd_func = funcCmd; + cmd->cmd_comp = (char**) anComp; cmd->cmd_len = strlcpy(cmd->cmd_name, csCmd, STRSIZ); if (csInfo) strlcpy(cmd->cmd_info, csInfo, STRSIZ); @@ -515,11 +563,13 @@ cli_delCommand(linebuffer_t * __restrict buffer, const * @funcCmd = Callback function when user call command * @csInfo = Inline information for command * @csHelp = Help line when call help + * @anComp = Completion array terminated with NULL element, -1 complete commands, NULL nothing, + * update only if funcCmd is not NULL * return: RETCODE_ERR error, RETCODE_OK ok */ int cli_updCommand(linebuffer_t * __restrict buffer, const char *csCmd, int cliLevel, cmd_func_t funcCmd, - const char *csInfo, const char *csHelp) + const char *csInfo, const char *csHelp, const char **anComp) { struct tagCommand *cmd; int ret = RETCODE_OK; @@ -533,8 +583,10 @@ cli_updCommand(linebuffer_t * __restrict buffer, const if (cmd->cmd_level == cliLevel && !strcmp(cmd->cmd_name, csCmd)) { ret = 1; - if (funcCmd) + if (funcCmd) { cmd->cmd_func = funcCmd; + cmd->cmd_comp = (char**) anComp; + } if (csInfo) strlcpy(cmd->cmd_info, csInfo, STRSIZ); if (csHelp) @@ -853,6 +905,11 @@ cliInit(int fin, int fout, const char *prompt) } else memset(keys, 0, sizeof(bindkey_t) * (MAX_BINDKEY + 1)); + /* add helper functions */ + cli_addCommand(buffer, "exit", 0, cli_Cmd_Exit, "exit ", "Exit from console", NULL); + cli_addCommand(buffer, "help", 0, cli_Cmd_Help, "help [command] ", "Help screen", + (const char**) -1); + /* fill key bindings */ // ascii chars & ctrl+chars for (i = 0; i < 256; i++) { @@ -871,10 +928,14 @@ cliInit(int fin, int fout, const char *prompt) keys[i].key_func = bufBEGIN; if (i == *K_CTRL_E) keys[i].key_func = bufEND; + if (i == *K_TAB) + keys[i].key_func = bufComp; if (i >= *K_SPACE && i < *K_BACKSPACE) keys[i].key_func = bufCHAR; if (i > *K_BACKSPACE && i < 0xff) keys[i].key_func = bufCHAR; + if (i == '?') + keys[i].key_func = bufHelp; } // alt+chars for (i = 256; i < 512; i++) { @@ -1148,14 +1209,12 @@ cliNetLoop(linebuffer_t * __restrict buffer, const cha case 0: close(sock); -// buffer = cliInit(STDIN_FILENO, STDOUT_FILENO, csPrompt); -// if (!buffer) -// return RETCODE_ERR; + if (buffer) { + ret = cliLoop(buffer, csHistFile) < 0 ? 1 : 0; + cliEnd(buffer); + } else + cli_SetErr(EINVAL, "Error:: invalid input parameters ..."); - ret = cliLoop(buffer, csHistFile) < 0 ? 1 : 0; - -// cliEnd(buffer); - /* spawn Shell mode */ /* execl("/bin/tcsh", "tcsh", NULL); @@ -1250,12 +1309,6 @@ cliLoop(linebuffer_t * __restrict buffer, const char * struct tagCommand *cmd; /* - inline int inline_help() - { - cli_Cmd_Help(cmdList ? cmdList : cli_stdCmds, -1, out, NULL); - rl_on_new_line(); - return 0; - } char **cli_stdCompletion(const char *text, int start, int end) {