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

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.4 ! misho       6: * $Id: cli.c,v 1.1.2.3 2010/03/11 00:17:52 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.4 ! misho      93:        { "test", io_Cmd_Unsupported, "Test - Don`t use default command structure!", "test <cr>", io_Comp_Filename }, 
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: 
1.1.2.4 ! misho     147:                        for (i = state; cmdList[i].cmd_name; i++) {
1.1.2.2   misho     148:                                if (strncmp(cmdList[i].cmd_name, "---", 3) && 
                    149:                                                !strncmp(cmdList[i].cmd_name, text, len))
                    150:                                        return strdup(cmdList[i].cmd_name);
1.1.2.4 ! misho     151:                        }
1.1.2.2   misho     152: 
                    153:                        return NULL;
                    154:                }
                    155: 
                    156:                if (!start)
                    157:                        matches = rl_completion_matches(text, cmdCompGet);
                    158:                else
1.1.2.4 ! misho     159:                        for (i = 0; cmdList[i].cmd_name; i++) {
        !           160:                                if (!cmdList[i].cmd_comp)
        !           161:                                        continue;
        !           162:                                if (!strncmp(rl_line_buffer, cmdList[i].cmd_name, strlen(cmdList[i].cmd_name)))
1.1.2.2   misho     163:                                        matches = rl_completion_matches(text, cmdList[i].cmd_comp);
1.1.2.4 ! misho     164:                        }
1.1.2.2   misho     165: 
                    166:                return matches;
                    167:        }
                    168:        char *io_stdCompEntry(const char *ignore, int invoking_key)
                    169:        {
                    170:                return NULL;
                    171:        }
                    172: 
                    173:        rl_bind_key('?', inline_help);
                    174:        if (!rl_attempted_completion_function) 
                    175:                ioCLIComp(io_stdCompletion, io_stdCompEntry);
1.1.2.1   misho     176: 
                    177:        do {
                    178:                line = readline(csPrompt);
                    179:                if (!line) {    // ^+d
                    180:                        fprintf(out, "\n");
                    181:                        fflush(out);
                    182:                        break;
                    183:                }
                    184:                // clear whitespaces
                    185:                for (s = line; isspace(*s); s++);
                    186:                if (*s) {
                    187:                        for (t = s + strlen(s) - 1; t > s && isspace(*t); t--);
                    188:                        *++t = 0;
                    189:                }
                    190: 
                    191:                if (*s) {
                    192:                        add_history(s);
                    193: 
                    194:                        memset(items, 0, sizeof(char*) * 20);
                    195:                        for (app = items; app < items + 19 && (*app = strsep(&s, " \t")); *app ? app++ : app);
                    196: 
                    197:                        /*
                    198:                        for (i = 0; i < 20; i++)
                    199:                                printf("i=%d %s\n", i, items[i]);
                    200:                                */
                    201: 
                    202:                        // exec_cmd ...
                    203:                        for (cmd = NULL, i = 0; cmdList[i].cmd_name; i++)
                    204:                                if (*items[0] && !strncmp(cmdList[i].cmd_name, items[0], strlen(items[0]))) {
                    205:                                        cmd = &cmdList[i];
                    206:                                        break;
                    207:                                }
                    208:                        if (!cmd) {
                    209:                                fprintf(out, "Command '%s' not found!\n", items[0]);
                    210:                                ret = -1;
                    211:                        } else
                    212:                                ret = cmd->cmd_func(cmdList, out, items);
                    213:                }
                    214: 
                    215:                free(line);
                    216:        } while (ret < 1);
                    217: 
                    218:        return ret;
                    219: }

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