--- libaitcli/src/aitcli.c 2010/06/07 12:30:28 1.2.2.8 +++ libaitcli/src/aitcli.c 2010/06/07 16:16:12 1.2.2.12 @@ -3,7 +3,7 @@ * by Michael Pounov * * $Author: misho $ -* $Id: aitcli.c,v 1.2.2.8 2010/06/07 12:30:28 misho Exp $ +* $Id: aitcli.c,v 1.2.2.12 2010/06/07 16:16:12 misho Exp $ * *************************************************************************/ #include "global.h" @@ -12,16 +12,6 @@ #pragma GCC visibility push(hidden) -/* -commands_t cli_stdCmds[] = { - { "test", cli_Cmd_Unsupported, "Test - Don`t use default command structure!", "test ", cli_Comp_Filename }, - { "-------", NULL, "---------------------", NULL, NULL }, - { "help", cli_Cmd_Help, "Help screen", "help [command] ", NULL }, - { "exit", cli_Cmd_Exit, "Exit from console", "exit ", NULL }, - { NULL, NULL, NULL, NULL } -}; -*/ - // ------------------------------------------------ int cli_Errno; @@ -108,17 +98,6 @@ printfNL(linebuffer_t * __restrict buf, int prompt) } } -static inline void -printfCLI(linebuffer_t * __restrict buf, const unsigned char *text, int textlen, int prompt) -{ - if (buf && text && textlen) { - if (prompt && buf->line_prompt) - write(buf->line_out, buf->line_prompt, buf->line_bol); - - write(buf->line_out, text, textlen); - } -} - // ------------------------------------------------------------ static int @@ -145,8 +124,8 @@ bufCHAR(int idx, void * __restrict buffer) write(buf->line_out, buf->line_keys[idx].key_ch, buf->line_keys[idx].key_len); if (buf->line_mode == LINEMODE_INS) { - printfCLI(buf, (const u_char*) buf->line_buf + pos + buf->line_keys[idx].key_len, - buf->line_len - buf->line_eol, 0); + write(buf->line_out, (const u_char*) buf->line_buf + pos + buf->line_keys[idx].key_len, + buf->line_len - buf->line_eol); printfEOL(buf, -1, 1); } return RETCODE_OK; @@ -165,12 +144,11 @@ bufEOL(int idx, void * __restrict buffer) static int bufEOF(int idx, void * __restrict buffer) { - linebuffer_t *buf = buffer; - + /* if (!buffer || idx < 0 || idx > MAX_BINDKEY) return RETCODE_ERR; + */ - write(buf->line_out, buf->line_keys[idx].key_ch, buf->line_keys[idx].key_len); return RETCODE_EOF; } @@ -388,11 +366,87 @@ static int bufComp(int idx, void * __restrict buffer) { linebuffer_t *buf = buffer; + char *str, *s, **app, *items[MAX_PROMPT_ITEMS], szLine[STRSIZ]; + register int i, j; + struct tagCommand *cmd, *c; + int pos, ret = RETCODE_OK; if (!buffer || idx < 0 || idx > MAX_BINDKEY) return RETCODE_ERR; - return RETCODE_OK; + str = strdup(buf->line_buf); + if (!str) + return RETCODE_ERR; + else { + s = str; + io_TrimStr((u_char*) s); + } + + i = j = 0; + c = NULL; + memset(szLine, 0, STRSIZ); + 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); + + if (i) { + SLIST_FOREACH(cmd, &buf->line_cmds, cmd_next) + if (cmd->cmd_level == buf->line_level && + !strncmp(cmd->cmd_name, items[0], strlen(items[0]))) { + j++; + c = cmd; + strlcat(szLine, " ", STRSIZ); + strlcat(szLine, cmd->cmd_name, STRSIZ); + } + + printf("i=%d j=%d c=%p name=%s comp=%p\n", i, j, c, c->cmd_name, c->cmd_comp); + if (i > 1 && j == 1 && c && c->cmd_comp) { + /* we are on argument of command and has complition callback */ + printf("ima comp!\n"); + goto endcomp; + } + } else { + /* we have valid char but i == 0, this case is illegal */ + ret = RETCODE_ERR; + goto endcomp; + } + } else { + /* we on 0 position of prompt, show commands for this level */ + SLIST_FOREACH(cmd, &buf->line_cmds, cmd_next) { + if (cmd->cmd_level == buf->line_level) + j++; + c = cmd; + strlcat(szLine, " ", STRSIZ); + strlcat(szLine, cmd->cmd_name, STRSIZ); + } + } + + /* completion show actions ... */ + if (j > 1 && c) { + printfNL(buf, 0); + write(buf->line_out, szLine, strlen(szLine)); + printfNL(buf, 1); + } + if (j == 1 && c) { + clrscrEOL(buf); + cli_freeLine(buf); + + pos = buf->line_eol - buf->line_bol; + + buf->line_len += c->cmd_len + 1; + buf->line_eol += c->cmd_len + 1; + + memcpy(buf->line_buf + pos, c->cmd_name, c->cmd_len); + buf->line_buf[pos + c->cmd_len] = (u_char) *K_SPACE; + buf->line_buf[buf->line_len - 1] = 0; + + printfEOL(buf, -1, 1); + } + +endcomp: + free(str); + return ret; } static int @@ -472,11 +526,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; @@ -494,6 +549,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); @@ -540,11 +596,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; @@ -558,8 +616,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) @@ -879,8 +939,9 @@ cliInit(int fin, int fout, const char *prompt) memset(keys, 0, sizeof(bindkey_t) * (MAX_BINDKEY + 1)); /* add helper functions */ - cli_addCommand(buffer, "exit", 0, cli_Cmd_Exit, "exit ", "Exit from console"); - cli_addCommand(buffer, "help", 0, cli_Cmd_Help, "help [command] ", "Help screen"); + 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