| Line | Branch | Decision | Exec | Source |
|---|---|---|---|---|
| 1 | /** | |||
| 2 | * @file cli_registry.cpp | |||
| 3 | * @brief Command-line interface commands registry | |||
| 4 | * | |||
| 5 | * Here we have a data structure which holds all the dynamically-registered | |||
| 6 | * command line interface action names & callback. This logic is invoked in | |||
| 7 | * user context by the console thread - see consoleThreadEntryPoint | |||
| 8 | * | |||
| 9 | * TODO: there is too much copy-paste here, this class needs some refactoring :) | |||
| 10 | * | |||
| 11 | * see testConsoleLogic() | |||
| 12 | * | |||
| 13 | * @date Nov 15, 2012 | |||
| 14 | * @author Andrey Belomutskiy, (c) 2012-2020 | |||
| 15 | */ | |||
| 16 | ||||
| 17 | #include <cstring> | |||
| 18 | #include <cstdint> | |||
| 19 | ||||
| 20 | // looks like some technical debt here?! that's about error: ‘isnan’ is not a member of ‘std’ | |||
| 21 | #include <cmath> | |||
| 22 | #include <rusefi/rusefi_math.h> | |||
| 23 | ||||
| 24 | #include "efiprintf.h" | |||
| 25 | #include "rusefi/efistringutil.h" | |||
| 26 | #include "cli_registry.h" | |||
| 27 | ||||
| 28 | /* for isspace() */ | |||
| 29 | #include <cctype> | |||
| 30 | ||||
| 31 | #ifndef CONSOLE_MAX_ACTIONS | |||
| 32 | #define CONSOLE_MAX_ACTIONS 256 | |||
| 33 | #endif | |||
| 34 | ||||
| 35 | #ifndef MAX_CMD_LINE_LENGTH | |||
| 36 | #define MAX_CMD_LINE_LENGTH 100 | |||
| 37 | #endif | |||
| 38 | ||||
| 39 | // todo: support \t as well | |||
| 40 | #define SPACE_CHAR ' ' | |||
| 41 | ||||
| 42 | using namespace rusefi::stringutil; | |||
| 43 | ||||
| 44 | static int consoleActionCount = 0; | |||
| 45 | static TokenCallback consoleActions[CONSOLE_MAX_ACTIONS]; | |||
| 46 | ||||
| 47 | 1 | void resetConsoleActions(void) { | ||
| 48 | 1 | consoleActionCount = 0; | ||
| 49 | 1 | } | ||
| 50 | ||||
| 51 | 12 | static void doAddAction(const char *token, action_type_e type, Void callback, void *param) { | ||
| 52 | #if !defined(EFI_DISABLE_CONSOLE_ACTIONS) | |||
| 53 |
2/2✓ Branch 0 taken 137 times.
✓ Branch 1 taken 12 times.
|
2/2✓ Decision 'true' taken 137 times.
✓ Decision 'false' taken 12 times.
|
149 | for (uint32_t i = 0; i < std::strlen(token); i++) { |
| 54 | 137 | char ch = token[i]; | ||
| 55 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 137 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 137 times.
|
137 | if (isupper(ch)) { |
| 56 | ✗ | onCliCaseError(token); | ||
| 57 | ✗ | return; | ||
| 58 | } | |||
| 59 | } | |||
| 60 |
2/2✓ Branch 0 taken 54 times.
✓ Branch 1 taken 8 times.
|
2/2✓ Decision 'true' taken 54 times.
✓ Decision 'false' taken 8 times.
|
62 | for (int i = 0; i < consoleActionCount; i++) { |
| 61 |
2/2✓ Branch 1 taken 4 times.
✓ Branch 2 taken 50 times.
|
2/2✓ Decision 'true' taken 4 times.
✓ Decision 'false' taken 50 times.
|
54 | if (strcmp(token, consoleActions[i].token) == 0 /* zero result means strings are equal */) { |
| 62 | 4 | onCliDuplicateError(token); | ||
| 63 | 4 | return; | ||
| 64 | } | |||
| 65 | } | |||
| 66 | ||||
| 67 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 8 times.
|
8 | if (consoleActionCount >= CONSOLE_MAX_ACTIONS) { |
| 68 | ✗ | onCliOverflowError(); | ||
| 69 | ✗ | return; | ||
| 70 | } | |||
| 71 | ||||
| 72 | 8 | TokenCallback *current = &consoleActions[consoleActionCount++]; | ||
| 73 | 8 | current->token = token; | ||
| 74 | 8 | current->parameterType = type; | ||
| 75 | 8 | current->callback = callback; | ||
| 76 | 8 | current->param = param; | ||
| 77 | #endif /* EFI_DISABLE_CONSOLE_ACTIONS */ | |||
| 78 | } | |||
| 79 | ||||
| 80 | ✗ | void addConsoleActionP(const char *token, VoidPtr callback, void *param) { | ||
| 81 | ✗ | doAddAction(token, NO_PARAMETER_P, (Void) callback, param); | ||
| 82 | ✗ | } | ||
| 83 | ||||
| 84 | ✗ | void addConsoleActionSSP(const char *token, VoidCharPtrCharPtrVoidPtr callback, void *param) { | ||
| 85 | ✗ | doAddAction(token, STRING2_PARAMETER_P, (Void) callback, param); | ||
| 86 | ✗ | } | ||
| 87 | ||||
| 88 | /** | |||
| 89 | * @brief Register console action without parameters | |||
| 90 | */ | |||
| 91 | 4 | void addConsoleAction(const char *token, Void callback) { | ||
| 92 | 4 | doAddAction(token, NO_PARAMETER, callback, NULL); | ||
| 93 | 4 | } | ||
| 94 | ||||
| 95 | /** | |||
| 96 | * @brief Register a console command with one Integer parameter | |||
| 97 | */ | |||
| 98 | 3 | void addConsoleActionI(const char *token, VoidInt callback) { | ||
| 99 | 3 | doAddAction(token, ONE_PARAMETER, (Void) callback, NULL); | ||
| 100 | 3 | } | ||
| 101 | ||||
| 102 | ✗ | void addConsoleActionIP(const char *token, VoidIntVoidPtr callback, void *param) { | ||
| 103 | ✗ | doAddAction(token, ONE_PARAMETER_P, (Void) callback, param); | ||
| 104 | ✗ | } | ||
| 105 | ||||
| 106 | /** | |||
| 107 | * @brief Register a console command with two Integer parameters | |||
| 108 | */ | |||
| 109 | 1 | void addConsoleActionII(const char *token, VoidIntInt callback) { | ||
| 110 | 1 | doAddAction(token, TWO_INTS_PARAMETER, (Void) callback, NULL); | ||
| 111 | 1 | } | ||
| 112 | ||||
| 113 | ✗ | void addConsoleActionIIP(const char *token, VoidIntIntVoidPtr callback, void *param) { | ||
| 114 | ✗ | doAddAction(token, TWO_INTS_PARAMETER_P, (Void) callback, param); | ||
| 115 | ✗ | } | ||
| 116 | ||||
| 117 | ✗ | void addConsoleActionIF(const char *token, VoidIntFloat callback) { | ||
| 118 | ✗ | doAddAction(token, INT_FLOAT_PARAMETER, (Void) callback, NULL); | ||
| 119 | ✗ | } | ||
| 120 | ||||
| 121 | ✗ | void addConsoleActionS(const char *token, VoidCharPtr callback) { | ||
| 122 | ✗ | doAddAction(token, STRING_PARAMETER, (Void) callback, NULL); | ||
| 123 | ✗ | } | ||
| 124 | ||||
| 125 | ✗ | void addConsoleActionSP(const char *token, VoidCharPtrVoidPtr callback, void *param) { | ||
| 126 | ✗ | doAddAction(token, STRING_PARAMETER_P, (Void) callback, param); | ||
| 127 | ✗ | } | ||
| 128 | ||||
| 129 | 2 | void addConsoleActionSS(const char *token, VoidCharPtrCharPtr callback) { | ||
| 130 | 2 | doAddAction(token, STRING2_PARAMETER, (Void) callback, NULL); | ||
| 131 | 2 | } | ||
| 132 | ||||
| 133 | 1 | void addConsoleActionSSS(const char *token, VoidCharPtrCharPtrCharPtr callback) { | ||
| 134 | 1 | doAddAction(token, STRING3_PARAMETER, (Void) callback, NULL); | ||
| 135 | 1 | } | ||
| 136 | ||||
| 137 | ✗ | void addConsoleActionSSSSS(const char *token, VoidCharPtrCharPtrCharPtrCharPtrCharPtr callback) { | ||
| 138 | ✗ | doAddAction(token, STRING5_PARAMETER, (Void) callback, NULL); | ||
| 139 | ✗ | } | ||
| 140 | ||||
| 141 | ✗ | void addConsoleActionNANF(const char *token, VoidFloat callback) { | ||
| 142 | ✗ | doAddAction(token, FLOAT_PARAMETER_NAN_ALLOWED, (Void) callback, NULL); | ||
| 143 | ✗ | } | ||
| 144 | ||||
| 145 | ✗ | void addConsoleActionF(const char *token, VoidFloat callback) { | ||
| 146 | ✗ | doAddAction(token, FLOAT_PARAMETER, (Void) callback, NULL); | ||
| 147 | ✗ | } | ||
| 148 | ||||
| 149 | ✗ | void addConsoleActionFF(const char *token, VoidFloatFloat callback) { | ||
| 150 | ✗ | doAddAction(token, FLOAT_FLOAT_PARAMETER, (Void) callback, NULL); | ||
| 151 | ✗ | } | ||
| 152 | ||||
| 153 | 1 | void addConsoleActionFFF(const char *token, VoidFloatFloatFloat callback) { | ||
| 154 | 1 | doAddAction(token, FLOAT_FLOAT_FLOAT_PARAMETER, (Void) callback, NULL); | ||
| 155 | 1 | } | ||
| 156 | ||||
| 157 | ✗ | void addConsoleActionFFFF(const char *token, VoidFloatFloatFloatFloat callback) { | ||
| 158 | ✗ | doAddAction(token, FLOAT_FLOAT_FLOAT_FLOAT_PARAMETER, (Void) callback, NULL); | ||
| 159 | ✗ | } | ||
| 160 | ||||
| 161 | ✗ | void addConsoleActionFFP(const char *token, VoidFloatFloatVoidPtr callback, void *param) { | ||
| 162 | ✗ | doAddAction(token, FLOAT_FLOAT_PARAMETER_P, (Void) callback, param); | ||
| 163 | ✗ | } | ||
| 164 | ||||
| 165 | 7 | static int getParameterCount(action_type_e parameterType) { | ||
| 166 |
3/7✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 3 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
|
7 | switch (parameterType) { | |
| 167 | ✗ | case NO_PARAMETER: | ||
| 168 | case NO_PARAMETER_P: | |||
| 169 | ✗ | return 0; | ||
| 170 |
1/1✓ Decision 'true' taken 2 times.
|
2 | case ONE_PARAMETER: | |
| 171 | case ONE_PARAMETER_P: | |||
| 172 | case FLOAT_PARAMETER: | |||
| 173 | case STRING_PARAMETER: | |||
| 174 |
1/1✓ Decision 'true' taken 2 times.
|
2 | return 1; | |
| 175 |
1/1✓ Decision 'true' taken 2 times.
|
2 | case FLOAT_FLOAT_PARAMETER: | |
| 176 | case FLOAT_FLOAT_PARAMETER_P: | |||
| 177 | case STRING2_PARAMETER: | |||
| 178 | case STRING2_PARAMETER_P: | |||
| 179 | case TWO_INTS_PARAMETER: | |||
| 180 | case TWO_INTS_PARAMETER_P: | |||
| 181 | case INT_FLOAT_PARAMETER: | |||
| 182 |
1/1✓ Decision 'true' taken 2 times.
|
2 | return 2; | |
| 183 |
1/1✓ Decision 'true' taken 3 times.
|
3 | case STRING3_PARAMETER: | |
| 184 | case FLOAT_FLOAT_FLOAT_PARAMETER: | |||
| 185 |
1/1✓ Decision 'true' taken 3 times.
|
3 | return 3; | |
| 186 | ✗ | case FLOAT_FLOAT_FLOAT_FLOAT_PARAMETER: | ||
| 187 | ✗ | return 4; | ||
| 188 | ✗ | case STRING5_PARAMETER: | ||
| 189 | ✗ | return 5; | ||
| 190 | ✗ | default: | ||
| 191 | ✗ | return -1; | ||
| 192 | } | |||
| 193 | } | |||
| 194 | ||||
| 195 | /** | |||
| 196 | * @brief This function prints out a list of all available commands | |||
| 197 | */ | |||
| 198 | 1 | void helpCommand(void) { | ||
| 199 | 1 | efiPrintf("%d actions available", consoleActionCount); | ||
| 200 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 1 time.
|
1 | for (int i = 0; i < consoleActionCount; i++) { |
| 201 | ✗ | TokenCallback *current = &consoleActions[i]; | ||
| 202 | ✗ | efiPrintf(" %s: %d parameters", current->token, getParameterCount(current->parameterType)); | ||
| 203 | } | |||
| 204 | 1 | efiPrintf("For more visit https://github.com/rusefi/rusefi/wiki/Dev-Console-Commands"); | ||
| 205 | 1 | } | ||
| 206 | ||||
| 207 | 3 | int findEndOfToken(const char *line) { | ||
| 208 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 time.
|
2/2✓ Decision 'true' taken 2 times.
✓ Decision 'false' taken 1 time.
|
3 | if (line[0] == '"') { |
| 209 | /** | |||
| 210 | * Looks like this is a quoted token | |||
| 211 | */ | |||
| 212 | 2 | int v = indexOf(line + 1, '"'); | ||
| 213 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 2 times.
|
2 | if (v == -1) { |
| 214 | /** | |||
| 215 | * Matching closing quote not found | |||
| 216 | */ | |||
| 217 | ✗ | return -1; | ||
| 218 | } | |||
| 219 | /** | |||
| 220 | * Skipping first quote and the symbol after closing quote | |||
| 221 | */ | |||
| 222 | 2 | return v + 2; | ||
| 223 | } | |||
| 224 | 1 | return indexOf(line, SPACE_CHAR); | ||
| 225 | } | |||
| 226 | ||||
| 227 | /** | |||
| 228 | * @return Number of space-separated tokens in the string | |||
| 229 | */ | |||
| 230 | 1 | int tokenLength(const char *msgp) { | ||
| 231 | 1 | int result = 0; | ||
| 232 |
2/2✓ Branch 0 taken 10 times.
✓ Branch 1 taken 1 time.
|
2/2✓ Decision 'true' taken 10 times.
✓ Decision 'false' taken 1 time.
|
11 | while (*msgp) { |
| 233 | 10 | char ch = *msgp++; | ||
| 234 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 10 times.
|
10 | if (ch == SPACE_CHAR) { |
| 235 | ✗ | break; | ||
| 236 | } | |||
| 237 | 10 | result++; | ||
| 238 | } | |||
| 239 | 1 | return result; | ||
| 240 | } | |||
| 241 | ||||
| 242 | 2 | char *unquote(char *line) { | ||
| 243 |
2/2✓ Branch 0 taken 1 time.
✓ Branch 1 taken 1 time.
|
2/2✓ Decision 'true' taken 1 time.
✓ Decision 'false' taken 1 time.
|
2 | if (line[0] == '"') { |
| 244 | 1 | int len = std::strlen(line); | ||
| 245 |
1/2✓ Branch 0 taken 1 time.
✗ Branch 1 not taken.
|
1/2✓ Decision 'true' taken 1 time.
✗ Decision 'false' not taken.
|
1 | if (line[len - 1] == '"') { |
| 246 | 1 | line[len - 1] = 0; | ||
| 247 | 1 | return line + 1; | ||
| 248 | } | |||
| 249 | } | |||
| 250 | 1 | return line; | ||
| 251 | } | |||
| 252 | ||||
| 253 | 8 | static int setargs(char *args, char **argv, int max_args) | ||
| 254 | { | |||
| 255 | 8 | int count = 0; | ||
| 256 | ||||
| 257 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 8 times.
|
8 | while (isspace(*args)) { |
| 258 | ✗ | *args = '\0'; | ||
| 259 | ✗ | args++; | ||
| 260 | } | |||
| 261 |
3/4✓ Branch 0 taken 24 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 24 times.
✗ Branch 3 not taken.
|
0/1? Decision couldn't be analyzed.
|
32 | while ((*args) && (count < max_args)) { |
| 262 |
1/2✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
|
1/2✓ Decision 'true' taken 24 times.
✗ Decision 'false' not taken.
|
24 | if (argv) { |
| 263 | 24 | argv[count] = args; | ||
| 264 | } | |||
| 265 |
4/4✓ Branch 0 taken 115 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 99 times.
✓ Branch 3 taken 16 times.
|
0/1? Decision couldn't be analyzed.
|
123 | while ((*args) && (!isspace(*args))) { |
| 266 |
2/2✓ Branch 0 taken 1 time.
✓ Branch 1 taken 98 times.
|
2/2✓ Decision 'true' taken 1 time.
✓ Decision 'false' taken 98 times.
|
99 | if (*args == '"') { |
| 267 | 1 | args++; | ||
| 268 | /* find closing quote */ | |||
| 269 |
3/4✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 1 time.
|
0/1? Decision couldn't be analyzed.
|
3 | while ((*args) && (*args != '"')) { |
| 270 | 2 | args++; | ||
| 271 | } | |||
| 272 | /* failed? */ | |||
| 273 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 time.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 1 time.
|
1 | if (*args == '\0') { |
| 274 | ✗ | return -1; | ||
| 275 | } | |||
| 276 | } | |||
| 277 | 99 | args++; | ||
| 278 | } | |||
| 279 |
2/2✓ Branch 0 taken 16 times.
✓ Branch 1 taken 8 times.
|
2/2✓ Decision 'true' taken 16 times.
✓ Decision 'false' taken 8 times.
|
24 | if (*args) { |
| 280 | 16 | *args = '\0'; | ||
| 281 | 16 | args++; | ||
| 282 | } | |||
| 283 |
2/2✓ Branch 0 taken 5 times.
✓ Branch 1 taken 24 times.
|
2/2✓ Decision 'true' taken 5 times.
✓ Decision 'false' taken 24 times.
|
29 | while (isspace(*args)) { |
| 284 | 5 | *args = '\0'; | ||
| 285 | 5 | args++; | ||
| 286 | } | |||
| 287 | 24 | count++; | ||
| 288 | } | |||
| 289 | 8 | return count; | ||
| 290 | } | |||
| 291 | ||||
| 292 | 7 | int handleActionWithParameter(TokenCallback *current, char *argv[], int argc) { | ||
| 293 | (void)argc; | |||
| 294 | ||||
| 295 |
4/17✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✓ Branch 12 taken 1 time.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 15 taken 2 times.
✗ Branch 16 not taken.
|
7 | switch (current->parameterType) { | |
| 296 | ✗ | case NO_PARAMETER: | ||
| 297 | { | |||
| 298 | ✗ | (*current->callback)(); | ||
| 299 | ✗ | return 0; | ||
| 300 | } | |||
| 301 | ✗ | case NO_PARAMETER_P: | ||
| 302 | { | |||
| 303 | ✗ | VoidPtr callbackS = (VoidPtr) current->callback; | ||
| 304 | ✗ | (*callbackS)(current->param); | ||
| 305 | ✗ | return 0; | ||
| 306 | } | |||
| 307 | ✗ | case STRING_PARAMETER: | ||
| 308 | { | |||
| 309 | ✗ | VoidCharPtr callbackS = (VoidCharPtr) current->callback; | ||
| 310 | ✗ | (*callbackS)(argv[0]); | ||
| 311 | ✗ | return 0; | ||
| 312 | } | |||
| 313 | ✗ | case STRING_PARAMETER_P: | ||
| 314 | { | |||
| 315 | ✗ | VoidCharPtrVoidPtr callbackS = (VoidCharPtrVoidPtr) current->callback; | ||
| 316 | ✗ | (*callbackS)(argv[0], current->param); | ||
| 317 | ✗ | return 0; | ||
| 318 | } | |||
| 319 | ✗ | case STRING2_PARAMETER: | ||
| 320 | { | |||
| 321 | ✗ | VoidCharPtrCharPtr callbackS = (VoidCharPtrCharPtr) current->callback; | ||
| 322 | ✗ | (*callbackS)(argv[0], argv[1]); | ||
| 323 | ✗ | return 0; | ||
| 324 | } | |||
| 325 | ✗ | case STRING2_PARAMETER_P: | ||
| 326 | { | |||
| 327 | ✗ | VoidCharPtrCharPtrVoidPtr callbackS = (VoidCharPtrCharPtrVoidPtr) current->callback; | ||
| 328 | ✗ | (*callbackS)(argv[0], argv[1], current->param); | ||
| 329 | ✗ | return 0; | ||
| 330 | } | |||
| 331 |
1/1✓ Decision 'true' taken 2 times.
|
2 | case STRING3_PARAMETER: | |
| 332 | { | |||
| 333 | 2 | VoidCharPtrCharPtrCharPtr callbackS = (VoidCharPtrCharPtrCharPtr) current->callback; | ||
| 334 | 2 | (*callbackS)(argv[0], argv[1], argv[2]); | ||
| 335 | 2 | return 0; | ||
| 336 | } | |||
| 337 | ✗ | case STRING5_PARAMETER: | ||
| 338 | { | |||
| 339 | ✗ | VoidCharPtrCharPtrCharPtrCharPtrCharPtr callbackS = (VoidCharPtrCharPtrCharPtrCharPtrCharPtr) current->callback; | ||
| 340 | ✗ | (*callbackS)(argv[0], argv[1], argv[2], argv[3], argv[4]); | ||
| 341 | ✗ | return 0; | ||
| 342 | } | |||
| 343 |
1/1✓ Decision 'true' taken 2 times.
|
2 | case TWO_INTS_PARAMETER: | |
| 344 | { | |||
| 345 | 2 | int value[2]; | ||
| 346 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
|
2/2✓ Decision 'true' taken 4 times.
✓ Decision 'false' taken 2 times.
|
6 | for (int i = 0; i < 2; i++) { |
| 347 | 4 | value[i] = atoi(argv[i]); | ||
| 348 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 4 times.
|
4 | if (absI(value[i]) == ATOI_ERROR_CODE) { |
| 349 | #if EFI_PROD_CODE || EFI_SIMULATOR | |||
| 350 | efiPrintf("not an integer [%s]", argv[0]); | |||
| 351 | #endif | |||
| 352 | ✗ | return -1; | ||
| 353 | } | |||
| 354 | } | |||
| 355 | 2 | VoidIntInt callbackS = (VoidIntInt) current->callback; | ||
| 356 |
1/1✓ Branch 1 taken 2 times.
|
2 | (*callbackS)(value[0], value[1]); | |
| 357 | 2 | return 0; | ||
| 358 | } | |||
| 359 | ✗ | case FLOAT_PARAMETER_NAN_ALLOWED: | ||
| 360 | { | |||
| 361 | ✗ | float value = atoff(argv[0]); | ||
| 362 | ✗ | VoidFloat callbackF = (VoidFloat) current->callback; | ||
| 363 | ✗ | (*callbackF)(value); | ||
| 364 | ✗ | return 0; | ||
| 365 | } | |||
| 366 | ||||
| 367 | ✗ | case FLOAT_PARAMETER: | ||
| 368 | { | |||
| 369 | ✗ | float value = atoff(argv[0]); | ||
| 370 | ✗ | if (std::isnan(value)) { | ||
| 371 | ✗ | efiPrintf("invalid float [%s]", argv[0]); | ||
| 372 | ✗ | return -1; | ||
| 373 | } | |||
| 374 | ✗ | VoidFloat callbackF = (VoidFloat) current->callback; | ||
| 375 | ✗ | (*callbackF)(value); | ||
| 376 | ✗ | return 0; | ||
| 377 | } | |||
| 378 | ||||
| 379 | ✗ | case FLOAT_FLOAT_PARAMETER: | ||
| 380 | case FLOAT_FLOAT_PARAMETER_P: | |||
| 381 | { | |||
| 382 | ✗ | float value[2]; | ||
| 383 | ✗ | for (int i = 0; i < 2; i++) { | ||
| 384 | ✗ | value[i] = atoff(argv[i]); | ||
| 385 | ✗ | if (std::isnan(value[i])) { | ||
| 386 | ✗ | efiPrintf("invalid float [%s]", argv[i]); | ||
| 387 | ✗ | return -1; | ||
| 388 | } | |||
| 389 | } | |||
| 390 | ✗ | if (current->parameterType == FLOAT_FLOAT_PARAMETER) { | ||
| 391 | ✗ | VoidFloatFloat callbackS = (VoidFloatFloat) current->callback; | ||
| 392 | ✗ | (*callbackS)(value[0], value[1]); | ||
| 393 | } else { | |||
| 394 | ✗ | VoidFloatFloatVoidPtr callbackS = (VoidFloatFloatVoidPtr) current->callback; | ||
| 395 | ✗ | (*callbackS)(value[0], value[1], current->param); | ||
| 396 | } | |||
| 397 | ✗ | return 0; | ||
| 398 | } | |||
| 399 |
1/1✓ Decision 'true' taken 1 time.
|
1 | case FLOAT_FLOAT_FLOAT_PARAMETER: | |
| 400 | { | |||
| 401 | 1 | float value[3]; | ||
| 402 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 time.
|
2/2✓ Decision 'true' taken 3 times.
✓ Decision 'false' taken 1 time.
|
4 | for (int i = 0; i < 3; i++) { |
| 403 |
1/1✓ Branch 2 taken 3 times.
|
3 | value[i] = atoff(argv[i]); | |
| 404 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 3 times.
|
3 | if (std::isnan(value[i])) { |
| 405 | ✗ | efiPrintf("invalid float [%s]", argv[i]); | ||
| 406 | ✗ | return -1; | ||
| 407 | } | |||
| 408 | } | |||
| 409 | 1 | VoidFloatFloatFloat callbackS = (VoidFloatFloatFloat) current->callback; | ||
| 410 |
1/1✓ Branch 1 taken 1 time.
|
1 | (*callbackS)(value[0], value[1], value[2]); | |
| 411 | 1 | return 0; | ||
| 412 | } | |||
| 413 | ✗ | case FLOAT_FLOAT_FLOAT_FLOAT_PARAMETER: | ||
| 414 | { | |||
| 415 | ✗ | float value[4]; | ||
| 416 | ✗ | for (int i = 0; i < 4; i++) { | ||
| 417 | ✗ | value[i] = atoff(argv[i]); | ||
| 418 | ✗ | if (std::isnan(value[i])) { | ||
| 419 | ✗ | efiPrintf("invalid float [%s]", argv[i]); | ||
| 420 | ✗ | return -1; | ||
| 421 | } | |||
| 422 | } | |||
| 423 | ✗ | VoidFloatFloatFloatFloat callbackS = (VoidFloatFloatFloatFloat) current->callback; | ||
| 424 | ✗ | (*callbackS)(value[0], value[1], value[2], value[3]); | ||
| 425 | ✗ | return 0; | ||
| 426 | } | |||
| 427 | ✗ | case INT_FLOAT_PARAMETER: | ||
| 428 | { | |||
| 429 | ✗ | int value1 = atoi(argv[0]); | ||
| 430 | ✗ | if (absI(value1) == ATOI_ERROR_CODE) { | ||
| 431 | #if EFI_PROD_CODE || EFI_SIMULATOR | |||
| 432 | efiPrintf("not an integer [%s]", argv[0]); | |||
| 433 | #endif | |||
| 434 | ✗ | return -1; | ||
| 435 | } | |||
| 436 | ✗ | float value2 = atoff(argv[1]); | ||
| 437 | ✗ | if (std::isnan(value2)) { | ||
| 438 | ✗ | efiPrintf("invalid float [%s]", argv[1]); | ||
| 439 | ✗ | return -1; | ||
| 440 | } | |||
| 441 | ✗ | VoidIntFloat callback = (VoidIntFloat) current->callback; | ||
| 442 | ✗ | callback(value1, value2); | ||
| 443 | ✗ | return 0; | ||
| 444 | } | |||
| 445 |
1/1✓ Decision 'true' taken 2 times.
|
2 | case ONE_PARAMETER_P: | |
| 446 | case ONE_PARAMETER: | |||
| 447 | { | |||
| 448 |
1/1✓ Decision 'true' taken 2 times.
|
2 | int value = atoi(argv[0]); | |
| 449 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 2 times.
|
2 | if (absI(value) == ATOI_ERROR_CODE) { |
| 450 | #if EFI_PROD_CODE || EFI_SIMULATOR | |||
| 451 | efiPrintf("not an integer [%s]", argv[0]); | |||
| 452 | #endif | |||
| 453 | ✗ | return -1; | ||
| 454 | } | |||
| 455 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 2 times.
|
2 | if (current->parameterType == ONE_PARAMETER_P) { |
| 456 | ✗ | VoidIntVoidPtr callback1 = (VoidIntVoidPtr) current->callback; | ||
| 457 | ✗ | (*callback1)(value, current->param); | ||
| 458 | ||||
| 459 | } else { | |||
| 460 | 2 | VoidInt callback1 = (VoidInt) current->callback; | ||
| 461 | 2 | (*callback1)(value); | ||
| 462 | } | |||
| 463 | 2 | return 0; | ||
| 464 | } | |||
| 465 | ✗ | default: | ||
| 466 | ✗ | efiPrintf("Unsupported parameterType %d", current->parameterType); | ||
| 467 | ✗ | break; | ||
| 468 | } | |||
| 469 | ✗ | return -1; | ||
| 470 | } | |||
| 471 | ||||
| 472 | ✗ | void initConsoleLogic() { | ||
| 473 | ✗ | addConsoleAction("help", helpCommand); | ||
| 474 | ✗ | } | ||
| 475 | ||||
| 476 | static char handleBuffer[MAX_CMD_LINE_LENGTH + 1]; | |||
| 477 | ||||
| 478 | 8 | static int handleConsoleLineInternal(const char *commandLine) { | ||
| 479 | 8 | strncpy(handleBuffer, commandLine, sizeof(handleBuffer) - 1); | ||
| 480 | ||||
| 481 | 8 | char *argv[10]; | ||
| 482 | 8 | int argc = setargs(handleBuffer, argv, 10); | ||
| 483 | ||||
| 484 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 8 times.
|
8 | if (argc <= 0) { |
| 485 | ✗ | efiPrintf("invalid input"); | ||
| 486 | ✗ | return -1; | ||
| 487 | } | |||
| 488 | ||||
| 489 |
2/2✓ Branch 0 taken 16 times.
✓ Branch 1 taken 1 time.
|
2/2✓ Decision 'true' taken 16 times.
✓ Decision 'false' taken 1 time.
|
17 | for (int i = 0; i < consoleActionCount; i++) { |
| 490 | 16 | TokenCallback *current = &consoleActions[i]; | ||
| 491 |
3/3✓ Branch 1 taken 16 times.
✓ Branch 3 taken 7 times.
✓ Branch 4 taken 9 times.
|
2/2✓ Decision 'true' taken 7 times.
✓ Decision 'false' taken 9 times.
|
16 | if (strEqual(argv[0], current->token)) { |
| 492 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 7 times.
|
7 | if ((argc - 1) != getParameterCount(current->parameterType)) { |
| 493 | ✗ | efiPrintf("Incorrect argument count %d, expected %d", | ||
| 494 | (argc - 1), getParameterCount(current->parameterType)); | |||
| 495 | ✗ | return -1; | ||
| 496 | } | |||
| 497 | ||||
| 498 | /* skip commant name */ | |||
| 499 |
1/1✓ Branch 1 taken 7 times.
|
7 | return handleActionWithParameter(current, argv + 1, argc - 1); | |
| 500 | } | |||
| 501 | } | |||
| 502 | ||||
| 503 |
1/1✓ Branch 1 taken 1 time.
|
1 | efiPrintf("unknown command [%s]", commandLine); | |
| 504 | 1 | return -1; | ||
| 505 | } | |||
| 506 | ||||
| 507 | /** | |||
| 508 | * @brief This function takes care of one command line once we have it | |||
| 509 | */ | |||
| 510 | 8 | void handleConsoleLine(char *line) { | ||
| 511 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 8 times.
|
8 | if (line == NULL) |
| 512 | ✗ | return; // error detected | ||
| 513 | ||||
| 514 | 8 | int lineLength = std::strlen(line); | ||
| 515 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
|
1/2✗ Decision 'true' not taken.
✓ Decision 'false' taken 8 times.
|
8 | if (lineLength > MAX_CMD_LINE_LENGTH) { |
| 516 | // todo: better reaction to excessive line | |||
| 517 | ✗ | efiPrintf("Long line?"); | ||
| 518 | ✗ | return; | ||
| 519 | } | |||
| 520 | ||||
| 521 | 8 | int ret = handleConsoleLineInternal(line); | ||
| 522 | ||||
| 523 |
2/2✓ Branch 0 taken 1 time.
✓ Branch 1 taken 7 times.
|
2/2✓ Decision 'true' taken 1 time.
✓ Decision 'false' taken 7 times.
|
8 | if (ret < 0) { |
| 524 | 1 | efiPrintf("failed to handle command [%s]", line); | ||
| 525 | 1 | return; | ||
| 526 | } | |||
| 527 | ||||
| 528 | 7 | efiPrintf("confirmation_%s:%d", line, lineLength); | ||
| 529 | } | |||
| 530 |