Skip to content

Commit 69743c8

Browse files
committed
Arduino compatibility
* File headers are fixed. * Now compatible with Arduino env. * Configuration in separate file
1 parent 65016f3 commit 69743c8

File tree

5 files changed

+573
-125
lines changed

5 files changed

+573
-125
lines changed

src/commander.cpp

Lines changed: 98 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,37 @@
11
/*
2-
* commander.cpp
2+
* Created on June 18 2020
33
*
4-
* Created on: Feb 5, 2022
5-
* Author: dani0
6-
*/
4+
* Copyright (c) 2020 - Daniel Hajnal
5+
6+
* This file is part of the Commander-API project.
7+
* Modified 2022.02.06
8+
*/
79

810
#include "commander.hpp"
911

1012

1113
void Commander::attachTreeFunction( API_t *API_tree_p, uint32_t API_tree_size_p ){
1214

15+
// Save parameters to internal variables.
1316
API_tree = API_tree_p;
1417
API_tree_size = API_tree_size_p;
1518

1619
}
1720

18-
void Commander::attachDebugPort( Serial *debugPort_p ){
19-
20-
debugPort = debugPort_p;
21-
22-
}
23-
2421
void Commander::init(){
2522

23+
// Generic conter variables.
2624
uint32_t i;
2725
uint32_t j;
2826

27+
// Temporary variable, used to flip elements.
2928
API_t temp;
3029

31-
if( debugPort ){
32-
33-
debugPort -> println( "Rendezes elott:" );
34-
for( i = 0; i < API_tree_size; i++ ){
35-
36-
debugPort -> printf( "%d. %s\r\n", i, API_tree[ i ].name );
37-
38-
}
39-
debugPort -> println();
40-
41-
}
42-
43-
// Nev szerint sorba rendezzuk a parancsokat.
30+
// Make the tree ordered by alphabet.
4431
for( i = 0; i < API_tree_size; i++ ){
4532

4633
for( j = i + 1; j < API_tree_size; j++ ){
4734

48-
//if( API_tree[ i ] > API_tree[ j ] ){
4935
if( strcmp( API_tree[ i ].name, API_tree[ j ].name ) > 0 ){
5036

5137
temp = API_tree[ i ];
@@ -58,40 +44,18 @@ void Commander::init(){
5844

5945
}
6046

61-
if( debugPort ){
62-
63-
debugPort -> println( "Rendezes utan:" );
64-
for( i = 0; i < API_tree_size; i++ ){
65-
66-
debugPort -> printf( "%d. %s\r\n", i, API_tree[ i ].name );
67-
68-
}
69-
debugPort -> println();
70-
71-
}
72-
73-
// Elmentjuk a nevsorrend szerinti helyet a place valtozoba.
47+
// Fill the place variable in the tree with
48+
// correct alphabetical place.
7449
for( i = 0; i < API_tree_size; i++ ){
7550

7651
API_tree[ i ].place = i;
7752

7853
}
7954

80-
// Optimalizaljuk a sorrendet.
81-
optimise_api_tree();
82-
83-
if( debugPort ){
84-
85-
debugPort -> println( "Optimalizalas utan:" );
86-
for( i = 0; i < API_tree_size; i++ ){
87-
88-
debugPort -> printf( "%d. %s\r\n", i, API_tree[ i ].name );
89-
90-
}
91-
debugPort -> println();
92-
93-
}
94-
55+
// Optimize the tree to make it balanced.
56+
// It is necessary to speed up the command
57+
// search phase.
58+
optimize_api_tree();
9559

9660
}
9761

@@ -113,14 +77,13 @@ uint16_t Commander::find_api_index_by_place( uint16_t place ){
11377

11478
}
11579

116-
// else return 0
11780
return 0;
11881

11982
}
12083

12184
void Commander::swap_api_elements( uint16_t index, uint16_t place ){
12285

123-
// Buffer that will temporarly hold an element.
86+
// Buffer that will temporary hold an element.
12487
// This is required for a swap.
12588
API_t buffer;
12689

@@ -141,7 +104,7 @@ void Commander::swap_api_elements( uint16_t index, uint16_t place ){
141104

142105
}
143106

144-
void Commander::optimise_api_tree(){
107+
void Commander::optimize_api_tree(){
145108

146109
uint32_t i;
147110

@@ -153,19 +116,19 @@ void Commander::optimise_api_tree(){
153116
// Stores the previous elements address in the tree
154117
API_t *prev;
155118

156-
// It will store string compersation result
119+
// It will store string comparison result
157120
int32_t comp_res;
158121

159-
// recursive optimiser need to initialise 'API_cntr' to 0
122+
// recursive optimizer need to initialize elementCounter to 0
160123
elementCounter = 0;
161124

162125
// recursively finds the order which is optimal for a balanced tree
163-
recursive_optimiser( 0, API_tree_size - 1 );
126+
recursive_optimizer( 0, API_tree_size - 1 );
164127

165128
// The order is good, but the connection between the branches broken,
166129
// because we swapped the API_tree array elements.
167-
// To fix this problem we have to reinitialise the tree, and use
168-
// 'add_interpreter_command' function again for all elements.
130+
// To fix this problem we have to add elements from index 1 and
131+
// place them in the binary tree.
169132
for( i = 1; i < API_tree_size; i++ ){
170133

171134
prev = &API_tree[ 0 ];
@@ -187,37 +150,36 @@ void Commander::optimise_api_tree(){
187150

188151
}
189152

190-
// This function is used to order the elements in API_tree array to
191-
// get the fastest search speed
192-
// this function needs 'API_cntr' to be zeroed out before the first call
193-
void Commander::recursive_optimiser( int32_t start_index, int32_t stop_index ){
153+
void Commander::recursive_optimizer( int32_t start_index, int32_t stop_index ){
194154

195-
int32_t mid;
155+
// The middle number between start and stop index
156+
// will be stored in this variable.
157+
int32_t mid;
196158

197-
// End of recursive algorythm
198-
if( start_index > stop_index ){
159+
// Detect the end of recursion.
160+
if( start_index > stop_index ){
199161

200-
return;
162+
return;
201163

202-
}
164+
}
203165

204-
// Find the middle of the intervall
205-
mid = ( start_index + stop_index ) / 2;
166+
// Find the middle of the interval
167+
mid = ( start_index + stop_index ) / 2;
206168

207-
// Put the right element to it's place
208-
swap_api_elements( elementCounter, mid );
209-
elementCounter++;
169+
// Put the right element to it's place
170+
swap_api_elements( elementCounter, mid );
171+
elementCounter++;
210172

211-
// Do some recursion for the other intervalls
212-
recursive_optimiser( start_index, mid - 1 );
213-
recursive_optimiser( mid + 1, stop_index );
173+
// Do some recursion for the other intervals
174+
recursive_optimizer( start_index, mid - 1 );
175+
recursive_optimizer( mid + 1, stop_index );
214176

215177

216178
}
217179

218180
void Commander::executeCommand( char *cmd ){
219181

220-
// The begining of the argument list will be stored in this pointer
182+
// The beginning of the argument list will be stored in this pointer
221183
char *arg;
222184

223185
// This variable tracks the command name length
@@ -227,8 +189,13 @@ void Commander::executeCommand( char *cmd ){
227189
// and the commands function won't be called.
228190
uint8_t show_description = 0;
229191

192+
// Pointer to the selected command data.
230193
API_t *commandData_ptr;
231194

195+
// Copy the command data to the internal buffer.
196+
// It is necessary because we have to modify the content
197+
// of it. If it is points to a const char array we will
198+
// get a bus-fault error without a buffer.
232199
strncpy( tempBuff, cmd, COMMANDER_MAX_COMMAND_SIZE );
233200

234201

@@ -240,7 +207,7 @@ void Commander::executeCommand( char *cmd ){
240207
// Reset the name counter before we start counting
241208
cmd_name_cntr = 0;
242209

243-
// Find the first space character or a string-end character.
210+
// Find the first space, question mark or a string-end character.
244211
// At this time count how long is the command name( in characters )
245212
while( ( *arg != '\0' ) && ( *arg != ' ' ) && ( *arg != '?' ) ){
246213

@@ -252,14 +219,6 @@ void Commander::executeCommand( char *cmd ){
252219
// If a space character found we have to terminate the string there.
253220
// It is important because strcmp function will search for string terminator
254221
// character, and this way we can separate the command name from its arguments.
255-
// This method has a downside. If we pass a const char as command
256-
// to the execution function it will try to overwrite a character in it.
257-
// It is impossible if the input string is constant and it will result hard fault!
258-
// To prevent this we nead a buffer. This is why INTERPRETER_BUFFER_SIZE macro has
259-
// been created. If you want to pass const chars to your interpreter directly, you
260-
// have to define INTERPRETER_BUFFER_SIZE with a resonable size.
261-
// But if you can prove it, that there is no chace in your program to use const chars,
262-
// you can comment out INTERPRETER_BUFFER_SIZE macro. This can save some space in your RAM.
263222
if( *arg == ' ' ){
264223

265224
*arg = '\0';
@@ -277,9 +236,10 @@ void Commander::executeCommand( char *cmd ){
277236

278237
}
279238

280-
// Megnézzük, hogy a parancs létezik-e.
239+
// Try to find the command datata.
281240
commandData_ptr = (*this)[ tempBuff ];
282241

242+
// If it is not a NULL pointer, that means we have a mtach.
283243
if( commandData_ptr ){
284244

285245
// Because we have found the command in the API tree we have to choose
@@ -288,7 +248,6 @@ void Commander::executeCommand( char *cmd ){
288248
if( show_description ){
289249

290250
// Print the description text to the output channel.
291-
292251
response -> printf( "%s: %s\r\n", commandData_ptr -> name, commandData_ptr -> desc );
293252

294253

@@ -316,22 +275,69 @@ void Commander::executeCommand( char *cmd ){
316275

317276
void Commander::execute( char *cmd ){
318277

278+
// Default execute handler, so the default response will be chosen.
319279
response = &defaultResponse;
280+
281+
// Execute the command.
320282
executeCommand( cmd );
321283

322284
}
323285

286+
#ifdef COMMANDER_USE_SERIAL_RESPONSE
287+
324288
void Commander::execute( char *cmd, Serial *resp ){
325289

326-
serialResponse.select( resp );
290+
// Serial execute handler, so the Serial response will be chosen.
327291
response = &serialResponse;
292+
293+
// Select the right Serial object in the response class.
294+
serialResponse.select( resp );
295+
296+
// Execute the command.
328297
executeCommand( cmd );
329298

330299
}
331300

301+
#endif
302+
303+
#ifdef COMMANDER_USE_ARDUINO_SERIAL_RESPONSE
304+
305+
void Commander::execute( char *cmd, HardwareSerial *resp ){
306+
307+
// Arduino Serial execute handler, so the Arduino Serial response will be chosen.
308+
response = &arduinoSerialResponse;
309+
310+
// Select the right HardwareSerial object in the response class.
311+
arduinoSerialResponse.select( resp );
312+
313+
// Execute the command.
314+
executeCommand( cmd );
315+
316+
}
317+
318+
#endif
319+
320+
#ifdef COMMANDER_USE_WIFI_CLIENT_RESPONSE
321+
322+
void Commander::execute( char *cmd, WiFiClient *resp ){
323+
324+
// Arduino Serial execute handler, so the Arduino Serial response will be chosen.
325+
response = &WiFiClientResponse;
326+
327+
// Select the right HardwareSerial object in the response class.
328+
WiFiClientResponse.select( resp );
329+
330+
// Execute the command.
331+
executeCommand( cmd );
332+
333+
}
334+
335+
#endif
336+
332337
Commander::API_t* Commander::operator [] ( int i ){
333338

334-
if( i < 0 ){
339+
// Detect wrong addressing.
340+
if( ( i < 0 ) || ( i >= (int)API_tree_size ) ){
335341

336342
return NULL;
337343

@@ -376,6 +382,7 @@ Commander::API_t* Commander::operator [] ( char* name ){
376382

377383
}
378384

385+
// If we did not found the command we return NULL.
379386
return NULL;
380387

381388
}
@@ -385,4 +392,3 @@ Commander::API_t* Commander::operator [] ( const char* name ){
385392
return (*this)[ (char*)name ];
386393

387394
}
388-

0 commit comments

Comments
 (0)