Annotation of libaitio/src/cli.c, revision 1.1.2.3

1.1.2.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.2.3 ! misho       6: * $Id: cli.c,v 1.1.2.2 2010/03/09 13:47:02 misho Exp $
1.1.2.1   misho       7: *
                      8: *************************************************************************/
                      9: #include "global.h"
                     10: 
                     11: 
1.1.2.2   misho      12: /*
                     13:  * io_Cmd_Exit() Builtin helper function for Exit from Cli
                     14:  * @cmds = Commands list
                     15:  * @out = Output handle
                     16:  * @args = Parsed arguments array
                     17:  * return: 1 exit from Cli!
                     18: */
                     19: int io_Cmd_Exit(void *cmds, FILE *out, char ** __restrict args)
1.1.2.1   misho      20: {
                     21:        return 1;
                     22: }
                     23: 
1.1.2.2   misho      24: /*
                     25:  * io_Cmd_Help() Builtin helper function for Help screen
                     26:  * @cmds = Commands list
                     27:  * @out = Output handle
                     28:  * @args = Parsed arguments array
                     29:  * return: -1 error, 0 = ok
                     30: */
                     31: int io_Cmd_Help(void *cmds, FILE *out, char ** __restrict args)
1.1.2.1   misho      32: {
                     33:        register int i;
                     34:        ioCommands_t *commands = cmds;
                     35: 
                     36:        if (!cmds)
                     37:                return -1;
                     38: 
                     39:        if (!args) {
                     40:                fprintf(out, "\n");
                     41:                for (i = 0; commands[i].cmd_name; i++)
                     42:                        fprintf(out, "%s\t\t%s\n", commands[i].cmd_name, commands[i].cmd_doc);
                     43:        } else {
                     44:                if (!args[1])
                     45:                        fprintf(out, "Help screen::\n");
                     46:                else
                     47:                        if (!strncmp(args[1], "---", 3))
                     48:                                return 0;
                     49: 
                     50:                for (i = 0; commands[i].cmd_name; i++) {
                     51:                        if (args[1] && strcmp(args[1], commands[i].cmd_name))
                     52:                                continue;
                     53: 
                     54:                        fprintf(out, "%s%s\t\t%s\n", args[1] ? "Syntax::\n\t" : "", commands[i].cmd_name, 
                     55:                                        args[1] ? commands[i].cmd_help : commands[i].cmd_doc);
                     56:                }
                     57:        }
                     58: 
                     59:        return 0;
                     60: }
                     61: 
1.1.2.2   misho      62: /*
                     63:  * io_Cmd_Unsupported() Builtin helper function for unsupported commands
                     64:  * @cmds = Commands list
                     65:  * @out = Output handle
                     66:  * @args = Parsed arguments array
                     67:  * return: -1 error, 0 = ok, 1 exit from Cli!
                     68: */
                     69: int io_Cmd_Unsupported(void *cmds, FILE *out, char ** __restrict args)
1.1.2.1   misho      70: {
                     71:        fprintf(out, "Command %s not supported in this version ...\n", args[0]);
                     72:        return 0;
                     73: }
                     74: 
                     75: // ------------------------------------------------------------
                     76: 
1.1.2.3 ! misho      77: /*
        !            78:  * io_Comp_Filename() Builtin helper function for filename completion arguments
        !            79:  * @text = Text line
        !            80:  * @state = Position state
        !            81:  * return: NULL not found filename, != NULL filename
        !            82: */
        !            83: char *io_Comp_Filename(const char *text, int state)
        !            84: {
        !            85:        return rl_filename_completion_function(text, state);
        !            86: }
        !            87: 
        !            88: // ------------------------------------------------------------
        !            89: 
1.1.2.1   misho      90: #pragma GCC visibility push(hidden)
                     91: 
                     92: ioCommands_t io_stdCmds[] = {
1.1.2.2   misho      93:        { "test", io_Cmd_Unsupported, "Test - Don`t use default command structure!", "test <cr>", NULL }, 
1.1.2.1   misho      94:        { "-------", NULL, "---------------------", NULL, NULL }, 
1.1.2.2   misho      95:        { "help", io_Cmd_Help, "Help screen", "help [command] <cr>", NULL }, 
                     96:        { "exit", io_Cmd_Exit, "Exit from console", "exit <cr>", NULL }, 
1.1.2.1   misho      97:        { NULL, NULL, NULL, NULL }
                     98: };
                     99: 
                    100: #pragma GCC visibility pop
                    101: 
                    102: // ------------------------------------------------------------
                    103: 
                    104: /*
1.1.2.2   misho     105:  * ioCLIComp() Initialize completion CLI features
1.1.2.1   misho     106:  * @cmdComplete = Completion function
                    107:  * @cmdEntry = Compentry function
                    108:  * return: none
                    109: */
