Annotation of libaitcli/src/aitcli.c, revision 1.1

1.1     ! misho       1: /*************************************************************************
        !             2: * (C) 2010 AITNET ltd - Sofia/Bulgaria - <misho@aitbg.com>
        !             3: *  by Michael Pounov <misho@openbsd-bg.org>
        !             4: *
        !             5: * $Author: misho $
        !             6: * $Id: cli.c,v 1.2 2010/03/22 15:21:20 misho Exp $
        !             7: *
        !             8: *************************************************************************/
        !             9: #include "global.h"
        !            10: 
        !            11: 
        !            12: #pragma GCC visibility push(hidden)
        !            13: 
        !            14: cliCommands_t cli_stdCmds[] = {
        !            15:        { "test", cli_Cmd_Unsupported, "Test - Don`t use default command structure!", "test <cr>", cli_Comp_Filename }, 
        !            16:        { "-------", NULL, "---------------------", NULL, NULL }, 
        !            17:        { "help", cli_Cmd_Help, "Help screen", "help [command] <cr>", NULL }, 
        !            18:        { "exit", cli_Cmd_Exit, "Exit from console", "exit <cr>", NULL }, 
        !            19:        { NULL, NULL, NULL, NULL }
        !            20: };
        !            21: 
        !            22: // ------------------------------------------------
        !            23: 
        !            24: int cli_Errno;
        !            25: char cli_Error[STRSIZ];
        !            26: 
        !            27: #pragma GCC visibility pop
        !            28: 
        !            29: 
        !            30: // cli_GetErrno() Get error code of last operation
        !            31: inline int cli_GetErrno()
        !            32: {
        !            33:        return cli_Errno;
        !            34: }
        !            35: 
        !            36: // io_GetError() Get error text of last operation
        !            37: inline const char *cli_GetError()
        !            38: {
        !            39:        return cli_Error;
        !            40: }
        !            41: 
        !            42: // cli_SetErr() Set error to variables for internal use!!!
        !            43: inline void cli_SetErr(int eno, char *estr, ...)
        !            44: {
        !            45:        va_list lst;
        !            46: 
        !            47:        cli_Errno = eno;
        !            48:        memset(cli_Error, 0, STRSIZ);
        !            49:        va_start(lst, estr);
        !            50:        vsnprintf(cli_Error, STRSIZ, estr, lst);
        !            51:        va_end(lst);
        !            52: }
        !            53: 
        !            54: // ------------------------------------------------------------
        !            55: 
        !            56: /*
        !            57:  * cli_Printf() Printf CLI features
        !            58:  * @out = Output stream
        !            59:  * @csFormat = Printf format string
        !            60:  * return: none
        !            61: */
        !            62: inline int cli_Printf(FILE *out, const char *csFormat, ...)
        !            63: {
        !            64:        va_list lst;
        !            65:        int ret;
        !            66: 
        !            67:        va_start(lst, csFormat);
        !            68: 
        !            69:        ret = vfprintf(out, csFormat, lst);
        !            70:        if (-1 == ret)
        !            71:                LOGERR;
        !            72: 
        !            73:        va_end(lst);
        !            74:        return ret;
        !            75: }
        !            76: 
        !            77: 
        !            78: /*
        !            79:  * cliComp() Initialize completion CLI features
        !            80:  * @cmdComplete = Completion function
        !            81:  * @cmdEntry = Compentry function
        !            82:  * return: none
        !            83: */
        !            84: inline void cliComp(cli_Completion_t *cmdComplete, cli_CompEntry_t *cmdEntry)
        !            85: {
        !            86:        // command completon
        !            87:        rl_attempted_completion_function = cmdComplete;
        !            88:        rl_completion_entry_function = cmdEntry;
        !            89: }
        !            90: 
        !            91: /*
        !            92:  * cliExec() Execute CLI main loop
        !            93:  * @cmdList = Commands list
        !            94:  * @out = Output handle
        !            95:  * @csPrompt = Prompt text
        !            96:  * return: -1 error, 0 = exit w/^+D, 1 done.
        !            97: */
        !            98: int cliExec(cliCommands_t *cmdList, FILE *out, const char *csPrompt)
        !            99: {
        !           100:        char *line, *s, *t, **app, *items[MAX_PROMPT_ITEMS];
        !           101:        int ret = 0;
        !           102:        register int i;
        !           103:        cliCommands_t *cmd = NULL;
        !           104: 
        !           105:        inline int inline_help()
        !           106:        {
        !           107:                cli_Cmd_Help(cmdList ? cmdList : cli_stdCmds, -1, out, NULL);
        !           108:                rl_on_new_line();
        !           109:                return 0;
        !           110:        }
        !           111: 
        !           112:        char **cli_stdCompletion(const char *text, int start, int end)
        !           113:        {
        !           114:                register int i;
        !           115:                char **matches = NULL;
        !           116: 
        !           117:                char *cmdCompGet(const char *text, int state)
        !           118:                {
        !           119:                        int len = strlen(text);
        !           120: 
        !           121:                        for (i = state; cmdList[i].cmd_name; i++) {
        !           122:                                if (strncmp(cmdList[i].cmd_name, "---", 3) && 
        !           123:                                                !strncmp(cmdList[i].cmd_name, text, len))
        !           124:                                        return strdup(cmdList[i].cmd_name);
        !           125:                        }
        !           126: 
        !           127:                        return NULL;
        !           128:                }
        !           129: 
        !           130:                if (!start)
        !           131:                        matches = rl_completion_matches(text, cmdCompGet);
        !           132:                else
        !           133:                        for (i = 0; cmdList[i].cmd_name; i++) {
        !           134:                                if (!cmdList[i].cmd_comp)
        !           135:                                        continue;
        !           136:                                if (!strncmp(rl_line_buffer, cmdList[i].cmd_name, strlen(cmdList[i].cmd_name)))
        !           137:                                        matches = rl_completion_matches(text, cmdList[i].cmd_comp);
        !           138:                        }
        !           139: 
        !           140:                return matches;
        !           141:        }
        !           142:        char *cli_stdCompEntry(const char *ignore, int invoking_key)
        !           143:        {
        !           144:                return NULL;
        !           145:        }
        !           146: 
        !           147:        /* --- main body of CLI --- */
        !           148: 
        !           149:        rl_bind_key('?', inline_help);
        !           150:        if (!rl_attempted_completion_function) 
        !           151:                cliComp(cli_stdCompletion, cli_stdCompEntry);
        !           152: 
        !           153:        do {
        !           154:                line = readline(csPrompt);
        !           155:                if (!line) {    // ^+d
        !           156:                        cli_Printf(out, "\n");
        !           157:                        break;
        !           158:                }
        !           159:                // clear whitespaces
        !           160:                for (s = line; isspace(*s); s++);
        !           161:                if (*s) {
        !           162:                        for (t = s + strlen(s) - 1; t > s && isspace(*t); t--);
        !           163:                        *++t = 0;
        !           164:                }
        !           165: 
        !           166:                if (*s) {
        !           167:                        add_history(s);
        !           168: 
        !           169:                        memset(items, 0, sizeof(char*) * MAX_PROMPT_ITEMS);
        !           170:                        for (app = items; app < items + MAX_PROMPT_ITEMS - 1 && (*app = strsep(&s, " \t")); 
        !           171:                                        *app ? app++ : app);
        !           172: 
        !           173:                        /*
        !           174:                        for (i = 0; i < MAX_PROMPT_ITEMS; i++)
        !           175:                                cli_Printf(out, "i=%d %s\n", i, items[i]);
        !           176:                                */
        !           177: 
        !           178:                        // exec_cmd ...
        !           179:                        for (cmd = NULL, i = 0; cmdList[i].cmd_name; i++)
        !           180:                                if (*items[0] && !strncmp(cmdList[i].cmd_name, items[0], strlen(items[0]))) {
        !           181:                                        cmd = &cmdList[i];
        !           182:                                        break;
        !           183:                                }
        !           184:                        if (!cmd) {
        !           185:                                cli_Printf(out, "Command '%s' not found!\n", items[0]);
        !           186:                                ret = -1;
        !           187:                        } else
        !           188:                                ret = cmd->cmd_func(cmdList, i, out, items);
        !           189:                }
        !           190: 
        !           191:                free(line);
        !           192:        } while (ret < 1);
        !           193: 
        !           194:        return ret;
        !           195: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>