xref: /nrf52832-nimble/packages/NimBLE-latest/porting/npl/rtthread/src/npl_shell.c (revision 042d53a763ad75cb1465103098bb88c245d95138)
1*042d53a7SEvalZero /*
2*042d53a7SEvalZero  * SPDX-License-Identifier: Apache-2.0
3*042d53a7SEvalZero  *
4*042d53a7SEvalZero  * Date           Author       Notes
5*042d53a7SEvalZero  * 2019-02-14     ZeroFree     first implementation
6*042d53a7SEvalZero  */
7*042d53a7SEvalZero 
8*042d53a7SEvalZero #include <string.h>
9*042d53a7SEvalZero #include "nimble/nimble_npl.h"
10*042d53a7SEvalZero #include "nimble/npl_shell.h"
11*042d53a7SEvalZero 
12*042d53a7SEvalZero #include <rtthread.h>
13*042d53a7SEvalZero 
14*042d53a7SEvalZero #define SHELL_PROMPT "shell"
15*042d53a7SEvalZero #define SHELL_MAX_MODULES 3
16*042d53a7SEvalZero #define SHELL_PROMPT_SUFFIX "> "
17*042d53a7SEvalZero 
18*042d53a7SEvalZero static const char *get_command_and_module(char *argv[], int *module);
19*042d53a7SEvalZero static int set_default_module(const char *name);
20*042d53a7SEvalZero static void print_prompt(void);
21*042d53a7SEvalZero static int get_destination_module(const char *module_str, int len);
22*042d53a7SEvalZero static int show_cmd_help(char *argv[]);
23*042d53a7SEvalZero 
24*042d53a7SEvalZero static struct shell_module shell_modules[SHELL_MAX_MODULES];
25*042d53a7SEvalZero static size_t num_of_shell_entities;
26*042d53a7SEvalZero 
27*042d53a7SEvalZero static const char *prompt;
28*042d53a7SEvalZero static int default_module = -1;
29*042d53a7SEvalZero 
30*042d53a7SEvalZero static shell_cmd_func_t app_cmd_handler;
31*042d53a7SEvalZero static shell_prompt_function_t app_prompt_handler;
32*042d53a7SEvalZero 
console_write(const char * str,int cnt)33*042d53a7SEvalZero void console_write(const char *str, int cnt)
34*042d53a7SEvalZero {
35*042d53a7SEvalZero     rt_device_write(rt_console_get_device(), 0, str, cnt);
36*042d53a7SEvalZero }
37*042d53a7SEvalZero 
shell_register(const char * module_name,const struct shell_cmd * commands)38*042d53a7SEvalZero int shell_register(const char *module_name, const struct shell_cmd *commands)
39*042d53a7SEvalZero {
40*042d53a7SEvalZero     if (num_of_shell_entities >= SHELL_MAX_MODULES)
41*042d53a7SEvalZero     {
42*042d53a7SEvalZero         console_printf("Max number of modules reached\n");
43*042d53a7SEvalZero         return -1;
44*042d53a7SEvalZero     }
45*042d53a7SEvalZero 
46*042d53a7SEvalZero     shell_modules[num_of_shell_entities].name = module_name;
47*042d53a7SEvalZero     shell_modules[num_of_shell_entities].commands = commands;
48*042d53a7SEvalZero     ++num_of_shell_entities;
49*042d53a7SEvalZero 
50*042d53a7SEvalZero     return 0;
51*042d53a7SEvalZero }
52*042d53a7SEvalZero 
shell_register_default_module(const char * name)53*042d53a7SEvalZero void shell_register_default_module(const char *name)
54*042d53a7SEvalZero {
55*042d53a7SEvalZero     int result = set_default_module(name);
56*042d53a7SEvalZero 
57*042d53a7SEvalZero     if (result != -1)
58*042d53a7SEvalZero     {
59*042d53a7SEvalZero         console_printf("\n");
60*042d53a7SEvalZero         print_prompt();
61*042d53a7SEvalZero     }
62*042d53a7SEvalZero }
63*042d53a7SEvalZero 
print_modules(void)64*042d53a7SEvalZero static void print_modules(void)
65*042d53a7SEvalZero {
66*042d53a7SEvalZero     int module;
67*042d53a7SEvalZero 
68*042d53a7SEvalZero     for (module = 0; module < num_of_shell_entities; module++)
69*042d53a7SEvalZero     {
70*042d53a7SEvalZero         console_printf("%s\n", shell_modules[module].name);
71*042d53a7SEvalZero     }
72*042d53a7SEvalZero }
73*042d53a7SEvalZero 
print_module_commands(const int module)74*042d53a7SEvalZero static void print_module_commands(const int module)
75*042d53a7SEvalZero {
76*042d53a7SEvalZero     const struct shell_module *shell_module = &shell_modules[module];
77*042d53a7SEvalZero     int i;
78*042d53a7SEvalZero 
79*042d53a7SEvalZero     console_printf("help\n");
80*042d53a7SEvalZero 
81*042d53a7SEvalZero     for (i = 0; shell_module->commands[i].sc_cmd; i++)
82*042d53a7SEvalZero     {
83*042d53a7SEvalZero         console_printf("%-30s", shell_module->commands[i].sc_cmd);
84*042d53a7SEvalZero         if (shell_module->commands[i].help &&
85*042d53a7SEvalZero                 shell_module->commands[i].help->summary)
86*042d53a7SEvalZero         {
87*042d53a7SEvalZero             console_printf("%s", shell_module->commands[i].help->summary);
88*042d53a7SEvalZero         }
89*042d53a7SEvalZero         console_printf("\n");
90*042d53a7SEvalZero     }
91*042d53a7SEvalZero }
92*042d53a7SEvalZero 
show_help(int argc,char * argv[])93*042d53a7SEvalZero static int show_help(int argc, char *argv[])
94*042d53a7SEvalZero {
95*042d53a7SEvalZero     int module;
96*042d53a7SEvalZero 
97*042d53a7SEvalZero     /* help per command */
98*042d53a7SEvalZero     if ((argc > 2) || ((default_module != -1) && (argc == 2)))
99*042d53a7SEvalZero     {
100*042d53a7SEvalZero         return show_cmd_help(&argv[1]);
101*042d53a7SEvalZero     }
102*042d53a7SEvalZero 
103*042d53a7SEvalZero     /* help per module */
104*042d53a7SEvalZero     if ((argc == 2) || ((default_module != -1) && (argc == 1)))
105*042d53a7SEvalZero     {
106*042d53a7SEvalZero         if (default_module == -1)
107*042d53a7SEvalZero         {
108*042d53a7SEvalZero             module = get_destination_module(argv[1], -1);
109*042d53a7SEvalZero             if (module == -1)
110*042d53a7SEvalZero             {
111*042d53a7SEvalZero                 console_printf("Illegal module %s\n", argv[1]);
112*042d53a7SEvalZero                 return 0;
113*042d53a7SEvalZero             }
114*042d53a7SEvalZero         }
115*042d53a7SEvalZero         else
116*042d53a7SEvalZero         {
117*042d53a7SEvalZero             module = default_module;
118*042d53a7SEvalZero         }
119*042d53a7SEvalZero 
120*042d53a7SEvalZero         print_module_commands(module);
121*042d53a7SEvalZero     }
122*042d53a7SEvalZero     else     /* help for all entities */
123*042d53a7SEvalZero     {
124*042d53a7SEvalZero         console_printf("Available modules:\n");
125*042d53a7SEvalZero         print_modules();
126*042d53a7SEvalZero         console_printf("To select a module, enter 'select <module name>'.\n");
127*042d53a7SEvalZero     }
128*042d53a7SEvalZero 
129*042d53a7SEvalZero     return 0;
130*042d53a7SEvalZero }
131*042d53a7SEvalZero 
set_default_module(const char * name)132*042d53a7SEvalZero static int set_default_module(const char *name)
133*042d53a7SEvalZero {
134*042d53a7SEvalZero     int module;
135*042d53a7SEvalZero 
136*042d53a7SEvalZero     module = get_destination_module(name, -1);
137*042d53a7SEvalZero 
138*042d53a7SEvalZero     if (module == -1)
139*042d53a7SEvalZero     {
140*042d53a7SEvalZero         console_printf("Illegal module %s, default is not changed\n", name);
141*042d53a7SEvalZero         return -1;
142*042d53a7SEvalZero     }
143*042d53a7SEvalZero 
144*042d53a7SEvalZero     default_module = module;
145*042d53a7SEvalZero 
146*042d53a7SEvalZero     return 0;
147*042d53a7SEvalZero }
148*042d53a7SEvalZero 
select_module(int argc,char * argv[])149*042d53a7SEvalZero static int select_module(int argc, char *argv[])
150*042d53a7SEvalZero {
151*042d53a7SEvalZero     if (argc == 1)
152*042d53a7SEvalZero     {
153*042d53a7SEvalZero         default_module = -1;
154*042d53a7SEvalZero     }
155*042d53a7SEvalZero     else
156*042d53a7SEvalZero     {
157*042d53a7SEvalZero         set_default_module(argv[1]);
158*042d53a7SEvalZero     }
159*042d53a7SEvalZero 
160*042d53a7SEvalZero     return 0;
161*042d53a7SEvalZero }
162*042d53a7SEvalZero 
line2argv(char * str,char * argv[],size_t size)163*042d53a7SEvalZero static size_t line2argv(char *str, char *argv[], size_t size)
164*042d53a7SEvalZero {
165*042d53a7SEvalZero     size_t argc = 0;
166*042d53a7SEvalZero 
167*042d53a7SEvalZero     if (!strlen(str))
168*042d53a7SEvalZero     {
169*042d53a7SEvalZero         return 0;
170*042d53a7SEvalZero     }
171*042d53a7SEvalZero 
172*042d53a7SEvalZero     while (*str && *str == ' ')
173*042d53a7SEvalZero     {
174*042d53a7SEvalZero         str++;
175*042d53a7SEvalZero     }
176*042d53a7SEvalZero 
177*042d53a7SEvalZero     if (!*str)
178*042d53a7SEvalZero     {
179*042d53a7SEvalZero         return 0;
180*042d53a7SEvalZero     }
181*042d53a7SEvalZero 
182*042d53a7SEvalZero     argv[argc++] = str;
183*042d53a7SEvalZero 
184*042d53a7SEvalZero     while ((str = strchr(str, ' ')))
185*042d53a7SEvalZero     {
186*042d53a7SEvalZero         *str++ = '\0';
187*042d53a7SEvalZero 
188*042d53a7SEvalZero         while (*str && *str == ' ')
189*042d53a7SEvalZero         {
190*042d53a7SEvalZero             str++;
191*042d53a7SEvalZero         }
192*042d53a7SEvalZero 
193*042d53a7SEvalZero         if (!*str)
194*042d53a7SEvalZero         {
195*042d53a7SEvalZero             break;
196*042d53a7SEvalZero         }
197*042d53a7SEvalZero 
198*042d53a7SEvalZero         argv[argc++] = str;
199*042d53a7SEvalZero 
200*042d53a7SEvalZero         if (argc == size)
201*042d53a7SEvalZero         {
202*042d53a7SEvalZero             console_printf("Too many parameters (max %zu)\n", size - 1);
203*042d53a7SEvalZero             return 0;
204*042d53a7SEvalZero         }
205*042d53a7SEvalZero     }
206*042d53a7SEvalZero 
207*042d53a7SEvalZero     /* keep it POSIX style where argv[argc] is required to be NULL */
208*042d53a7SEvalZero     argv[argc] = NULL;
209*042d53a7SEvalZero 
210*042d53a7SEvalZero     return argc;
211*042d53a7SEvalZero }
212*042d53a7SEvalZero 
get_cb(int argc,char * argv[])213*042d53a7SEvalZero static shell_cmd_func_t get_cb(int argc, char *argv[])
214*042d53a7SEvalZero {
215*042d53a7SEvalZero     const char *first_string = argv[0];
216*042d53a7SEvalZero     int module = -1;
217*042d53a7SEvalZero     const struct shell_module *shell_module;
218*042d53a7SEvalZero     const char *command;
219*042d53a7SEvalZero     int i;
220*042d53a7SEvalZero 
221*042d53a7SEvalZero     if (!first_string || first_string[0] == '\0')
222*042d53a7SEvalZero     {
223*042d53a7SEvalZero         console_printf("Illegal parameter\n");
224*042d53a7SEvalZero         return NULL;
225*042d53a7SEvalZero     }
226*042d53a7SEvalZero 
227*042d53a7SEvalZero     if (!strcmp(first_string, "help"))
228*042d53a7SEvalZero     {
229*042d53a7SEvalZero         return show_help;
230*042d53a7SEvalZero     }
231*042d53a7SEvalZero 
232*042d53a7SEvalZero     if (!strcmp(first_string, "select"))
233*042d53a7SEvalZero     {
234*042d53a7SEvalZero         return select_module;
235*042d53a7SEvalZero     }
236*042d53a7SEvalZero 
237*042d53a7SEvalZero     if ((argc == 1) && (default_module == -1))
238*042d53a7SEvalZero     {
239*042d53a7SEvalZero         console_printf("Missing parameter\n");
240*042d53a7SEvalZero         return NULL;
241*042d53a7SEvalZero     }
242*042d53a7SEvalZero 
243*042d53a7SEvalZero     command = get_command_and_module(argv, &module);
244*042d53a7SEvalZero     if ((module == -1) || (command == NULL))
245*042d53a7SEvalZero     {
246*042d53a7SEvalZero         return NULL;
247*042d53a7SEvalZero     }
248*042d53a7SEvalZero 
249*042d53a7SEvalZero     shell_module = &shell_modules[module];
250*042d53a7SEvalZero     for (i = 0; shell_module->commands[i].sc_cmd; i++)
251*042d53a7SEvalZero     {
252*042d53a7SEvalZero         if (!strcmp(command, shell_module->commands[i].sc_cmd))
253*042d53a7SEvalZero         {
254*042d53a7SEvalZero             return shell_module->commands[i].sc_cmd_func;
255*042d53a7SEvalZero         }
256*042d53a7SEvalZero     }
257*042d53a7SEvalZero 
258*042d53a7SEvalZero     return NULL;
259*042d53a7SEvalZero }
260*042d53a7SEvalZero 
261*042d53a7SEvalZero 
get_prompt(void)262*042d53a7SEvalZero static const char *get_prompt(void)
263*042d53a7SEvalZero {
264*042d53a7SEvalZero     const char *str;
265*042d53a7SEvalZero 
266*042d53a7SEvalZero     if (app_prompt_handler)
267*042d53a7SEvalZero     {
268*042d53a7SEvalZero 
269*042d53a7SEvalZero         str = app_prompt_handler();
270*042d53a7SEvalZero         if (str)
271*042d53a7SEvalZero         {
272*042d53a7SEvalZero             return str;
273*042d53a7SEvalZero         }
274*042d53a7SEvalZero     }
275*042d53a7SEvalZero 
276*042d53a7SEvalZero     if (default_module != -1)
277*042d53a7SEvalZero     {
278*042d53a7SEvalZero         return shell_modules[default_module].name;
279*042d53a7SEvalZero     }
280*042d53a7SEvalZero 
281*042d53a7SEvalZero     return prompt;
282*042d53a7SEvalZero }
283*042d53a7SEvalZero 
print_prompt(void)284*042d53a7SEvalZero static void print_prompt(void)
285*042d53a7SEvalZero {
286*042d53a7SEvalZero     console_printf("%s%s", get_prompt(), SHELL_PROMPT_SUFFIX);
287*042d53a7SEvalZero }
288*042d53a7SEvalZero 
get_destination_module(const char * module_str,int len)289*042d53a7SEvalZero static int get_destination_module(const char *module_str, int len)
290*042d53a7SEvalZero {
291*042d53a7SEvalZero     int i;
292*042d53a7SEvalZero 
293*042d53a7SEvalZero     for (i = 0; i < num_of_shell_entities; i++)
294*042d53a7SEvalZero     {
295*042d53a7SEvalZero         if (len < 0)
296*042d53a7SEvalZero         {
297*042d53a7SEvalZero             if (!strcmp(module_str, shell_modules[i].name))
298*042d53a7SEvalZero             {
299*042d53a7SEvalZero                 return i;
300*042d53a7SEvalZero             }
301*042d53a7SEvalZero         }
302*042d53a7SEvalZero         else
303*042d53a7SEvalZero         {
304*042d53a7SEvalZero             if (!strncmp(module_str, shell_modules[i].name, len))
305*042d53a7SEvalZero             {
306*042d53a7SEvalZero                 return i;
307*042d53a7SEvalZero             }
308*042d53a7SEvalZero         }
309*042d53a7SEvalZero     }
310*042d53a7SEvalZero 
311*042d53a7SEvalZero     return -1;
312*042d53a7SEvalZero }
313*042d53a7SEvalZero 
314*042d53a7SEvalZero /* For a specific command: argv[0] = module name, argv[1] = command name
315*042d53a7SEvalZero  * If a default module was selected: argv[0] = command name
316*042d53a7SEvalZero  */
get_command_and_module(char * argv[],int * module)317*042d53a7SEvalZero static const char *get_command_and_module(char *argv[], int *module)
318*042d53a7SEvalZero {
319*042d53a7SEvalZero     *module = -1;
320*042d53a7SEvalZero 
321*042d53a7SEvalZero     if (!argv[0])
322*042d53a7SEvalZero     {
323*042d53a7SEvalZero         console_printf("Unrecognized command\n");
324*042d53a7SEvalZero         return NULL;
325*042d53a7SEvalZero     }
326*042d53a7SEvalZero 
327*042d53a7SEvalZero     if (default_module == -1)
328*042d53a7SEvalZero     {
329*042d53a7SEvalZero         if (!argv[1] || argv[1][0] == '\0')
330*042d53a7SEvalZero         {
331*042d53a7SEvalZero             console_printf("Unrecognized command: %s\n", argv[0]);
332*042d53a7SEvalZero             return NULL;
333*042d53a7SEvalZero         }
334*042d53a7SEvalZero 
335*042d53a7SEvalZero         *module = get_destination_module(argv[0], -1);
336*042d53a7SEvalZero         if (*module == -1)
337*042d53a7SEvalZero         {
338*042d53a7SEvalZero             console_printf("Illegal module %s\n", argv[0]);
339*042d53a7SEvalZero             return NULL;
340*042d53a7SEvalZero         }
341*042d53a7SEvalZero 
342*042d53a7SEvalZero         return argv[1];
343*042d53a7SEvalZero     }
344*042d53a7SEvalZero 
345*042d53a7SEvalZero     *module = default_module;
346*042d53a7SEvalZero     return argv[0];
347*042d53a7SEvalZero }
348*042d53a7SEvalZero 
print_command_params(const int module,const int command)349*042d53a7SEvalZero static void print_command_params(const int module, const int command)
350*042d53a7SEvalZero {
351*042d53a7SEvalZero     const struct shell_module *shell_module = &shell_modules[module];
352*042d53a7SEvalZero     const struct shell_cmd *shell_cmd = &shell_module->commands[command];
353*042d53a7SEvalZero     int i;
354*042d53a7SEvalZero 
355*042d53a7SEvalZero     if (!(shell_cmd->help && shell_cmd->help->params))
356*042d53a7SEvalZero     {
357*042d53a7SEvalZero         return;
358*042d53a7SEvalZero     }
359*042d53a7SEvalZero 
360*042d53a7SEvalZero     for (i = 0; shell_cmd->help->params[i].param_name; i++)
361*042d53a7SEvalZero     {
362*042d53a7SEvalZero         console_printf("%-30s%s\n", shell_cmd->help->params[i].param_name,
363*042d53a7SEvalZero                        shell_cmd->help->params[i].help);
364*042d53a7SEvalZero     }
365*042d53a7SEvalZero }
366*042d53a7SEvalZero 
show_cmd_help(char * argv[])367*042d53a7SEvalZero static int show_cmd_help(char *argv[])
368*042d53a7SEvalZero {
369*042d53a7SEvalZero     const char *command = NULL;
370*042d53a7SEvalZero     int module = -1;
371*042d53a7SEvalZero     const struct shell_module *shell_module = NULL;
372*042d53a7SEvalZero     const struct shell_cmd *cmd;
373*042d53a7SEvalZero     int i;
374*042d53a7SEvalZero 
375*042d53a7SEvalZero     command = get_command_and_module(argv, &module);
376*042d53a7SEvalZero     if ((module == -1) || (command == NULL))
377*042d53a7SEvalZero     {
378*042d53a7SEvalZero         return 0;
379*042d53a7SEvalZero     }
380*042d53a7SEvalZero 
381*042d53a7SEvalZero     shell_module = &shell_modules[module];
382*042d53a7SEvalZero     for (i = 0; shell_module->commands[i].sc_cmd; i++)
383*042d53a7SEvalZero     {
384*042d53a7SEvalZero         cmd = &shell_module->commands[i];
385*042d53a7SEvalZero 
386*042d53a7SEvalZero         if (!strcmp(command, cmd->sc_cmd))
387*042d53a7SEvalZero         {
388*042d53a7SEvalZero 
389*042d53a7SEvalZero             if (!cmd->help || (!cmd->help->summary &&
390*042d53a7SEvalZero                                !cmd->help->usage &&
391*042d53a7SEvalZero                                !cmd->help->params))
392*042d53a7SEvalZero             {
393*042d53a7SEvalZero                 console_printf("(no help available)\n");
394*042d53a7SEvalZero                 return 0;
395*042d53a7SEvalZero             }
396*042d53a7SEvalZero 
397*042d53a7SEvalZero             if (cmd->help->summary)
398*042d53a7SEvalZero             {
399*042d53a7SEvalZero                 console_printf("Summary:\n");
400*042d53a7SEvalZero                 console_printf("%s\n", cmd->help->summary);
401*042d53a7SEvalZero             }
402*042d53a7SEvalZero 
403*042d53a7SEvalZero             if (cmd->help->usage)
404*042d53a7SEvalZero             {
405*042d53a7SEvalZero                 console_printf("Usage:\n");
406*042d53a7SEvalZero                 console_printf("%s\n", cmd->help->usage);
407*042d53a7SEvalZero             }
408*042d53a7SEvalZero 
409*042d53a7SEvalZero             if (cmd->help->params)
410*042d53a7SEvalZero             {
411*042d53a7SEvalZero                 console_printf("Parameters:\n");
412*042d53a7SEvalZero                 print_command_params(module, i);
413*042d53a7SEvalZero             }
414*042d53a7SEvalZero 
415*042d53a7SEvalZero             return 0;
416*042d53a7SEvalZero         }
417*042d53a7SEvalZero     }
418*042d53a7SEvalZero 
419*042d53a7SEvalZero     console_printf("Unrecognized command: %s\n", argv[0]);
420*042d53a7SEvalZero     return 0;
421*042d53a7SEvalZero }
422*042d53a7SEvalZero 
shell_process_command(char * line)423*042d53a7SEvalZero void shell_process_command(char *line)
424*042d53a7SEvalZero {
425*042d53a7SEvalZero     char *argv[FINSH_CMD_SIZE + 1];
426*042d53a7SEvalZero     shell_cmd_func_t sc_cmd_func;
427*042d53a7SEvalZero     size_t argc_offset = 0;
428*042d53a7SEvalZero     size_t argc;
429*042d53a7SEvalZero 
430*042d53a7SEvalZero     argc = line2argv(line, argv, FINSH_CMD_SIZE + 1);
431*042d53a7SEvalZero     if (!argc)
432*042d53a7SEvalZero     {
433*042d53a7SEvalZero         print_prompt();
434*042d53a7SEvalZero         return;
435*042d53a7SEvalZero     }
436*042d53a7SEvalZero 
437*042d53a7SEvalZero     sc_cmd_func = get_cb(argc, argv);
438*042d53a7SEvalZero     if (!sc_cmd_func)
439*042d53a7SEvalZero     {
440*042d53a7SEvalZero         if (app_cmd_handler != NULL)
441*042d53a7SEvalZero         {
442*042d53a7SEvalZero             sc_cmd_func = app_cmd_handler;
443*042d53a7SEvalZero         }
444*042d53a7SEvalZero         else
445*042d53a7SEvalZero         {
446*042d53a7SEvalZero             console_printf("Unrecognized command: %s\n", argv[0]);
447*042d53a7SEvalZero             console_printf("Type 'help' for list of available commands\n");
448*042d53a7SEvalZero             print_prompt();
449*042d53a7SEvalZero             return;
450*042d53a7SEvalZero         }
451*042d53a7SEvalZero     }
452*042d53a7SEvalZero 
453*042d53a7SEvalZero     /* Allow invoking a cmd with module name as a prefix; a command should
454*042d53a7SEvalZero      * not know how it was invoked (with or without prefix)
455*042d53a7SEvalZero      */
456*042d53a7SEvalZero     if (default_module == -1 && sc_cmd_func != select_module &&
457*042d53a7SEvalZero             sc_cmd_func != show_help)
458*042d53a7SEvalZero     {
459*042d53a7SEvalZero         argc_offset = 1;
460*042d53a7SEvalZero     }
461*042d53a7SEvalZero 
462*042d53a7SEvalZero     /* Execute callback with arguments */
463*042d53a7SEvalZero     if (sc_cmd_func(argc - argc_offset, &argv[argc_offset]) < 0)
464*042d53a7SEvalZero     {
465*042d53a7SEvalZero         show_cmd_help(argv);
466*042d53a7SEvalZero     }
467*042d53a7SEvalZero 
468*042d53a7SEvalZero     print_prompt();
469*042d53a7SEvalZero }
470