Ken Yourek / ucmd

Dependents:   nucleo_ucmd_helloworld

Committer:
kyourek
Date:
Mon Oct 12 21:09:07 2015 +0000
Revision:
0:9e2fc73e5a12
Initial commit of the ucmd library for mbed.; https://github.com/kyourek/ucmd

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kyourek 0:9e2fc73e5a12 1 #include <stdio.h>
kyourek 0:9e2fc73e5a12 2 #include <stdlib.h>
kyourek 0:9e2fc73e5a12 3 #include <string.h>
kyourek 0:9e2fc73e5a12 4 #include "ucmd_internal.h"
kyourek 0:9e2fc73e5a12 5
kyourek 0:9e2fc73e5a12 6 typedef struct HelpState {
kyourek 0:9e2fc73e5a12 7 ucCmdLineApp *app;
kyourek 0:9e2fc73e5a12 8 ucCmdLineOpt *cmd_opt;
kyourek 0:9e2fc73e5a12 9 } HelpState;
kyourek 0:9e2fc73e5a12 10
kyourek 0:9e2fc73e5a12 11 typedef struct QuitState {
kyourek 0:9e2fc73e5a12 12 ucCmdLineApp *app;
kyourek 0:9e2fc73e5a12 13 } QuitState;
kyourek 0:9e2fc73e5a12 14
kyourek 0:9e2fc73e5a12 15 static const char *quit(ucCmdLine *cmd, void *state) {
kyourek 0:9e2fc73e5a12 16 QuitState *s = (QuitState*)state;
kyourek 0:9e2fc73e5a12 17 return ucCmdLineApp_get_escape_response(s->app);
kyourek 0:9e2fc73e5a12 18 }
kyourek 0:9e2fc73e5a12 19
kyourek 0:9e2fc73e5a12 20 static const char *help(ucCmdLine *cmd, void *state) {
kyourek 0:9e2fc73e5a12 21 HelpState *s;
kyourek 0:9e2fc73e5a12 22 ucArgTok *arg_tok;
kyourek 0:9e2fc73e5a12 23 ucCmdLineOpt *cmd_opt;
kyourek 0:9e2fc73e5a12 24
kyourek 0:9e2fc73e5a12 25 s = (HelpState*)state;
kyourek 0:9e2fc73e5a12 26 cmd_opt = s->cmd_opt;
kyourek 0:9e2fc73e5a12 27
kyourek 0:9e2fc73e5a12 28 arg_tok = ucCmdTok_get_arg(ucCmdLine_get_cmd_tok(cmd));
kyourek 0:9e2fc73e5a12 29 if (NULL != arg_tok) {
kyourek 0:9e2fc73e5a12 30 cmd_opt = ucCmdLineOpt_find_by_name(cmd_opt, ucTok_get_value(arg_tok));
kyourek 0:9e2fc73e5a12 31 if (NULL != cmd_opt) {
kyourek 0:9e2fc73e5a12 32 ucCmdLineOpt_send_help(cmd_opt, cmd);
kyourek 0:9e2fc73e5a12 33 return 0;
kyourek 0:9e2fc73e5a12 34 }
kyourek 0:9e2fc73e5a12 35 ucCmdLine_respond(cmd, ucCmdLine_format_response(cmd, "Invalid command: no option found for \"%s\".", ucTok_get_value(arg_tok)));
kyourek 0:9e2fc73e5a12 36 return 0;
kyourek 0:9e2fc73e5a12 37 }
kyourek 0:9e2fc73e5a12 38
kyourek 0:9e2fc73e5a12 39 ucCmdLine_respond(cmd, "Commands");
kyourek 0:9e2fc73e5a12 40 while (NULL != cmd_opt) {
kyourek 0:9e2fc73e5a12 41 ucOpt_send_help((ucOpt*)cmd_opt, cmd, "\t");
kyourek 0:9e2fc73e5a12 42 cmd_opt = ucCmdLineOpt_get_next(cmd_opt);
kyourek 0:9e2fc73e5a12 43 }
kyourek 0:9e2fc73e5a12 44 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)));
kyourek 0:9e2fc73e5a12 45
kyourek 0:9e2fc73e5a12 46 return 0;
kyourek 0:9e2fc73e5a12 47 }
kyourek 0:9e2fc73e5a12 48
kyourek 0:9e2fc73e5a12 49 static ucErr run(ucCmdLineApp *p, ucCmdLineOpt *cmd_opt) {
kyourek 0:9e2fc73e5a12 50 char *command;
kyourek 0:9e2fc73e5a12 51 const char *response;
kyourek 0:9e2fc73e5a12 52 ucCmdTok *cmd_tok;
kyourek 0:9e2fc73e5a12 53 ucCmdLine *cmd;
kyourek 0:9e2fc73e5a12 54 ucCmdLineOpt *quit_opt, *main_opt;
kyourek 0:9e2fc73e5a12 55 HelpState HelpState_s;
kyourek 0:9e2fc73e5a12 56 QuitState QuitState_s;
kyourek 0:9e2fc73e5a12 57
kyourek 0:9e2fc73e5a12 58 if (NULL == p) return -1;
kyourek 0:9e2fc73e5a12 59
kyourek 0:9e2fc73e5a12 60 /* Create options for help and quit. */
kyourek 0:9e2fc73e5a12 61 quit_opt = ucCmdLineOpt_create(quit, &QuitState_s, ucCmdLineApp_get_quit_command(p), "Exits the command interface.", NULL, NULL, cmd_opt);
kyourek 0:9e2fc73e5a12 62 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);
kyourek 0:9e2fc73e5a12 63
kyourek 0:9e2fc73e5a12 64 /* Set the state used for the help and quit commands. */
kyourek 0:9e2fc73e5a12 65 QuitState_s.app = p;
kyourek 0:9e2fc73e5a12 66 HelpState_s.app = p;
kyourek 0:9e2fc73e5a12 67 HelpState_s.cmd_opt = main_opt;
kyourek 0:9e2fc73e5a12 68
kyourek 0:9e2fc73e5a12 69 /* Get this app's command object. */
kyourek 0:9e2fc73e5a12 70 cmd = ucCmdLineApp_get_cmd(p);
kyourek 0:9e2fc73e5a12 71
kyourek 0:9e2fc73e5a12 72 /* Show the banner. */
kyourek 0:9e2fc73e5a12 73 ucCmdLine_respond(cmd, ucCmdLine_format_response(cmd, "Type %s to quit.", ucCmdLineApp_get_quit_command(p)));
kyourek 0:9e2fc73e5a12 74 ucCmdLine_respond(cmd, ucCmdLine_format_response(cmd, "Type %s for help.", ucCmdLineApp_get_help_command(p)));
kyourek 0:9e2fc73e5a12 75
kyourek 0:9e2fc73e5a12 76 /* Loop until quit. */
kyourek 0:9e2fc73e5a12 77 for (;;) {
kyourek 0:9e2fc73e5a12 78
kyourek 0:9e2fc73e5a12 79 /* Read the command. */
kyourek 0:9e2fc73e5a12 80 command = ucCmdLineApp_receive(p);
kyourek 0:9e2fc73e5a12 81
kyourek 0:9e2fc73e5a12 82 /* Parse the input into a command token. */
kyourek 0:9e2fc73e5a12 83 cmd_tok = ucCmdParser_parse(ucCmdLineApp_get_cmd_parser(p), command);
kyourek 0:9e2fc73e5a12 84
kyourek 0:9e2fc73e5a12 85 /* Set the command's parsed command token. */
kyourek 0:9e2fc73e5a12 86 ucCmdLine_set_cmd_tok(cmd, cmd_tok);
kyourek 0:9e2fc73e5a12 87
kyourek 0:9e2fc73e5a12 88 /* Process the command. */
kyourek 0:9e2fc73e5a12 89 response = ucCmdLineOpt_process(main_opt, cmd);
kyourek 0:9e2fc73e5a12 90
kyourek 0:9e2fc73e5a12 91 /* Check if we got a response. */
kyourek 0:9e2fc73e5a12 92 if (response) {
kyourek 0:9e2fc73e5a12 93
kyourek 0:9e2fc73e5a12 94 /* Check if the response is the escape response. */
kyourek 0:9e2fc73e5a12 95 if (0 == strcmp(response, ucCmdLineApp_get_escape_response(p))) {
kyourek 0:9e2fc73e5a12 96
kyourek 0:9e2fc73e5a12 97 /* We've been signaled to quit the app. */
kyourek 0:9e2fc73e5a12 98 break;
kyourek 0:9e2fc73e5a12 99 }
kyourek 0:9e2fc73e5a12 100 }
kyourek 0:9e2fc73e5a12 101 }
kyourek 0:9e2fc73e5a12 102
kyourek 0:9e2fc73e5a12 103 /* Clear the options we created. */
kyourek 0:9e2fc73e5a12 104 ucCmdLineOpt_destroy(quit_opt);
kyourek 0:9e2fc73e5a12 105 ucCmdLineOpt_destroy(main_opt);
kyourek 0:9e2fc73e5a12 106
kyourek 0:9e2fc73e5a12 107 /* If we got here, then the app was quit. */
kyourek 0:9e2fc73e5a12 108 return ucErr_NONE;
kyourek 0:9e2fc73e5a12 109 }
kyourek 0:9e2fc73e5a12 110
kyourek 0:9e2fc73e5a12 111 void ucCmdLineApp_set_escape_response(ucCmdLineApp *p, const char *value) {
kyourek 0:9e2fc73e5a12 112 if (NULL == p) return;
kyourek 0:9e2fc73e5a12 113 p->escape_response = value;
kyourek 0:9e2fc73e5a12 114 }
kyourek 0:9e2fc73e5a12 115
kyourek 0:9e2fc73e5a12 116 const char *ucCmdLineApp_get_escape_response(ucCmdLineApp *p) {
kyourek 0:9e2fc73e5a12 117 if (NULL == p) return NULL;
kyourek 0:9e2fc73e5a12 118 return p->escape_response;
kyourek 0:9e2fc73e5a12 119 }
kyourek 0:9e2fc73e5a12 120
kyourek 0:9e2fc73e5a12 121 void ucCmdLineApp_set_receive(ucCmdLineApp *p, ucCmdLineApp_ReceiveFunc *value) {
kyourek 0:9e2fc73e5a12 122 if (NULL == p) return;
kyourek 0:9e2fc73e5a12 123 p->receive = value;
kyourek 0:9e2fc73e5a12 124 }
kyourek 0:9e2fc73e5a12 125
kyourek 0:9e2fc73e5a12 126 ucCmdLineApp_ReceiveFunc *ucCmdLineApp_get_receive(ucCmdLineApp *p) {
kyourek 0:9e2fc73e5a12 127 if (NULL == p) return NULL;
kyourek 0:9e2fc73e5a12 128 return p->receive;
kyourek 0:9e2fc73e5a12 129 }
kyourek 0:9e2fc73e5a12 130
kyourek 0:9e2fc73e5a12 131 void *ucCmdLineApp_get_receive_state(ucCmdLineApp *p) {
kyourek 0:9e2fc73e5a12 132 if (NULL == p) return NULL;
kyourek 0:9e2fc73e5a12 133 return p->receive_state;
kyourek 0:9e2fc73e5a12 134 }
kyourek 0:9e2fc73e5a12 135
kyourek 0:9e2fc73e5a12 136 void ucCmdLineApp_set_receive_state(ucCmdLineApp *p, void *value) {
kyourek 0:9e2fc73e5a12 137 if (NULL == p) return;
kyourek 0:9e2fc73e5a12 138 p->receive_state = value;
kyourek 0:9e2fc73e5a12 139 }
kyourek 0:9e2fc73e5a12 140
kyourek 0:9e2fc73e5a12 141 void ucCmdLineApp_set_quit_command(ucCmdLineApp *p, const char *value) {
kyourek 0:9e2fc73e5a12 142 if (NULL == p) return;
kyourek 0:9e2fc73e5a12 143 p->quit_command = value;
kyourek 0:9e2fc73e5a12 144 }
kyourek 0:9e2fc73e5a12 145
kyourek 0:9e2fc73e5a12 146 const char *ucCmdLineApp_get_quit_command(ucCmdLineApp *p) {
kyourek 0:9e2fc73e5a12 147 if (NULL == p) return NULL;
kyourek 0:9e2fc73e5a12 148 return p->quit_command;
kyourek 0:9e2fc73e5a12 149 }
kyourek 0:9e2fc73e5a12 150
kyourek 0:9e2fc73e5a12 151 void ucCmdLineApp_set_help_command(ucCmdLineApp *p, const char *value) {
kyourek 0:9e2fc73e5a12 152 if (NULL == p) return;
kyourek 0:9e2fc73e5a12 153 p->help_command = value;
kyourek 0:9e2fc73e5a12 154 }
kyourek 0:9e2fc73e5a12 155
kyourek 0:9e2fc73e5a12 156 const char *ucCmdLineApp_get_help_command(ucCmdLineApp *p) {
kyourek 0:9e2fc73e5a12 157 if (NULL == p) return NULL;
kyourek 0:9e2fc73e5a12 158 return p->help_command;
kyourek 0:9e2fc73e5a12 159 }
kyourek 0:9e2fc73e5a12 160
kyourek 0:9e2fc73e5a12 161 void ucCmdLineApp_set_cmd(ucCmdLineApp *p, ucCmdLine *value) {
kyourek 0:9e2fc73e5a12 162 if (NULL == p) return;
kyourek 0:9e2fc73e5a12 163 p->cmd = value;
kyourek 0:9e2fc73e5a12 164 }
kyourek 0:9e2fc73e5a12 165
kyourek 0:9e2fc73e5a12 166 ucCmdLine *ucCmdLineApp_get_cmd(ucCmdLineApp *p) {
kyourek 0:9e2fc73e5a12 167 if (NULL == p) return NULL;
kyourek 0:9e2fc73e5a12 168 return p->cmd;
kyourek 0:9e2fc73e5a12 169 }
kyourek 0:9e2fc73e5a12 170
kyourek 0:9e2fc73e5a12 171 ucCmdParser *ucCmdLineApp_get_cmd_parser(ucCmdLineApp *p) {
kyourek 0:9e2fc73e5a12 172 if (NULL == p) return NULL;
kyourek 0:9e2fc73e5a12 173 return p->cmd_parser;
kyourek 0:9e2fc73e5a12 174 }
kyourek 0:9e2fc73e5a12 175
kyourek 0:9e2fc73e5a12 176 ucCmdLineApp *ucCmdLineApp_init(ucCmdLineApp *p, ucCmdParser *cmd_parser, ucCmdLine *cmd) {
kyourek 0:9e2fc73e5a12 177 if (NULL == p) return NULL;
kyourek 0:9e2fc73e5a12 178 p->cmd = cmd;
kyourek 0:9e2fc73e5a12 179 p->cmd_parser = cmd_parser;
kyourek 0:9e2fc73e5a12 180 p->run = run;
kyourek 0:9e2fc73e5a12 181 p->receive = NULL;
kyourek 0:9e2fc73e5a12 182 p->receive_state = NULL;
kyourek 0:9e2fc73e5a12 183 p->help_command = "help";
kyourek 0:9e2fc73e5a12 184 p->quit_command = "quit";
kyourek 0:9e2fc73e5a12 185 p->escape_response = "\x1b";
kyourek 0:9e2fc73e5a12 186 return p;
kyourek 0:9e2fc73e5a12 187 }
kyourek 0:9e2fc73e5a12 188
kyourek 0:9e2fc73e5a12 189 ucCmdLineApp *ucCmdLineApp_get_instance(void) {
kyourek 0:9e2fc73e5a12 190 static ucCmdLineApp instance = { 0 };
kyourek 0:9e2fc73e5a12 191 static ucCmdLineApp *pointer = NULL;
kyourek 0:9e2fc73e5a12 192 if (pointer == NULL) {
kyourek 0:9e2fc73e5a12 193 pointer = ucCmdLineApp_init(&instance, ucCmdParser_get_instance(), ucCmdLine_get_instance());
kyourek 0:9e2fc73e5a12 194 }
kyourek 0:9e2fc73e5a12 195 return pointer;
kyourek 0:9e2fc73e5a12 196 }
kyourek 0:9e2fc73e5a12 197
kyourek 0:9e2fc73e5a12 198 ucErr ucCmdLineApp_run(ucCmdLineApp *p, ucCmdLineOpt *cmd_opt) {
kyourek 0:9e2fc73e5a12 199 if (NULL == p) return -1;
kyourek 0:9e2fc73e5a12 200 if (NULL == p->run) return -2;
kyourek 0:9e2fc73e5a12 201 return p->run(p, cmd_opt);
kyourek 0:9e2fc73e5a12 202 }
kyourek 0:9e2fc73e5a12 203
kyourek 0:9e2fc73e5a12 204 char *ucCmdLineApp_receive(ucCmdLineApp *p) {
kyourek 0:9e2fc73e5a12 205 if (NULL == p) return NULL;
kyourek 0:9e2fc73e5a12 206 if (NULL == p->receive) return NULL;
kyourek 0:9e2fc73e5a12 207 return p->receive(p->cmd_str, sizeof(p->cmd_str), p->receive_state);
kyourek 0:9e2fc73e5a12 208 }
kyourek 0:9e2fc73e5a12 209
kyourek 0:9e2fc73e5a12 210 size_t ucCmdLineApp_get_cmd_str_size_max(ucCmdLineApp *p) {
kyourek 0:9e2fc73e5a12 211 if (NULL == p) return 0;
kyourek 0:9e2fc73e5a12 212 return ucCmdLineApp_CMD_STR_SIZE;
kyourek 0:9e2fc73e5a12 213 }
kyourek 0:9e2fc73e5a12 214