Skip to content

Commit cf00766

Browse files
committed
feat(esp_commands): Add tests to the esp_commands component
1 parent 9045c4e commit cf00766

File tree

15 files changed

+591
-128
lines changed

15 files changed

+591
-128
lines changed

.github/ISSUE_TEMPLATE/bug-report.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ body:
3030
- dhara
3131
- eigen
3232
- esp_delta_ota
33+
- esp_commands
3334
- esp_encrypted_img
3435
- esp_jpeg
3536
- esp_lcd_qemu_rgb

.github/workflows/upload_component.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ jobs:
4242
dhara;
4343
eigen;
4444
esp_delta_ota;
45+
esp_commands;
4546
esp_encrypted_img;
4647
esp_lcd_qemu_rgb;
4748
esp_jpeg;

.idf_build_apps.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ manifest_file = [
77
"bdc_motor/.build-test-rules.yml",
88
"ccomp_timer/.build-test-rules.yml",
99
"coremark/.build-test-rules.yml",
10+
"esp_commands/.build-test-rules.yml",
1011
"esp_encrypted_img/.build-test-rules.yml",
1112
"esp_jpeg/.build-test-rules.yml",
1213
"esp_serial_slave_link/.build-test-rules.yml",

esp_commands/CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
idf_build_get_property(target IDF_TARGET)
22

33
set(srcs "esp_commands.c"
4-
"eps_commands_helpers.c")
4+
"esp_commands_helpers.c")
55

66
idf_component_register(
7-
SRCS "esp_commands.c" "eps_commands_helpers.c"
7+
SRCS ${srcs}
88
INCLUDE_DIRS include
99
PRIV_INCLUDE_DIRS private_include
1010
LDFRAGMENTS linker.lf)

esp_commands/esp_commands.c

Lines changed: 156 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -8,28 +8,14 @@
88
#include "esp_commands_helpers.h"
99
#include "esp_err.h"
1010

11-
#define ANSI_COLOR_DEFAULT 39 /** Default foreground color */
11+
/* Default foreground color */
12+
#define ANSI_COLOR_DEFAULT 39
1213

1314
/* Pointers to the first and last command in the dedicated section.
1415
* See linker.lf for detailed information about the section */
1516
extern esp_command_t _esp_commands_start;
1617
extern esp_command_t _esp_commands_end;
1718

18-
/**
19-
* @brief go through all commands registered in the
20-
* memory section starting at _esp_commands_start
21-
* and ending at _esp_commands_end
22-
*/
23-
#define FOR_EACH_COMMAND_IN_SECTION(cmd) \
24-
for ((cmd) = &_esp_commands_start; \
25-
(cmd) < &_esp_commands_end; \
26-
(esp_command_t*)(cmd)++)
27-
28-
#define FOR_EACH_COMMAND_IN_SET(cmd, cmd_set) \
29-
for ((cmd) = cmd_set->cmd_ptr_set[0]; \
30-
(cmd) < cmd_set->cmd_ptr_set[cmd_set->cmd_prt_set_size - 1]; \
31-
(esp_command_t*)(cmd)++)
32-
3319
/**
3420
* @brief Array of pointers to command defining
3521
* a set of command. Created while calling
@@ -47,12 +33,10 @@ static esp_commands_config_t s_config;
4733
static char *s_tmp_line_buf;
4834

4935
/**
50-
* @brief find a command by its name in the list of registered
51-
* commands
52-
*
53-
* @param name name of the command to find
54-
* @return esp_command_t* pointer to the command matching the command
55-
* name, NULL if the command is not found
36+
* @brief go through all commands registered in the
37+
* memory section starting at _esp_commands_start
38+
* and ending at _esp_commands_end OR go through all
39+
* the commands listed in cmd_set if not NULL
5640
*/
5741
#define FOR_EACH_COMMAND(cmd_set, cmd) \
5842
for (size_t _i = 0; \
@@ -63,29 +47,35 @@ static char *s_tmp_line_buf;
6347
_i < (cmd_set)->cmd_set_size)); \
6448
++_i)
6549

