Skip to content

Commit ac29f9b

Browse files
committed
Fixing Progmem support on AVR
Todo: progmem support on esp8266
1 parent a191084 commit ac29f9b

File tree

6 files changed

+57
-119
lines changed

6 files changed

+57
-119
lines changed

.vscode/settings.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
"xlocale": "cpp",
1313
"ios": "cpp",
1414
"xmemory": "cpp",
15-
"system_error": "cpp"
15+
"system_error": "cpp",
16+
"typeinfo": "cpp"
1617
},
1718
"C_Cpp.errorSquiggles": "disabled"
1819
}

extras/examples_desktop/Desktop/Memory/Memory.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ int main(){
200200
int num_of_hints;
201201
int i;
202202

203-
num_of_hints = commander.generateHint( "cat --reboot ", buffer, buffer_size );
203+
num_of_hints = commander.generateHint( "cat --reboot", buffer, buffer_size );
204204
stdioChannel.print( "number of hints: " );
205205
stdioChannel.println( num_of_hints );
206206
for( i = 0; i < num_of_hints; i++ ){

src/Commander-API.cpp

Lines changed: 27 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -181,38 +181,23 @@ bool Commander::executeCommand( const char *cmd ){
181181
// If show_description flag is set, than we have to print the description.
182182
if( show_description ){
183183

184-
if( memoryType == MEMORY_REGULAR ){
185-
186-
//if( caller -> channel != NULL ){
187-
188-
// Print the description text to the output channel.
189-
caller -> print( commandData_ptr -> name );
190-
caller -> print( ':' );
191-
caller -> print( ' ' );
192-
caller -> println( commandData_ptr -> data.desc );
193-
194-
//}
195-
196-
}
197-
198-
#ifdef __AVR__
199-
200-
else if( memoryType == MEMORY_PROGMEM ){
201-
202-
//if( response != NULL ){
203-
204-
// Print the description text to the output channel.
205-
caller -> print( commandData_ptr -> name_P );
206-
caller -> print( ':' );
207-
caller -> print( ' ' );
208-
caller -> println( commandData_ptr -> data.desc_P );
209-
210-
//}
211-
212-
}
213-
214-
#endif
215-
184+
#ifdef __AVR__
185+
caller -> print( commandData_ptr -> name );
186+
caller -> print( ':' );
187+
caller -> print( ' ' );
188+
if( commandData_ptr -> data.desc ){
189+
caller -> print( commandData_ptr -> data.desc );
190+
}
191+
else if( commandData_ptr -> data.desc_P ){
192+
caller -> print( commandData_ptr -> data.desc_P );
193+
}
194+
caller -> println();
195+
#else
196+
caller -> print( commandData_ptr -> name );
197+
caller -> print( ':' );
198+
caller -> print( ' ' );
199+
caller -> println( commandData_ptr -> data.desc );
200+
#endif
216201

217202
}
218203

@@ -475,15 +460,8 @@ void Commander::printHelp( Stream* out, bool description, bool style ){
475460
out -> print( __CONST_TXT__( "\033[1;32m" ) );
476461
}
477462

478-
if( memoryType == MEMORY_REGULAR ){
479-
//out -> print( API_tree[ find_api_index_by_place( i ) ].name );
480-
out -> print( regularCommands[ regularCommands.findIndexByPlace( i ) ] -> name );
481-
}
482-
#ifdef __AVR__
483-
else if( memoryType == MEMORY_PROGMEM ){
484-
out -> print( regularCommands[ regularCommands.findIndexByPlace( i ) ] -> name_P );
485-
}
486-
#endif
463+
//out -> print( API_tree[ find_api_index_by_place( i ) ].name );
464+
out -> print( regularCommands[ regularCommands.findIndexByPlace( i ) ] -> name );
487465

488466
if( style ){
489467
out -> print( __CONST_TXT__( "\033[0;37m" ) );
@@ -497,13 +475,15 @@ void Commander::printHelp( Stream* out, bool description, bool style ){
497475

498476
out -> print( __CONST_TXT__( ": " ) );
499477

500-
if( memoryType == MEMORY_REGULAR ){
501-
out -> print( regularCommands[ regularCommands.findIndexByPlace( i ) ] -> data.desc );
502-
}
503478
#ifdef __AVR__
504-
else if( memoryType == MEMORY_PROGMEM ){
505-
out -> print( regularCommands[ regularCommands.findIndexByPlace( i ) ] -> data.desc_P );
506-
}
479+
if( regularCommands[ regularCommands.findIndexByPlace( i ) ] -> data.desc ){
480+
out -> print( regularCommands[ regularCommands.findIndexByPlace( i ) ] -> data.desc );
481+
}
482+
else if( regularCommands[ regularCommands.findIndexByPlace( i ) ] -> data.desc_P ){
483+
out -> print( regularCommands[ regularCommands.findIndexByPlace( i ) ] -> data.desc_P );
484+
}
485+
#else
486+
out -> print( regularCommands[ regularCommands.findIndexByPlace( i ) ] -> data.desc );
507487
#endif
508488

509489
out -> println();
@@ -572,25 +552,6 @@ int Commander::hasChar( const char* str, char c, int number, bool ignoreString )
572552

573553
}
574554

575-
/*
576-
#ifdef __AVR__
577-
578-
int Commander::commander_strcmp_progmem( API_t* element1, API_t* element2 ){
579-
580-
strncpy_P( progmemBuffer, ( PGM_P ) element1 -> name_P, COMMANDER_MAX_COMMAND_SIZE );
581-
return strcmp_P( progmemBuffer, ( PGM_P )element2 -> name_P );
582-
583-
}
584-
585-
int Commander::commander_strcmp_tree_ram_progmem( API_t* element1, const char* element2 ){
586-
587-
return strcmp_P( element2, (PGM_P)element1 -> name_P ) * -1;
588-
589-
}
590-
591-
#endif
592-
*/
593-
594555
void Commander::enableFormatting(){
595556
formatting = true;
596557
}

src/Commander-API.hpp

Lines changed: 15 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -99,14 +99,24 @@ SOFTWARE.
9999
/// @param name The name of the command. The best practice is to use a const char array.
100100
/// @param desc The description of the command. The best practice is to use a const char array.
101101
/// @param func_arg This function will be called, when this command gets executed.
102-
#define systemCommand_P( element, name_p, desc_p, func_P ) { element.place = 0; \
102+
#define systemCommand_P( element, name_p, desc_progmem, func_p ) { element.place = 0; \
103103
element.left = NULL; \
104104
element.right = NULL; \
105-
element.name_p = __CONST_TXT__( name ); \
106-
element.data.desc_P = __CONST_TXT__( desc ); \
107-
element.data.func_p = func; \
105+
element.name = name_p; \
106+
element.data.desc = NULL; \
107+
element.data.desc_P = __CONST_TXT__( desc_progmem ); \
108+
element.data.func = func_p; \
108109
}
109-
//#define apiElement_P( element, name, desc, func_arg ) { element.name_P = __CONST_TXT__( name ); element.desc_P = __CONST_TXT__( desc ); element.func = func_arg; }
110+
111+
#else
112+
#define systemCommand_P( element, name_p, desc_progmem, func_p ) { element.place = 0; \
113+
element.left = NULL; \
114+
element.right = NULL; \
115+
element.name = name_p; \
116+
element.data.desc = __CONST_TXT__( desc_progmem ); \
117+
element.data.func = func_p; \
118+
}
119+
110120

111121
#endif
112122

@@ -249,14 +259,6 @@ class Commander{
249259

250260
typedef CommanderDatabase<systemVariableData_t>::dataRecord_t systemVariable_t;
251261

252-
enum memoryType_t{
253-
MEMORY_REGULAR, ///< Regular memory implementation
254-
MEMORY_PROGMEM ///< Progmem memory implementation
255-
};
256-
257-
/// Flag for memory type.
258-
memoryType_t memoryType = MEMORY_REGULAR;
259-
260262
/// Attach API-tree to the object.
261263
///
262264
/// With this function you can attach the API-tree
@@ -436,32 +438,6 @@ class Commander{
436438

437439
bool formatting = false;
438440

439-
#ifdef __AVR__
440-
441-
/// With the PROGMEM implementation we need to copy the
442-
/// data from the PROGMEM area to a buffer for compersation.
443-
char progmemBuffer[ COMMANDER_MAX_COMMAND_SIZE + 1 ];
444-
445-
/// Compare two API-tree element's name.
446-
///
447-
/// It compares two API-tree element's name like a regular strcmp.
448-
/// It compares the names stored in the name_P
449-
/// variable. This names are stored in PROGMEM space.
450-
/// @param element1 Pointer to an API-tree element.
451-
/// @param element2 Pointer to an API-tree element.
452-
/// @returns Returns an int value indicating the [relationship](https://cplusplus.com/reference/cstring/strcmp/) between the strings.
453-
int commander_strcmp_progmem( API_t* element1, API_t* element2 );
454-
455-
/// Compare an API-tree element's name with a regular string.
456-
///
457-
/// It compares an API-tree element's name with a regular string like a regular strcmp.
458-
/// @param element1 Pointer to an API-tree element.
459-
/// @param element2 Character array.
460-
/// @returns Returns an int value indicating the [relationship](https://cplusplus.com/reference/cstring/strcmp/) between the strings.
461-
int commander_strcmp_tree_ram_progmem( API_t* element1, const char* element2 );
462-
463-
#endif
464-
465441
/// Flag to enable or disable debug messages.
466442
static debugLevel_t debugLevel;
467443

src/Commander-Autocomplete.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,11 @@ SOFTWARE.
3737
#include <stdint.h>
3838
#include <string.h>
3939

40+
/*
4041
#include <wchar.h>
4142
#include <stdlib.h>
4243
#include <locale.h>
44+
*/
4345

4446
#define AUTOCOMPLETE_RESULT_SIZE 10
4547

src/Commander-Database.hpp

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,6 @@ class CommanderDatabase{
7676

7777
T data; ///< Stored data. It comes from the template, so it can be any type of data.
7878

79-
#ifdef __AVR__
80-
__FlashStringHelper *name_P; ///< Name of the element( stored in PROGMEM )
81-
#endif
82-
8379
};
8480

8581
/// Empty constructor.
@@ -159,7 +155,7 @@ class CommanderDatabase{
159155

160156
int completeFragment( const char* fragment, char* buffer, int buffer_size );
161157

162-
private:
158+
protected:
163159
/// Starting address of the API-tree.
164160
dataRecord_t* dataTree = NULL;
165161

@@ -223,7 +219,11 @@ CommanderDatabase< T >::CommanderDatabase(){
223219
debugChannel = NULL;
224220
debugLevel = DEBUG_OFF;
225221
initFlag = false;
222+
strcmpElementElement = &CommanderDatabase::strcmpElementElementRegular;
223+
strcmpElementCharArray = &CommanderDatabase::strcmpElementCharArrayRegular;
226224

225+
strncmpElementElement = &CommanderDatabase::strncmpElementElementRegular;
226+
strncmpElementCharArray = &CommanderDatabase::strncmpElementCharArrayRegular;
227227
}
228228

229229
template< typename T >
@@ -234,7 +234,11 @@ CommanderDatabase< T >::CommanderDatabase( struct dataRecord_t* dataTree_p, uint
234234
debugChannel = NULL;
235235
debugLevel = DEBUG_OFF;
236236
initFlag = false;
237+
strcmpElementElement = &CommanderDatabase::strcmpElementElementRegular;
238+
strcmpElementCharArray = &CommanderDatabase::strcmpElementCharArrayRegular;
237239

240+
strncmpElementElement = &CommanderDatabase::strncmpElementElementRegular;
241+
strncmpElementCharArray = &CommanderDatabase::strncmpElementCharArrayRegular;
238242
}
239243

240244
template< typename T >
@@ -497,12 +501,6 @@ bool CommanderDatabase< T >::init(){
497501
bool swapped;
498502
int compareResult;
499503

500-
strcmpElementElement = &CommanderDatabase::strcmpElementElementRegular;
501-
strcmpElementCharArray = &CommanderDatabase::strcmpElementCharArrayRegular;
502-
503-
strncmpElementElement = &CommanderDatabase::strncmpElementElementRegular;
504-
strncmpElementCharArray = &CommanderDatabase::strncmpElementCharArrayRegular;
505-
506504
if( ( debugChannel != NULL ) && ( debugLevel >= DEBUG_DEBUG ) ){
507505
debugChannel -> println( __CONST_TXT__( "Database init start" ) );
508506
debugChannel -> println( __CONST_TXT__( "Creating alphabetical order..." ) );
@@ -732,7 +730,7 @@ int CommanderDatabase< T >::completeFragment( const char* fragment, char* buffer
732730

733731
fragment_len = strlen( fragment );
734732

735-
// Thee roo node will be the first element.
733+
// Thee root node will be the first element.
736734
prev = &dataTree[ 0 ];
737735

738736
comp_res = ( this ->* strncmpElementCharArray )( prev, fragment, fragment_len );

0 commit comments

Comments
 (0)