1.1.2.2   misho     110: inline void ioCLIComp(io_Completion_t *cmdComplete, io_CompEntry_t *cmdEntry)
1.1.2.1   misho     111: {
                    112:        // command completon
                    113:        rl_attempted_completion_function = cmdComplete;
                    114:        rl_completion_entry_function = cmdEntry;
                    115: }
                    116: 
                    117: /*
                    118:  * ioCLIExec() Execute CLI main loop
                    119:  * @cmdList = Commands list
                    120:  * @out = Output handle
                    121:  * @csPrompt = Prompt text
                    122:  * return: -1 error, 0 = exit w/^+D, 1 done.
                    123: */
                    124: int ioCLIExec(ioCommands_t *cmdList, FILE *out, const char *csPrompt)
                    125: {
                    126:        char *line, *s, *t, **app, *items[20];
                    127:        int ret = 0;
                    128:        register int i;
                    129:        ioCommands_t *cmd = NULL;
                    130: 
1.1.2.2   misho     131:        inline int inline_help()
                    132:        {
                    133:                io_Cmd_Help(cmdList ? cmdList : io_stdCmds, out, NULL);
                    134:                rl_on_new_line();
                    135:                return 0;
                    136:        }
                    137: 
                    138:        char **io_stdCompletion(const char *text, int start, int end)
                    139:        {
                    140:                register int i;
                    141:                char **matches = NULL;
                    142: 
                    143:                char *cmdCompGet(const char *text, int state)
                    144:                {
                    145:                        int len = strlen(text);
                    146: 
                    147:                        for (i = state; cmdList[i].cmd_name; i++)
                    148:                                if (strncmp(cmdList[i].cmd_name, "---", 3) && 
                    149:                                                !strncmp(cmdList[i].cmd_name, text, len))
                    150:                                        return strdup(cmdList[i].cmd_name);
                    151: 
                    152:                        return NULL;
                    153:                }
                    154: 
                    155:                if (!start)
                    156:                        matches = rl_completion_matches(text, cmdCompGet);
                    157:                else
                    158:                        for (i = 0; cmdList[i].cmd_name; i++)
                    159:                                if (cmdList[i].cmd_comp && !strncmp(rl_line_buffer, 
                    160:                                                        cmdList[i].cmd_name, strlen(cmdList[i].cmd_name)))
                    161:                                        matches = rl_completion_matches(text, cmdList[i].cmd_comp);
                    162: 
                    163:                return matches;
                    164:        }
                    165:        char *io_stdCompEntry(const char *ignore, int invoking_key)
                    166:        {
                    167:                return NULL;
                    168:        }
                    169: 
                    170:        rl_bind_key('?', inline_help);
                    171:        if (!rl_attempted_completion_function) 
                    172:                ioCLIComp(io_stdCompletion, io_stdCompEntry);
1.1.2.1   misho     173: 
                    174:        do {
                    175:                line = readline(csPrompt);
                    176:                if (!line) {    // ^+d
                    177:                        fprintf(out, "\n");
                    178:                        fflush(out);
                    179:                        break;
                    180:                }
                    181:                // clear whitespaces
                    182:                for (s = line; isspace(*s); s++);
                    183:                if (*s) {
                    184:                        for (t = s + strlen(s) - 1; t > s && isspace(*t); t--);
                    185:                        *++t = 0;
                    186:                }
                    187: 
                    188:                if (*s) {
                    189:                        add_history(s);
                    190: 
                    191:                        memset(items, 0, sizeof(char*) * 20);
                    192:                        for (app = items; app < items + 19 && (*app = strsep(&s, " \t")); *app ? app++ : app);
                    193: 
                    194:                        /*
                    195:                        for (i = 0; i < 20; i++)
                    196:                                printf("i=%d %s\n", i, items[i]);
                    197:                                */
                    198: 
                    199:                        // exec_cmd ...
                    200:                        for (cmd = NULL, i = 0; cmdList[i].cmd_name; i++)
                    201:                                if (*items[0] && !strncmp(cmdList[i].cmd_name, items[0], strlen(items[0]))) {
                    202:                                        cmd = &cmdList[i];
                    203:                                        break;
                    204:                                }
                    205:                        if (!cmd) {
                    206:                                fprintf(out, "Command '%s' not found!\n", items[0]);
                    207:                                ret = -1;
                    208:                        } else
                    209:                                ret = cmd->cmd_func(cmdList, out, items);
                    210:                }
                    211: 
                    212:                free(line);
                    213:        } while (ret < 1);
                    214: 
                    215:        return ret;
                    216: }

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