GCC Code Coverage Report


Directory: ./
File: firmware/util/cli_registry.cpp
Date: 2025-10-03 00:57:22
Warnings: 3 unchecked decisions!
Coverage Exec Excl Total
Lines: 47.8% 139 0 291
Functions: 54.8% 17 0 31
Branches: 52.3% 68 0 130
Decisions: 49.1% 56 - 114

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