Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: nucleo_ucmd_helloworld
ucCmdLineOpt.c@0:9e2fc73e5a12, 2015-10-12 (annotated)
- 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?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| kyourek | 0:9e2fc73e5a12 | 1 | #include <string.h> |
| kyourek | 0:9e2fc73e5a12 | 2 | #include "ucmd_internal.h" |
| kyourek | 0:9e2fc73e5a12 | 3 | |
| kyourek | 0:9e2fc73e5a12 | 4 | ucMemoryManager_INIT(ucCmdLineOpt, ucCmdLineOpt_COUNT); |
| kyourek | 0:9e2fc73e5a12 | 5 | |
| kyourek | 0:9e2fc73e5a12 | 6 | static ucCmdLineOpt *create_cmd_line_opt(void) { |
| kyourek | 0:9e2fc73e5a12 | 7 | return ucMemoryManager_create(); |
| kyourek | 0:9e2fc73e5a12 | 8 | } |
| kyourek | 0:9e2fc73e5a12 | 9 | |
| kyourek | 0:9e2fc73e5a12 | 10 | static const char *add_opt_to_usage_response(ucOpt *opt, ucCmdLine *cmd, const char *response) { |
| kyourek | 0:9e2fc73e5a12 | 11 | static const char *required_format = "%s %s"; |
| kyourek | 0:9e2fc73e5a12 | 12 | static const char *optional_format = "%s [%s]"; |
| kyourek | 0:9e2fc73e5a12 | 13 | return ucCmdLine_format_response( |
| kyourek | 0:9e2fc73e5a12 | 14 | cmd, |
| kyourek | 0:9e2fc73e5a12 | 15 | ucOpt_is_required(opt) ? required_format : optional_format, |
| kyourek | 0:9e2fc73e5a12 | 16 | response, |
| kyourek | 0:9e2fc73e5a12 | 17 | ucOpt_get_name(opt) |
| kyourek | 0:9e2fc73e5a12 | 18 | ); |
| kyourek | 0:9e2fc73e5a12 | 19 | } |
| kyourek | 0:9e2fc73e5a12 | 20 | |
| kyourek | 0:9e2fc73e5a12 | 21 | static const char *add_arg_opts_to_usage_response(ucArgOpt *arg_opt, ucCmdLine *cmd, const char *response) { |
| kyourek | 0:9e2fc73e5a12 | 22 | |
| kyourek | 0:9e2fc73e5a12 | 23 | while (NULL != arg_opt) { |
| kyourek | 0:9e2fc73e5a12 | 24 | response = add_opt_to_usage_response((ucOpt*)arg_opt, cmd, response); |
| kyourek | 0:9e2fc73e5a12 | 25 | arg_opt = ucArgOpt_get_next(arg_opt); |
| kyourek | 0:9e2fc73e5a12 | 26 | } |
| kyourek | 0:9e2fc73e5a12 | 27 | |
| kyourek | 0:9e2fc73e5a12 | 28 | return response; |
| kyourek | 0:9e2fc73e5a12 | 29 | } |
| kyourek | 0:9e2fc73e5a12 | 30 | |
| kyourek | 0:9e2fc73e5a12 | 31 | static void send_arg_opts_help(ucArgOpt *arg_opt, ucCmdLine *cmd, const char *prefix) { |
| kyourek | 0:9e2fc73e5a12 | 32 | while (NULL != arg_opt) { |
| kyourek | 0:9e2fc73e5a12 | 33 | ucOpt_send_help((ucOpt*)arg_opt, cmd, prefix); |
| kyourek | 0:9e2fc73e5a12 | 34 | arg_opt = ucArgOpt_get_next(arg_opt); |
| kyourek | 0:9e2fc73e5a12 | 35 | } |
| kyourek | 0:9e2fc73e5a12 | 36 | } |
| kyourek | 0:9e2fc73e5a12 | 37 | |
| kyourek | 0:9e2fc73e5a12 | 38 | ucCmdLineOpt *ucCmdLineOpt_get_next(ucCmdLineOpt *p) { |
| kyourek | 0:9e2fc73e5a12 | 39 | if (NULL == p) return NULL; |
| kyourek | 0:9e2fc73e5a12 | 40 | return p->next; |
| kyourek | 0:9e2fc73e5a12 | 41 | } |
| kyourek | 0:9e2fc73e5a12 | 42 | |
| kyourek | 0:9e2fc73e5a12 | 43 | ucArgOpt *ucCmdLineOpt_get_arg_opt(ucCmdLineOpt *p) { |
| kyourek | 0:9e2fc73e5a12 | 44 | if (NULL == p) return NULL; |
| kyourek | 0:9e2fc73e5a12 | 45 | return ucArgOptOwner_get_arg_opt((ucArgOptOwner*)p); |
| kyourek | 0:9e2fc73e5a12 | 46 | } |
| kyourek | 0:9e2fc73e5a12 | 47 | |
| kyourek | 0:9e2fc73e5a12 | 48 | ucSwitchOpt *ucCmdLineOpt_get_switch_opt(ucCmdLineOpt *p) { |
| kyourek | 0:9e2fc73e5a12 | 49 | if (NULL == p) return NULL; |
| kyourek | 0:9e2fc73e5a12 | 50 | return p->switch_opt; |
| kyourek | 0:9e2fc73e5a12 | 51 | } |
| kyourek | 0:9e2fc73e5a12 | 52 | |
| kyourek | 0:9e2fc73e5a12 | 53 | ucCmdLineOpt *ucCmdLineOpt_init(ucCmdLineOpt *p, ucCmdLineOpt_Func *func, void* state, const char *name, const char *desc, ucArgOpt *arg_opt, ucSwitchOpt *switch_opt, ucCmdLineOpt* next) { |
| kyourek | 0:9e2fc73e5a12 | 54 | if (NULL == p) return NULL; |
| kyourek | 0:9e2fc73e5a12 | 55 | if (NULL == ucArgOptOwner_init((ucArgOptOwner*)p, name, desc, ucBool_TRUE, arg_opt)) return NULL; |
| kyourek | 0:9e2fc73e5a12 | 56 | p->func = func; |
| kyourek | 0:9e2fc73e5a12 | 57 | p->state = state; |
| kyourek | 0:9e2fc73e5a12 | 58 | p->switch_opt = switch_opt; |
| kyourek | 0:9e2fc73e5a12 | 59 | p->next = next; |
| kyourek | 0:9e2fc73e5a12 | 60 | return p; |
| kyourek | 0:9e2fc73e5a12 | 61 | } |
| kyourek | 0:9e2fc73e5a12 | 62 | |
| kyourek | 0:9e2fc73e5a12 | 63 | ucCmdLineOpt *ucCmdLineOpt_create(ucCmdLineOpt_Func *func, void *state, const char *name, const char *desc, ucArgOpt* arg_opt, ucSwitchOpt *switch_opt, ucCmdLineOpt *next) { |
| kyourek | 0:9e2fc73e5a12 | 64 | return ucCmdLineOpt_init(create_cmd_line_opt(), func, state, name, desc, arg_opt, switch_opt, next); |
| kyourek | 0:9e2fc73e5a12 | 65 | } |
| kyourek | 0:9e2fc73e5a12 | 66 | |
| kyourek | 0:9e2fc73e5a12 | 67 | ucCmdLineOpt *ucCmdLineOpt_find_by_name(ucCmdLineOpt* p, const char *name) { |
| kyourek | 0:9e2fc73e5a12 | 68 | while (NULL != p) { |
| kyourek | 0:9e2fc73e5a12 | 69 | if (0 == strcmp(name, ucOpt_get_name((ucOpt*)p))) { |
| kyourek | 0:9e2fc73e5a12 | 70 | return p; |
| kyourek | 0:9e2fc73e5a12 | 71 | } |
| kyourek | 0:9e2fc73e5a12 | 72 | p = ucCmdLineOpt_get_next(p); |
| kyourek | 0:9e2fc73e5a12 | 73 | } |
| kyourek | 0:9e2fc73e5a12 | 74 | return NULL; |
| kyourek | 0:9e2fc73e5a12 | 75 | } |
| kyourek | 0:9e2fc73e5a12 | 76 | |
| kyourek | 0:9e2fc73e5a12 | 77 | ucCmdLineOpt_Func *ucCmdLineOpt_get_func(ucCmdLineOpt *p) { |
| kyourek | 0:9e2fc73e5a12 | 78 | if (NULL == p) return NULL; |
| kyourek | 0:9e2fc73e5a12 | 79 | return p->func; |
| kyourek | 0:9e2fc73e5a12 | 80 | } |
| kyourek | 0:9e2fc73e5a12 | 81 | |
| kyourek | 0:9e2fc73e5a12 | 82 | void *ucCmdLineOpt_get_state(ucCmdLineOpt *p) { |
| kyourek | 0:9e2fc73e5a12 | 83 | if (NULL == p) return NULL; |
| kyourek | 0:9e2fc73e5a12 | 84 | return p->state; |
| kyourek | 0:9e2fc73e5a12 | 85 | } |
| kyourek | 0:9e2fc73e5a12 | 86 | |
| kyourek | 0:9e2fc73e5a12 | 87 | void ucCmdLineOpt_send_usage(ucCmdLineOpt *p, ucCmdLine *cmd) { |
| kyourek | 0:9e2fc73e5a12 | 88 | ucSwitchOpt *switch_opt; |
| kyourek | 0:9e2fc73e5a12 | 89 | |
| kyourek | 0:9e2fc73e5a12 | 90 | /* start the usage string with the name of the command */ |
| kyourek | 0:9e2fc73e5a12 | 91 | const char *response = ucCmdLine_format_response(cmd, "%s", ucOpt_get_name((ucOpt*)p)); |
| kyourek | 0:9e2fc73e5a12 | 92 | |
| kyourek | 0:9e2fc73e5a12 | 93 | /* add each available argument option of the command |
| kyourek | 0:9e2fc73e5a12 | 94 | to the usage string */ |
| kyourek | 0:9e2fc73e5a12 | 95 | response = add_arg_opts_to_usage_response(ucCmdLineOpt_get_arg_opt(p), cmd, response); |
| kyourek | 0:9e2fc73e5a12 | 96 | |
| kyourek | 0:9e2fc73e5a12 | 97 | /* loop through each available switch option */ |
| kyourek | 0:9e2fc73e5a12 | 98 | switch_opt = ucCmdLineOpt_get_switch_opt(p); |
| kyourek | 0:9e2fc73e5a12 | 99 | while (NULL != switch_opt) { |
| kyourek | 0:9e2fc73e5a12 | 100 | |
| kyourek | 0:9e2fc73e5a12 | 101 | /* add it to the usage string */ |
| kyourek | 0:9e2fc73e5a12 | 102 | response = add_opt_to_usage_response((ucOpt*)switch_opt, cmd, response); |
| kyourek | 0:9e2fc73e5a12 | 103 | |
| kyourek | 0:9e2fc73e5a12 | 104 | /* also add each of the switch's argument options to the |
| kyourek | 0:9e2fc73e5a12 | 105 | usage string */ |
| kyourek | 0:9e2fc73e5a12 | 106 | response = add_arg_opts_to_usage_response(ucSwitchOpt_get_arg_opt(switch_opt), cmd, response); |
| kyourek | 0:9e2fc73e5a12 | 107 | |
| kyourek | 0:9e2fc73e5a12 | 108 | /* go to the next switch */ |
| kyourek | 0:9e2fc73e5a12 | 109 | switch_opt = ucSwitchOpt_get_next(switch_opt); |
| kyourek | 0:9e2fc73e5a12 | 110 | } |
| kyourek | 0:9e2fc73e5a12 | 111 | |
| kyourek | 0:9e2fc73e5a12 | 112 | /* send the completed usage string */ |
| kyourek | 0:9e2fc73e5a12 | 113 | ucCmdLine_respond(cmd, response); |
| kyourek | 0:9e2fc73e5a12 | 114 | } |
| kyourek | 0:9e2fc73e5a12 | 115 | |
| kyourek | 0:9e2fc73e5a12 | 116 | void ucCmdLineOpt_send_help(ucCmdLineOpt *p, ucCmdLine *cmd) { |
| kyourek | 0:9e2fc73e5a12 | 117 | static const char *single_tab = "\t"; |
| kyourek | 0:9e2fc73e5a12 | 118 | static const char *double_tab = "\t\t"; |
| kyourek | 0:9e2fc73e5a12 | 119 | |
| kyourek | 0:9e2fc73e5a12 | 120 | ucSwitchOpt *switch_opt; |
| kyourek | 0:9e2fc73e5a12 | 121 | |
| kyourek | 0:9e2fc73e5a12 | 122 | ucCmdLineOpt_send_usage(p, cmd); |
| kyourek | 0:9e2fc73e5a12 | 123 | |
| kyourek | 0:9e2fc73e5a12 | 124 | ucOpt_send_help((ucOpt*)p, cmd, ""); |
| kyourek | 0:9e2fc73e5a12 | 125 | send_arg_opts_help(ucCmdLineOpt_get_arg_opt(p), cmd, single_tab); |
| kyourek | 0:9e2fc73e5a12 | 126 | |
| kyourek | 0:9e2fc73e5a12 | 127 | switch_opt = ucCmdLineOpt_get_switch_opt(p); |
| kyourek | 0:9e2fc73e5a12 | 128 | while (NULL != switch_opt) { |
| kyourek | 0:9e2fc73e5a12 | 129 | ucOpt_send_help((ucOpt*)switch_opt, cmd, single_tab); |
| kyourek | 0:9e2fc73e5a12 | 130 | send_arg_opts_help(ucSwitchOpt_get_arg_opt(switch_opt), cmd, double_tab); |
| kyourek | 0:9e2fc73e5a12 | 131 | switch_opt = ucSwitchOpt_get_next(switch_opt); |
| kyourek | 0:9e2fc73e5a12 | 132 | } |
| kyourek | 0:9e2fc73e5a12 | 133 | } |
| kyourek | 0:9e2fc73e5a12 | 134 | |
| kyourek | 0:9e2fc73e5a12 | 135 | const char *ucCmdLineOpt_format_validation_err(ucCmdLineOpt *p, ucCmdLine *cmd) { |
| kyourek | 0:9e2fc73e5a12 | 136 | static const char *invalid_switch = "Invalid switch: "; |
| kyourek | 0:9e2fc73e5a12 | 137 | |
| kyourek | 0:9e2fc73e5a12 | 138 | ucCmdTok *cmd_tok; |
| kyourek | 0:9e2fc73e5a12 | 139 | ucSwitchOpt *switch_opt, *found_switch_opt, *next_switch_opt; |
| kyourek | 0:9e2fc73e5a12 | 140 | ucSwitchTok *switch_tok, *found_switch_tok, *next_switch_tok; |
| kyourek | 0:9e2fc73e5a12 | 141 | const char *switch_name, *validation; |
| kyourek | 0:9e2fc73e5a12 | 142 | |
| kyourek | 0:9e2fc73e5a12 | 143 | cmd_tok = ucCmdLine_get_cmd_tok(cmd); |
| kyourek | 0:9e2fc73e5a12 | 144 | |
| kyourek | 0:9e2fc73e5a12 | 145 | validation = ucArgOptOwner_format_validation_err((ucArgOptOwner*)p, cmd, ucCmdTok_get_arg(cmd_tok), NULL); |
| kyourek | 0:9e2fc73e5a12 | 146 | if (NULL != validation) return validation; |
| kyourek | 0:9e2fc73e5a12 | 147 | |
| kyourek | 0:9e2fc73e5a12 | 148 | switch_tok = ucCmdTok_get_switch(cmd_tok); |
| kyourek | 0:9e2fc73e5a12 | 149 | switch_opt = ucCmdLineOpt_get_switch_opt(p); |
| kyourek | 0:9e2fc73e5a12 | 150 | |
| kyourek | 0:9e2fc73e5a12 | 151 | if (NULL == switch_opt) { |
| kyourek | 0:9e2fc73e5a12 | 152 | if (NULL != switch_tok) { |
| kyourek | 0:9e2fc73e5a12 | 153 | return ucCmdLine_format_response(cmd, "%sno switch options exist for command \"%s\".", invalid_switch, ucTok_get_value((ucTok*)cmd_tok)); |
| kyourek | 0:9e2fc73e5a12 | 154 | } |
| kyourek | 0:9e2fc73e5a12 | 155 | return NULL; |
| kyourek | 0:9e2fc73e5a12 | 156 | } |
| kyourek | 0:9e2fc73e5a12 | 157 | |
| kyourek | 0:9e2fc73e5a12 | 158 | next_switch_tok = switch_tok; |
| kyourek | 0:9e2fc73e5a12 | 159 | |
| kyourek | 0:9e2fc73e5a12 | 160 | while (NULL != next_switch_tok) { |
| kyourek | 0:9e2fc73e5a12 | 161 | found_switch_opt = ucSwitchOpt_find(switch_opt, ucTok_get_value((ucTok*)next_switch_tok)); |
| kyourek | 0:9e2fc73e5a12 | 162 | if (NULL == found_switch_opt) { |
| kyourek | 0:9e2fc73e5a12 | 163 | return ucCmdLine_format_response(cmd, "%sno option exists for switch \"%s\".", invalid_switch, ucTok_get_value(next_switch_tok)); |
| kyourek | 0:9e2fc73e5a12 | 164 | } |
| kyourek | 0:9e2fc73e5a12 | 165 | next_switch_tok = ucSwitchTok_get_next(next_switch_tok); |
| kyourek | 0:9e2fc73e5a12 | 166 | } |
| kyourek | 0:9e2fc73e5a12 | 167 | |
| kyourek | 0:9e2fc73e5a12 | 168 | next_switch_opt = switch_opt; |
| kyourek | 0:9e2fc73e5a12 | 169 | |
| kyourek | 0:9e2fc73e5a12 | 170 | while (NULL != next_switch_opt) { |
| kyourek | 0:9e2fc73e5a12 | 171 | switch_name = ucOpt_get_name((ucOpt*)next_switch_opt); |
| kyourek | 0:9e2fc73e5a12 | 172 | found_switch_tok = ucSwitchTok_find(switch_tok, switch_name); |
| kyourek | 0:9e2fc73e5a12 | 173 | |
| kyourek | 0:9e2fc73e5a12 | 174 | if (ucOpt_is_required((ucOpt*)next_switch_opt)) { |
| kyourek | 0:9e2fc73e5a12 | 175 | if (NULL == found_switch_tok) { |
| kyourek | 0:9e2fc73e5a12 | 176 | return ucCmdLine_format_response(cmd, "%sthe switch \"%s\" is required.", invalid_switch, switch_name); |
| kyourek | 0:9e2fc73e5a12 | 177 | } |
| kyourek | 0:9e2fc73e5a12 | 178 | } |
| kyourek | 0:9e2fc73e5a12 | 179 | |
| kyourek | 0:9e2fc73e5a12 | 180 | if (NULL != found_switch_tok) { |
| kyourek | 0:9e2fc73e5a12 | 181 | validation = ucSwitchOpt_format_validation_err(next_switch_opt, cmd, found_switch_tok); |
| kyourek | 0:9e2fc73e5a12 | 182 | if (NULL != validation) return validation; |
| kyourek | 0:9e2fc73e5a12 | 183 | } |
| kyourek | 0:9e2fc73e5a12 | 184 | |
| kyourek | 0:9e2fc73e5a12 | 185 | next_switch_opt = ucSwitchOpt_get_next(next_switch_opt); |
| kyourek | 0:9e2fc73e5a12 | 186 | } |
| kyourek | 0:9e2fc73e5a12 | 187 | |
| kyourek | 0:9e2fc73e5a12 | 188 | return NULL; |
| kyourek | 0:9e2fc73e5a12 | 189 | } |
| kyourek | 0:9e2fc73e5a12 | 190 | |
| kyourek | 0:9e2fc73e5a12 | 191 | static const char *internal_process(ucCmdLineOpt *p, ucCmdLine *cmd, ucBool *invalid_command_handled) { |
| kyourek | 0:9e2fc73e5a12 | 192 | ucCmdTok *cmd_tok; |
| kyourek | 0:9e2fc73e5a12 | 193 | ucCmdLineOpt *opt; |
| kyourek | 0:9e2fc73e5a12 | 194 | ucCmdLineOpt_Func *func; |
| kyourek | 0:9e2fc73e5a12 | 195 | const char *cmd_value; |
| kyourek | 0:9e2fc73e5a12 | 196 | const char *validation; |
| kyourek | 0:9e2fc73e5a12 | 197 | |
| kyourek | 0:9e2fc73e5a12 | 198 | /* Get the command token of the command structure. */ |
| kyourek | 0:9e2fc73e5a12 | 199 | cmd_tok = ucCmdLine_get_cmd_tok(cmd); |
| kyourek | 0:9e2fc73e5a12 | 200 | |
| kyourek | 0:9e2fc73e5a12 | 201 | /* Get the command option that we'll process by finding |
| kyourek | 0:9e2fc73e5a12 | 202 | the one that matches the name of the command. */ |
| kyourek | 0:9e2fc73e5a12 | 203 | cmd_value = ucTok_get_value((ucTok*)cmd_tok); |
| kyourek | 0:9e2fc73e5a12 | 204 | opt = ucCmdLineOpt_find_by_name(p, cmd_value); |
| kyourek | 0:9e2fc73e5a12 | 205 | if (NULL == opt) { |
| kyourek | 0:9e2fc73e5a12 | 206 | |
| kyourek | 0:9e2fc73e5a12 | 207 | /* The command is invalid (meaning it doesn't exist). |
| kyourek | 0:9e2fc73e5a12 | 208 | Try to handle it. */ |
| kyourek | 0:9e2fc73e5a12 | 209 | *invalid_command_handled = ucCmdLine_handle_invalid_command(cmd, cmd_value); |
| kyourek | 0:9e2fc73e5a12 | 210 | |
| kyourek | 0:9e2fc73e5a12 | 211 | /* If the command was handled, then we don't return an error. */ |
| kyourek | 0:9e2fc73e5a12 | 212 | if (*invalid_command_handled) { |
| kyourek | 0:9e2fc73e5a12 | 213 | return NULL; |
| kyourek | 0:9e2fc73e5a12 | 214 | } |
| kyourek | 0:9e2fc73e5a12 | 215 | } |
| kyourek | 0:9e2fc73e5a12 | 216 | |
| kyourek | 0:9e2fc73e5a12 | 217 | /* Send an indication that the command was received. */ |
| kyourek | 0:9e2fc73e5a12 | 218 | ucCmdLine_acknowledge_command(cmd); |
| kyourek | 0:9e2fc73e5a12 | 219 | |
| kyourek | 0:9e2fc73e5a12 | 220 | /* Check to see if the command is unknown. */ |
| kyourek | 0:9e2fc73e5a12 | 221 | if (NULL == opt) return ucCmdLine_format_response(cmd, "Invalid command: no option found for \"%s\"", cmd_value); |
| kyourek | 0:9e2fc73e5a12 | 222 | |
| kyourek | 0:9e2fc73e5a12 | 223 | /* Validate the command structure against the option. |
| kyourek | 0:9e2fc73e5a12 | 224 | If validation fails, then return the validation result. */ |
| kyourek | 0:9e2fc73e5a12 | 225 | validation = ucCmdLineOpt_format_validation_err(opt, cmd); |
| kyourek | 0:9e2fc73e5a12 | 226 | if (validation) return validation; |
| kyourek | 0:9e2fc73e5a12 | 227 | |
| kyourek | 0:9e2fc73e5a12 | 228 | /* Get the function callback from the command option. */ |
| kyourek | 0:9e2fc73e5a12 | 229 | func = ucCmdLineOpt_get_func(opt); |
| kyourek | 0:9e2fc73e5a12 | 230 | if (NULL == func) return "Invalid function: null pointer"; |
| kyourek | 0:9e2fc73e5a12 | 231 | |
| kyourek | 0:9e2fc73e5a12 | 232 | /* Invoke the callback. */ |
| kyourek | 0:9e2fc73e5a12 | 233 | return func(cmd, ucCmdLineOpt_get_state(opt)); |
| kyourek | 0:9e2fc73e5a12 | 234 | } |
| kyourek | 0:9e2fc73e5a12 | 235 | |
| kyourek | 0:9e2fc73e5a12 | 236 | const char *ucCmdLineOpt_process(ucCmdLineOpt* p, ucCmdLine *cmd) { |
| kyourek | 0:9e2fc73e5a12 | 237 | ucBool invalid_command_handled = ucBool_FALSE; |
| kyourek | 0:9e2fc73e5a12 | 238 | const char *response = internal_process(p, cmd, &invalid_command_handled); |
| kyourek | 0:9e2fc73e5a12 | 239 | if (invalid_command_handled) { |
| kyourek | 0:9e2fc73e5a12 | 240 | return response; |
| kyourek | 0:9e2fc73e5a12 | 241 | } |
| kyourek | 0:9e2fc73e5a12 | 242 | |
| kyourek | 0:9e2fc73e5a12 | 243 | if (response) { |
| kyourek | 0:9e2fc73e5a12 | 244 | ucCmdLine_respond(cmd, response); |
| kyourek | 0:9e2fc73e5a12 | 245 | } |
| kyourek | 0:9e2fc73e5a12 | 246 | |
| kyourek | 0:9e2fc73e5a12 | 247 | ucCmdLine_terminate_response(cmd); |
| kyourek | 0:9e2fc73e5a12 | 248 | |
| kyourek | 0:9e2fc73e5a12 | 249 | return response; |
| kyourek | 0:9e2fc73e5a12 | 250 | } |
| kyourek | 0:9e2fc73e5a12 | 251 | |
| kyourek | 0:9e2fc73e5a12 | 252 | void ucCmdLineOpt_destroy(ucCmdLineOpt *p) { |
| kyourek | 0:9e2fc73e5a12 | 253 | ucMemoryManager_destroy(p); |
| kyourek | 0:9e2fc73e5a12 | 254 | } |
| kyourek | 0:9e2fc73e5a12 | 255 | |
| kyourek | 0:9e2fc73e5a12 | 256 | void ucCmdLineOpt_destroy_chain(ucCmdLineOpt *p) { |
| kyourek | 0:9e2fc73e5a12 | 257 | ucCmdLineOpt *next = p; |
| kyourek | 0:9e2fc73e5a12 | 258 | while (NULL != next) { |
| kyourek | 0:9e2fc73e5a12 | 259 | p = next; |
| kyourek | 0:9e2fc73e5a12 | 260 | next = ucCmdLineOpt_get_next(p); |
| kyourek | 0:9e2fc73e5a12 | 261 | ucArgOpt_destroy_chain(ucCmdLineOpt_get_arg_opt(p)); |
| kyourek | 0:9e2fc73e5a12 | 262 | ucSwitchOpt_destroy_chain(ucCmdLineOpt_get_switch_opt(p)); |
| kyourek | 0:9e2fc73e5a12 | 263 | ucCmdLineOpt_destroy(p); |
| kyourek | 0:9e2fc73e5a12 | 264 | } |
| kyourek | 0:9e2fc73e5a12 | 265 | } |
| kyourek | 0:9e2fc73e5a12 | 266 |