Ken Yourek / ucmd

Dependents:   nucleo_ucmd_helloworld

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ucCmdLineApp.c Source File

ucCmdLineApp.c

00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <string.h>
00004 #include "ucmd_internal.h"
00005 
00006 typedef struct HelpState {
00007     ucCmdLineApp *app;
00008     ucCmdLineOpt *cmd_opt;
00009 } HelpState;
00010 
00011 typedef struct QuitState {
00012     ucCmdLineApp *app;
00013 } QuitState;
00014 
00015 static const char *quit(ucCmdLine *cmd, void *state) {
00016     QuitState *s = (QuitState*)state;
00017     return ucCmdLineApp_get_escape_response(s->app);
00018 }
00019 
00020 static const char *help(ucCmdLine *cmd, void *state) {
00021     HelpState *s;
00022     ucArgTok *arg_tok;
00023     ucCmdLineOpt *cmd_opt;
00024 
00025     s = (HelpState*)state;
00026     cmd_opt = s->cmd_opt;
00027 
00028     arg_tok = ucCmdTok_get_arg(ucCmdLine_get_cmd_tok(cmd));
00029     if (NULL != arg_tok) {
00030         cmd_opt = ucCmdLineOpt_find_by_name(cmd_opt, ucTok_get_value(arg_tok));
00031         if (NULL != cmd_opt) {
00032             ucCmdLineOpt_send_help(cmd_opt, cmd);
00033             return 0;
00034         }
00035         ucCmdLine_respond(cmd, ucCmdLine_format_response(cmd, "Invalid command: no option found for \"%s\".", ucTok_get_value(arg_tok)));
00036         return 0;
00037     }
00038 
00039     ucCmdLine_respond(cmd, "Commands");
00040     while (NULL != cmd_opt) {
00041         ucOpt_send_help((ucOpt*)cmd_opt, cmd, "\t");
00042         cmd_opt = ucCmdLineOpt_get_next(cmd_opt);
00043     }
00044     ucCmdLine_respond(cmd, ucCmdLine_format_response(cmd, "Type \"%s\" followed by a command name for additional help with that command.", ucCmdLineApp_get_help_command(s->app)));
00045 
00046     return 0;
00047 }
00048 
00049 static ucErr run(ucCmdLineApp *p, ucCmdLineOpt *cmd_opt) {
00050     char *command;
00051     const char *response;
00052     ucCmdTok *cmd_tok;
00053     ucCmdLine *cmd;
00054     ucCmdLineOpt *quit_opt, *main_opt;
00055     HelpState HelpState_s;
00056     QuitState QuitState_s;
00057 
00058     if (NULL == p) return -1;
00059 
00060     /* Create options for help and quit. */
00061     quit_opt = ucCmdLineOpt_create(quit, &QuitState_s, ucCmdLineApp_get_quit_command(p), "Exits the command interface.", NULL, NULL, cmd_opt);
00062     main_opt = ucCmdLineOpt_create(help, &HelpState_s, ucCmdLineApp_get_help_command(p), "Shows command information.", ucArgOpt_create("<command>", "If provided, help is shown for the given command.", NULL), NULL, quit_opt);
00063 
00064     /* Set the state used for the help and quit commands. */
00065     QuitState_s.app = p;
00066     HelpState_s.app = p;
00067     HelpState_s.cmd_opt = main_opt;
00068 
00069     /* Get this app's command object. */
00070     cmd = ucCmdLineApp_get_cmd(p);
00071 
00072     /* Show the banner. */
00073     ucCmdLine_respond(cmd, ucCmdLine_format_response(cmd, "Type %s to quit.", ucCmdLineApp_get_quit_command(p)));
00074     ucCmdLine_respond(cmd, ucCmdLine_format_response(cmd, "Type %s for help.", ucCmdLineApp_get_help_command(p)));
00075 
00076     /* Loop until quit. */
00077     for (;;) {
00078                 
00079         /* Read the command. */
00080         command = ucCmdLineApp_receive(p);
00081 
00082         /* Parse the input into a command token. */
00083         cmd_tok = ucCmdParser_parse(ucCmdLineApp_get_cmd_parser(p), command);
00084 
00085         /* Set the command's parsed command token. */
00086         ucCmdLine_set_cmd_tok(cmd, cmd_tok);
00087 
00088         /* Process the command. */
00089         response = ucCmdLineOpt_process(main_opt, cmd);
00090 
00091         /* Check if we got a response. */
00092         if (response) {
00093 
00094             /* Check if the response is the escape response. */
00095             if (0 == strcmp(response, ucCmdLineApp_get_escape_response(p))) {
00096 
00097                 /* We've been signaled to quit the app. */
00098                 break;
00099             }
00100         }
00101     }
00102 
00103     /* Clear the options we created. */
00104     ucCmdLineOpt_destroy(quit_opt);
00105     ucCmdLineOpt_destroy(main_opt);
00106 
00107     /* If we got here, then the app was quit. */
00108     return ucErr_NONE;
00109 }
00110 
00111 void ucCmdLineApp_set_escape_response(ucCmdLineApp *p, const char *value) {
00112     if (NULL == p) return;
00113     p->escape_response = value;
00114 }
00115 
00116 const char *ucCmdLineApp_get_escape_response(ucCmdLineApp *p) {
00117     if (NULL == p) return NULL;
00118     return p->escape_response;
00119 }
00120 
00121 void ucCmdLineApp_set_receive(ucCmdLineApp *p, ucCmdLineApp_ReceiveFunc *value) {
00122     if (NULL == p) return;
00123     p->receive = value;
00124 }
00125 
00126 ucCmdLineApp_ReceiveFunc *ucCmdLineApp_get_receive(ucCmdLineApp *p) {
00127     if (NULL == p) return NULL;
00128     return p->receive;
00129 }
00130 
00131 void *ucCmdLineApp_get_receive_state(ucCmdLineApp *p) {
00132     if (NULL == p) return NULL;
00133     return p->receive_state;
00134 }
00135 
00136 void ucCmdLineApp_set_receive_state(ucCmdLineApp *p, void *value) {
00137     if (NULL == p) return;
00138     p->receive_state = value;
00139 }
00140 
00141 void ucCmdLineApp_set_quit_command(ucCmdLineApp *p, const char *value) {
00142     if (NULL == p) return;
00143     p->quit_command = value;
00144 }
00145 
00146 const char *ucCmdLineApp_get_quit_command(ucCmdLineApp *p) {
00147     if (NULL == p) return NULL;
00148     return p->quit_command;
00149 }
00150 
00151 void ucCmdLineApp_set_help_command(ucCmdLineApp *p, const char *value) {
00152     if (NULL == p) return;
00153     p->help_command = value;
00154 }
00155 
00156 const char *ucCmdLineApp_get_help_command(ucCmdLineApp *p) {
00157     if (NULL == p) return NULL;
00158     return p->help_command;
00159 }
00160 
00161 void ucCmdLineApp_set_cmd(ucCmdLineApp *p, ucCmdLine *value) {
00162     if (NULL == p) return;
00163     p->cmd = value;
00164 }
00165 
00166 ucCmdLine *ucCmdLineApp_get_cmd(ucCmdLineApp *p) {
00167     if (NULL == p) return NULL;
00168     return p->cmd;
00169 }
00170 
00171 ucCmdParser *ucCmdLineApp_get_cmd_parser(ucCmdLineApp *p) {
00172     if (NULL == p) return NULL;
00173     return p->cmd_parser;
00174 }
00175 
00176 ucCmdLineApp *ucCmdLineApp_init(ucCmdLineApp *p, ucCmdParser *cmd_parser, ucCmdLine *cmd) {
00177     if (NULL == p) return NULL;
00178     p->cmd = cmd;
00179     p->cmd_parser = cmd_parser;
00180     p->run = run;
00181     p->receive = NULL;
00182     p->receive_state = NULL;
00183     p->help_command = "help";
00184     p->quit_command = "quit";
00185     p->escape_response = "\x1b";
00186     return p;
00187 }
00188 
00189 ucCmdLineApp *ucCmdLineApp_get_instance(void) {
00190     static ucCmdLineApp instance = { 0 };
00191     static ucCmdLineApp *pointer = NULL;
00192     if (pointer == NULL) {
00193         pointer = ucCmdLineApp_init(&instance, ucCmdParser_get_instance(), ucCmdLine_get_instance());
00194     }
00195     return pointer;
00196 }
00197 
00198 ucErr ucCmdLineApp_run(ucCmdLineApp *p, ucCmdLineOpt *cmd_opt) {
00199     if (NULL == p) return -1;
00200     if (NULL == p->run) return -2;
00201     return p->run(p, cmd_opt);
00202 }
00203 
00204 char *ucCmdLineApp_receive(ucCmdLineApp *p) {
00205     if (NULL == p) return NULL;
00206     if (NULL == p->receive) return NULL;
00207     return p->receive(p->cmd_str, sizeof(p->cmd_str), p->receive_state);
00208 }
00209 
00210 size_t ucCmdLineApp_get_cmd_str_size_max(ucCmdLineApp *p) {
00211     if (NULL == p) return 0;
00212     return ucCmdLineApp_CMD_STR_SIZE;
00213 }
00214