50+
/**
51+
* @brief returns the number of commands registered
52+
* in the .esp_commands section
53+
*/
54+
#define ESP_COMMANDS_COUNT (size_t)(&_esp_commands_end - &_esp_commands_start)
55+
6656
/**
6757
* @brief find a command by its name in the list of registered
68-
* commands
58+
* commands or in a command set if the parameter cmd_set is set.
6959
*
60+
* @note If cmd_set is set to NULL by the caller, then the function
61+
* will try to find a command by name from the list of registered
62+
* commands in the .esp_commands section
63+
*
64+
* @param cmd_set command set to find a command from
7065
* @param name name of the command to find
7166
* @return esp_command_t* pointer to the command matching the command
7267
* name, NULL if the command is not found
7368
*/
74-
static esp_command_t *find_command_by_name_in_set(esp_command_set_t *cmd_set, const char *name)
69+
static esp_command_t *find_command_by_name(esp_command_set_t *cmd_set, const char *name)
7570
{
7671
/* no need to check that cmd_set is NULL, if it is, then FOR_EACH_COMMAND will go through
7772
* the commands registered in the .esp_commands section */
7873
if (!name) {
7974
return NULL;
8075
}
8176
esp_command_t *cmd = NULL;
82-
FOR_EACH_COMMAND_IN_SET(cmd, cmd_set) {
83-
if (!cmd) {
84-
/* this happens if a command name passed in a set was not found,
85-
* the pointer to command is set to NULL */
86-
continue;
87-
}
88-
if (strcmp(cmd->command, name) == 0) {
77+
FOR_EACH_COMMAND(cmd_set, cmd) {
78+
if (strcmp(cmd->name, name) == 0) {
8979
return cmd;
9080
}
9181
}
@@ -131,8 +121,8 @@ esp_err_t esp_commands_execute(esp_command_set_handle_t cmd_set, const char *cmd
131121
}
132122
strlcpy(s_tmp_line_buf, cmdline, s_config.max_cmdline_length);
133123

134-
size_t argc = esp_console_split_argv(s_tmp_line_buf, argv,
135-
s_config.max_cmdline_args);
124+
size_t argc = esp_commands_split_argv(s_tmp_line_buf, argv,
125+
s_config.max_cmdline_args);
136126
if (argc == 0) {
137127
free(argv);
138128
return ESP_ERR_INVALID_ARG;
@@ -143,7 +133,7 @@ esp_err_t esp_commands_execute(esp_command_set_handle_t cmd_set, const char *cmd
143133
bool is_cmd_help = false;
144134
if (strcmp("help", argv[0]) == 0) {
145135
/* find the help command in the list in .esp_commands section */
146-
cmd = find_command_by_name((esp_command_set_t*)NULL, "help");
136+
cmd = find_command_by_name((esp_command_set_t *)NULL, "help");
147137
is_cmd_help = true;
148138
} else {
149139
cmd = find_command_by_name(cmd_set, argv[0]);
@@ -161,13 +151,115 @@ esp_err_t esp_commands_execute(esp_command_set_handle_t cmd_set, const char *cmd
161151
// executing help command, pass the cmd_set as context
162152
*cmd_ret = (*cmd->func_w_ctx)(cmd_set, argc, argv);
163153
} else {
164-
*cmd_ret = (*cmd->func_w_context)(cmd->context, argc, argv);
154+
*cmd_ret = (*cmd->func_w_ctx)(cmd->func_ctx, argc, argv);
165155
}
166156
}
167157
free(argv);
168158
return ESP_OK;
169159
}
170160

161+
esp_command_set_handle_t esp_commands_create_cmd_set(const char **cmd_set, const size_t cmd_set_size, esp_commands_get_field_t get_field)
162+
{
163+
if (!cmd_set || cmd_set_size == 0) {
164+
return NULL;
165+
}
166+
167+
esp_command_set_t *cmd_ptr_set = heap_caps_malloc(sizeof(esp_command_set_t), s_config.heap_alloc_caps);
168+
if (!cmd_ptr_set) {
169+
return NULL;
170+
}
171+
172+
esp_command_t *cmd_ptrs_temp[ESP_COMMANDS_COUNT];
173+
size_t cmd_ptr_count = 0;
174+
175+
/* populate the temporary cmd pointer set */
176+
for (size_t i = 0; i < cmd_set_size; i++) {
177+
esp_command_t *it = NULL;
178+
FOR_EACH_COMMAND((esp_command_set_t *)NULL, it) {
179+
if (strcmp(get_field(it), cmd_set[i]) == 0) {
180+
// it's a match, add the pointer to command to the cmd ptr set
181+
cmd_ptrs_temp[cmd_ptr_count] = it;
182+
cmd_ptr_count++;
183+
continue;
184+
}
185+
}
186+
}
187+
188+
/* if no command was found, return a set with 0 items in it */
189+
if (cmd_ptr_count == 0) {
190+
cmd_ptr_set->cmd_ptr_set = NULL;
191+
cmd_ptr_set->cmd_set_size = 0;
192+
} else {
193+
const size_t alloc_cmd_ptrs_size = sizeof(esp_command_t *) * cmd_ptr_count;
194+
cmd_ptr_set->cmd_ptr_set = heap_caps_malloc(alloc_cmd_ptrs_size, s_config.heap_alloc_caps);
195+
if (!cmd_ptr_set->cmd_ptr_set) {
196+
heap_caps_free(cmd_ptr_set);
197+
cmd_ptr_set = NULL;
198+
} else {
199+
/* copy the temp set of pointer in to the final destination */
200+
memcpy(cmd_ptr_set->cmd_ptr_set, cmd_ptrs_temp, alloc_cmd_ptrs_size);
201+
cmd_ptr_set->cmd_set_size = cmd_ptr_count;
202+
}
203+
}
204+
205+
return (esp_command_set_handle_t)cmd_ptr_set;
206+
}
207+
208+
esp_command_set_handle_t esp_commands_concat_cmd_set(esp_command_set_handle_t cmd_set_a, esp_command_set_handle_t cmd_set_b)
209+
{
210+
if (!cmd_set_a && !cmd_set_b) {
211+
return NULL;
212+
} else if (cmd_set_a && !cmd_set_b) {
213+
return cmd_set_a;
214+
} else if (!cmd_set_a && cmd_set_b) {
215+
return cmd_set_b;
216+
}
217+
218+
/* Reaching this point, both cmd_set_a and cmd_set_b are set.
219+
* Create a new cmd_set that can host the items from both sets,
220+
* assign the items to the new set and free the input sets */
221+
const size_t new_set_size = cmd_set_a->cmd_set_size + cmd_set_b->cmd_set_size;
222+
esp_command_set_t *concat_cmd_set = heap_caps_malloc(sizeof(esp_command_set_t), s_config.heap_alloc_caps);
223+
if (!concat_cmd_set) {
224+
return NULL;
225+
}
226+
concat_cmd_set->cmd_ptr_set = heap_caps_calloc(new_set_size, sizeof(esp_command_t *), s_config.heap_alloc_caps);
227+
if (!concat_cmd_set->cmd_ptr_set) {
228+
heap_caps_free(concat_cmd_set);
229+
return NULL;
230+
}
231+
232+
/* update the new cmd set size*/
233+
concat_cmd_set->cmd_set_size = new_set_size;
234+
235+
/* fill the list of command pointers */
236+
memcpy(concat_cmd_set->cmd_ptr_set,
237+
cmd_set_a->cmd_ptr_set,
238+
sizeof(esp_command_t *) * cmd_set_a->cmd_set_size);
239+
memcpy(concat_cmd_set->cmd_ptr_set + cmd_set_a->cmd_set_size,
240+
cmd_set_b->cmd_ptr_set,
241+
sizeof(esp_command_t *) * cmd_set_b->cmd_set_size);
242+
243+
esp_commands_destroy_cmd_set(&cmd_set_a);
244+
esp_commands_destroy_cmd_set(&cmd_set_b);
245+
246+
return (esp_command_set_handle_t)concat_cmd_set;
247+
}
248+
249+
void esp_commands_destroy_cmd_set(esp_command_set_handle_t *cmd_set)
250+
{
251+
if (!cmd_set || !*cmd_set) {
252+
return;
253+
}
254+
255+
if ((*cmd_set)->cmd_ptr_set) {
256+
heap_caps_free((*cmd_set)->cmd_ptr_set);
257+
}
258+
259+
heap_caps_free(*cmd_set);
260+
*cmd_set = NULL;
261+
}
262+
171263
void esp_commands_get_completion(esp_command_set_handle_t cmd_set, const char *buf, esp_command_get_completion_t completion_cb)
172264
{
173265
size_t len = strlen(buf);
@@ -201,6 +293,7 @@ const char *esp_commands_get_hint(esp_command_set_handle_t cmd_set, const char *
201293
return NULL;
202294
}
203295

296+
<<<<<<< HEAD
204297
esp_command_set_handle_t esp_commands_create_cmd_set(const char **cmd_set, const size_t cmd_set_size, esp_commands_get_field_t get_field)
205298
{
206299
if (!cmd_set || cmd_set_size == 0) {
@@ -304,6 +397,8 @@ void esp_commands_destroy_cmd_set(esp_command_set_handle_t *cmd_set)
304397
free(*cmd_set);
305398
*cmd_set = NULL;
306399
}
400+
=======
401+
>>>>>>> 7bb19c4 (feat(esp_commands): Add tests to the esp_commands component)
307402

308403
/* -------------------------------------------------------------- */
309404
/* help command related code */
@@ -314,25 +409,25 @@ static void print_arg_help(esp_command_t *it)
314409
/* First line: command name and hint
315410
* Pad all the hints to the same column
316411
*/
317-
printf("%-s", it->command);
318-
if (it->get_hint_cb) {
319-
printf(" %s\n", it->get_hint_cb());
412+
printf("%-s", it->name);
413+
if (it->hint_cb) {
414+
printf(" %s\n", it->hint_cb());
320415
} else {
321416
printf("\n");
322417
}
323418

324419
/* Second line: print help */
325420
/* TODO: replace the simple print with a function that
326421
* replaces arg_print_formatted */
327-
if (it->get_help_cb) {
328-
printf(" %s\n", it->get_help_cb());
422+
if (it->help) {
423+
printf(" %s\n", it->help);
329424
} else {
330425
printf(" -\n");
331426
}
332427

333428
/* Third line: print the glossary*/
334-
if (it->get_glossary_cb) {
335-
printf("%s\n", it->get_glossary_cb());
429+
if (it->glossary_cb) {
430+
printf("%s\n", it->glossary_cb());
336431
} else {
337432
printf(" -\n");
338433
}
@@ -342,9 +437,9 @@ static void print_arg_help(esp_command_t *it)
342437

343438
static void print_arg_command(esp_command_t *it)
344439
{
345-
printf("%-s", it->command);
346-
if (it->get_hint_cb) {
347-
printf(" %s\n", it->get_hint_cb());
440+
printf("%-s", it->name);
441+
if (it->hint_cb) {
442+
printf(" %s\n", it->hint_cb());
348443
}
349444
}
350445

@@ -414,21 +509,21 @@ static int help_command(void *context, int argc, char **argv)
414509
* is not NULL, find the command and only print the help for this command. if the
415510
* command is not found, return with error */
416511
bool command_found = false;
417-
for (size_t i = 0; i < cmd_set->cmd_set_size; i++) {
418-
419-
if (!cmd_set->cmd_ptr_set[i]) {
512+
esp_command_t *it = NULL;
513+
FOR_EACH_COMMAND(cmd_set, it) {
514+
if (!it) {
420515
/* this happens if a command name passed in a set was not found,
421516
* the pointer to command is set to NULL */
422517
continue;
423518
}
424519

425520
if (!command_name) {
426521
/* command_name is empty, print all commands */
427-
print_verbose_level_arr[verbose_level](cmd_set->cmd_ptr_set[i]);
522+
print_verbose_level_arr[verbose_level](it);
428523
} else if (command_name &&
429-
(strcmp(command_name, cmd_set->cmd_ptr_set[i]->command) == 0)) {
524+
(strcmp(command_name, it->name) == 0)) {
430525
/* we found the command name, print the help and return */
431-
print_verbose_level_arr[verbose_level](cmd_set->cmd_ptr_set[i]);
526+
print_verbose_level_arr[verbose_level](it);
432527
command_found = true;
433528
break;
434529
}
@@ -453,11 +548,14 @@ static const char *get_help_glossary(void)
453548
" -v, --verbose <0|1> If specified, list console commands with given verbose level";;
454549
}
455550

456-
ESP_COMMAND_REGISTER(help,
457-
NULL, /* the help should be a part of all set, it does not need a group name */
458-
"Print the summary of all registered commands if no arguments "
459-
"are given, otherwise print summary of given command.",
460-
&help_command,
551+
static const char help_str[] = "Print the summary of all registered commands if no arguments "
552+
"are given, otherwise print summary of given command.";
553+
554+
ESP_COMMAND_REGISTER(help, /* name of the heap command */
555+
help, /* group of the help command */
556+
help_str, /* help string of the help command */
557+
NULL, /* func (null since func with context is used) */
558+
help_command, /* func_w_ctx */
461559
NULL, /* the context is null here, it will provided by the exec function */
462-
get_help_hint,
463-
get_help_glossary);
560+
get_help_hint, /* hint callback */
561+
get_help_glossary); /* glossary callback */

esp_commands/esp_commands_helpers.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ typedef enum {
3232
state = SS_SPACE; \
3333
} while(0)
3434

35-
size_t esp_console_split_argv(char *line, char **argv, size_t argv_size)
35+
size_t esp_commands_split_argv(char *line, char **argv, size_t argv_size)
3636
{
3737
const int QUOTE = '"';
3838
const int ESCAPE = '\\';

0 commit comments

Comments
 (0)