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 */
1516extern esp_command_t _esp_commands_start ;
1617extern 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;
4733static 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+
171263void 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
204297esp_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+ >>>>>>> 7bb 19 c4 (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
343438static 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 */
0 commit comments