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>