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

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 $
1.1.1.1.2.3! misho       6: * $Id: aitcli.c,v 1.1.1.1.2.2 2010/04/19 09:30:49 misho Exp $
1.1       misho       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: /*
1.1.1.1.2.1  misho      92:  * cliTTY() Initialize I/O TTY CLI features
1.1.1.1.2.3! misho      93:  * @term = terminal name
1.1.1.1.2.1  misho      94:  * @inp = input handle
                     95:  * @out = output handle
                     96:  * return: none
                     97: */
1.1.1.1.2.3! misho      98: inline void cliTTY(const char *term, FILE *inp, FILE *out)
1.1.1.1.2.1  misho      99: {
1.1.1.1.2.3! misho     100:        rl_terminal_name = term;
1.1.1.1.2.1  misho     101:        rl_outstream = inp;
                    102:        rl_outstream = out;
                    103: }
                    104: 
                    105: /*
1.1       misho     106:  * cliExec() Execute CLI main loop
                    107:  * @cmdList = Commands list
                    108:  * @csPrompt = Prompt text
                    109:  * return: -1 error, 0 = exit w/^+D, 1 done.
                    110: */
1.1.1.1.2.2  misho     111: int cliExec(cliCommands_t *cmdList, const char *csPrompt)
1.1       misho     112: {
                    113:        char *line, *s, *t, **app, *items[MAX_PROMPT_ITEMS];
                    114:        int ret = 0;
                    115:        register int i;
                    116:        cliCommands_t *cmd = NULL;
1.1.1.1.2.2  misho     117:        FILE *out;
1.1       misho     118: 
                    119:        inline int inline_help()
                    120:        {
                    121:                cli_Cmd_Help(cmdList ? cmdList : cli_stdCmds, -1, out, NULL);
                    122:                rl_on_new_line();
                    123:                return 0;
                    124:        }
                    125: 
                    126:        char **cli_stdCompletion(const char *text, int start, int end)
                    127:        {
                    128:                register int i;
                    129:                char **matches = NULL;
                    130: 
                    131:                char *cmdCompGet(const char *text, int state)
                    132:                {
                    133:                        int len = strlen(text);
                    134: 
                    135:                        for (i = state; cmdList[i].cmd_name; i++) {
                    136:                                if (strncmp(cmdList[i].cmd_name, "---", 3) && 
                    137:                                                !strncmp(cmdList[i].cmd_name, text, len))
                    138:                                        return strdup(cmdList[i].cmd_name);
                    139:                        }
                    140: 
                    141:                        return NULL;
                    142:                }
                    143: 
                    144:                if (!start)
                    145:                        matches = rl_completion_matches(text, cmdCompGet);
                    146:                else
                    147:                        for (i = 0; cmdList[i].cmd_name; i++) {
                    148:                                if (!cmdList[i].cmd_comp)
                    149:                                        continue;
                    150:                                if (!strncmp(rl_line_buffer, cmdList[i].cmd_name, strlen(cmdList[i].cmd_name)))
                    151:                                        matches = rl_completion_matches(text, cmdList[i].cmd_comp);
                    152:                        }
                    153: 
                    154:                return matches;
                    155:        }
                    156:        char *cli_stdCompEntry(const char *ignore, int invoking_key)
                    157:        {
                    158:                return NULL;
                    159:        }
                    160: 
                    161:        /* --- main body of CLI --- */
                    162: 
1.1.1.1.2.2  misho     163:        out = rl_outstream;
                    164:        if (!out)
                    165:                out = stdout;
                    166: 
1.1       misho     167:        rl_bind_key('?', inline_help);
                    168:        if (!rl_attempted_completion_function) 
                    169:                cliComp(cli_stdCompletion, cli_stdCompEntry);
                    170: 
                    171:        do {
                    172:                line = readline(csPrompt);
                    173:                if (!line) {    // ^+d
                    174:                        cli_Printf(out, "\n");
                    175:                        break;
                    176:                }
                    177:                // clear whitespaces
                    178:                for (s = line; isspace(*s); s++);
                    179:                if (*s) {
                    180:                        for (t = s + strlen(s) - 1; t > s && isspace(*t); t--);
                    181:                        *++t = 0;
                    182:                }
                    183: 
                    184:                if (*s) {
                    185:                        add_history(s);
                    186: 
                    187:                        memset(items, 0, sizeof(char*) * MAX_PROMPT_ITEMS);
                    188:                        for (app = items; app < items + MAX_PROMPT_ITEMS - 1 && (*app = strsep(&s, " \t")); 
                    189:                                        *app ? app++ : app);
                    190: 
                    191:                        /*
                    192:                        for (i = 0; i < MAX_PROMPT_ITEMS; i++)
                    193:                                cli_Printf(out, "i=%d %s\n", i, items[i]);
                    194:                                */
                    195: 
                    196:                        // exec_cmd ...
                    197:                        for (cmd = NULL, i = 0; cmdList[i].cmd_name; i++)
                    198:                                if (*items[0] && !strncmp(cmdList[i].cmd_name, items[0], strlen(items[0]))) {
                    199:                                        cmd = &cmdList[i];
                    200:                                        break;
                    201:                                }
                    202:                        if (!cmd) {
                    203:                                cli_Printf(out, "Command '%s' not found!\n", items[0]);
                    204:                                ret = -1;
                    205:                        } else
                    206:                                ret = cmd->cmd_func(cmdList, i, out, items);
                    207:                }
                    208: 
                    209:                free(line);
                    210:        } while (ret < 1);
                    211: 
                    212:        return ret;
                    213: }

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