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>