Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@

Try and adhere to the [kernel coding style](https://www.kernel.org/doc/html/latest/process/coding-style.html) with the exception of using 4 spaces instead of 8 for indentation.

The "astyle" code formatter and the library's ```formatter.conf``` configuration file do a pretty good job of correcting indentation, removing tabs etc.
The "astyle" code formatter and the library's ```formatter.conf``` configuration file do a pretty good job of correcting indentation, removing tabs etc. ("astyle" is the formatter the Arduino IDE uses when you select "Tools...Auto format".)

Tip: ```git diff --check``` will check your files and flag lines with trailing whitespace, and flag lines with tabs following spaces.

## Reporting Bugs

Expand Down
51 changes: 31 additions & 20 deletions examples/ArduinoTextInterface/MemoryUsageAVR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,20 @@ int MU_AVR::maxStackSize = getStackSize();
int MU_AVR::numStackComputeCalls = 0;

// print 1, 2 or 3 items on a line
#define PRINT1(a) shell.println((a));
#define PRINT2(a,b) shell.print((a)); shell.println((b));
#define PRINT3(a,b,c) shell.print((a)); shell.print((b)); shell.println((c));
void PRINT (const __FlashStringHelper *a, int b = -1, const __FlashStringHelper * c = NULL)
{
shell.print(a);
if (b != -1) {
shell.print(b);
shell.print(F(" (0x"));
shell.print(b,HEX);
shell.print(F(")"));
if (c) {
shell.print(c);
}
}
shell.println();
}

/// Modified function from http://www.avr-developers.com/mm/memoryusage.html
void MU_AVR::SRamDisplay(void)
Expand All @@ -32,23 +43,23 @@ void MU_AVR::SRamDisplay(void)

available -= data_size + bss_size + heap_size + stack_size;

PRINT3( F( "+----------------+ " ), getDataStart(), F(" (__data_start)"));
PRINT1( F( "+ data +" ));
PRINT2( F( "+ variables + size = " ), data_size);
PRINT3( F( "+----------------+ " ), (int)&__data_end, F(" (__data_end / __bss_start)"));
PRINT1( F( "+ bss +" ));
PRINT2( F( "+ variables + size = " ), bss_size);
PRINT3( F( "+----------------+ " ), (int)&__bss_end, F(" (__bss_end / __heap_start)"));
PRINT2( F( "+ heap + size = " ), heap_size);
PRINT3( F( "+----------------+ " ), (int)heap_end, F(" (__brkval if not 0, or __heap_start)"));
PRINT1( F( "+ +" ));
PRINT1( F( "+ +" ));
PRINT2( F( "+ FREE RAM + size = " ), available);
PRINT1( F( "+ +" ));
PRINT1( F( "+ +" ));
PRINT3( F( "+----------------+ " ), (int)SP, F(" (SP)"));
PRINT2( F( "+ stack + size = " ), stack_size);
PRINT3( F( "+----------------+ " ), (int)RAMEND, F(" (RAMEND / __stack)"));
PRINT( F( "+----------------+ " ), getDataStart(), F(" (__data_start)"));
PRINT( F( "+ data +" ));
PRINT( F( "+ variables + size = " ), data_size);
PRINT( F( "+----------------+ " ), (int)&__data_end, F(" (__data_end / __bss_start)"));
PRINT( F( "+ bss +" ));
PRINT( F( "+ variables + size = " ), bss_size);
PRINT( F( "+----------------+ " ), (int)&__bss_end, F(" (__bss_end / __heap_start)"));
PRINT( F( "+ heap + size = " ), heap_size);
PRINT( F( "+----------------+ " ), (int)heap_end, F(" (__brkval if not 0, or __heap_start)"));
PRINT( F( "+ +" ));
PRINT( F( "+ +" ));
PRINT( F( "+ FREE RAM + size = " ), available);
PRINT( F( "+ +" ));
PRINT( F( "+ +" ));
PRINT( F( "+----------------+ " ), (int)SP, F(" (SP)"));
PRINT( F( "+ stack + size = " ), stack_size);
PRINT( F( "+----------------+ " ), (int)RAMEND, F(" (RAMEND / __stack)"));
shell.println();
shell.println();
}
Expand Down
3 changes: 3 additions & 0 deletions examples/ArduinoTextInterface/memoryCommands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ void prettyPrintChars(int lineNo, const char *chars, int numChars)
for (int j = 0; j < numChars; j++) { // hex values
unsigned char b = chars[j];
shell.print(F(" "));
if(b < 0x10) {
shell.print(F("0"));
}
shell.print(b, HEX);
}
shell.print(F(" "));
Expand Down
61 changes: 53 additions & 8 deletions extras/tests/HelpTest/HelpTest.ino
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class HelpTest: public aunit::TestOnce {
}
};

int echo(int, char **)
int echo(int, char **)
{
return 0;
}
Expand All @@ -53,7 +53,7 @@ int echo(int, char **)

#define rangeCommandNameAndDocs F("range <lower> <upper>")

int rangeCommand(int, char **)
int rangeCommand(int, char **)
{
// simulates setting range (lower, upper)
return 0;
Expand All @@ -62,21 +62,66 @@ int rangeCommand(int, char **)
//////////////////////////////////////////////////////////////////////////////
// The goal of this test is to validate that the help messages
// return as expected.
testF(HelpTest, helpTest)
testF(HelpTest, helpTest)
{
const char* testCommand = "help\r";
terminal.pressKeys(testCommand);
assertTrue(shell.executeIfInput());

// The begining part of the response is the echo of the user's input.
assertEqual(terminal.getline(),
("help" NEW_LINE
HELP_PREAMBLE NEW_LINE
TWO_SPACE "echo" NEW_LINE
TWO_SPACE "help" NEW_LINE
assertEqual(terminal.getline(),
("help" NEW_LINE
HELP_PREAMBLE NEW_LINE
TWO_SPACE "echo" NEW_LINE
TWO_SPACE "help" NEW_LINE
TWO_SPACE "range <lower> <upper>" COMMAND_PROMPT));
}

//////////////////////////////////////////////////////////////////////////////
// The goal of this test is to check a bug (#28) that was introduced when using
// a command that starts off with another.
testF(HelpTest, helpTest2)
{
// Notice that this command text is a superset of the "range" command
terminal.pressKeys("ranger 1 2\r");
assertTrue(shell.executeIfInput());

// The begining part of the response is the echo of the user's input.
assertEqual(terminal.getline(),
("ranger 1 2" NEW_LINE
"\"ranger\": -1: command not found"
COMMAND_PROMPT));

// Notice that this command text is a subset of the "range" command
terminal.pressKeys("rang 1 2\r");
assertTrue(shell.executeIfInput());

// The begining part of the response is the echo of the user's input.
assertEqual(terminal.getline(),
("rang 1 2" NEW_LINE
"\"rang\": -1: command not found"
COMMAND_PROMPT));

// Now check the normal command
terminal.pressKeys("range 1 2\r");
assertTrue(shell.executeIfInput());

// The begining part of the response is the echo of the user's input.
assertEqual(terminal.getline(),
("range 1 2"
COMMAND_PROMPT));

// Now check the normal command, except show that the comparison is
// case-insensitive (per original implementation)
terminal.pressKeys("Range 1 2\r");
assertTrue(shell.executeIfInput());

// The begining part of the response is the echo of the user's input.
assertEqual(terminal.getline(),
("Range 1 2"
COMMAND_PROMPT));
}

//////////////////////////////////////////////////////////////////////////////
// ... so which sketch is this?
int showID(int /*argc*/ = 0, char ** /*argv*/ = NULL)
Expand Down
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=SimpleSerialShell
version=0.9.1
version=0.9.2

author=Phil Jansen
maintainer=Phil Jansen
Expand Down
4 changes: 4 additions & 0 deletions releaseNotes.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
Release notes

### v0.9.2
* #28 bug - use full command name (no partial matches)
* added example memory dump commands

### v0.9.1
* Ensure shell is a Singleton

Expand Down
27 changes: 13 additions & 14 deletions src/SimpleSerialShell.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@
*
*/

// The static instance of the singleton
// The static instance of the singleton
SimpleSerialShell SimpleSerialShell::theShell;

// A reference to the singleton shell in the global namespace. There is an
// extern definition of this in SimpleSherialShell.h, so all users of the
// class will have visibilty to this reference.
// A reference to the singleton shell in the global namespace. There is an
// extern definition of this in SimpleSherialShell.h, so all users of the
// class will have visibilty to this reference.
SimpleSerialShell& shell = SimpleSerialShell::theShell;

//
Expand Down Expand Up @@ -42,27 +42,26 @@ class SimpleSerialShell::Command {
};

int compareName(const char * aName) const
{
// Look for the command delimiter and make sure we don't
{
// Look for the command delimiter and make sure we don't
// consider anything beyond it in the comparison. There
// may be more documentation in the string.
//
// Note for future consideration: The temporary String here could
// be eliminated here by leveraging strlen_P, pgm_read_byte, and
// strncasecmp_P. That will take a bit of research since
// be eliminated here by leveraging strlen_P, pgm_read_byte, and
// strncasecmp_P. That will take a bit of research since
// the header file may have a different name on ESP2886/ESP32.
String work(nameAndDocs);
int compareLength = SIMPLE_SERIAL_SHELL_BUFSIZE;
int delim = work.indexOf(' ');
if (delim >=0) {
compareLength = delim;
if (delim >= 0) {
work.remove(delim);
}
return strncasecmp(work.c_str(), aName, compareLength);
return strncasecmp(work.c_str(), aName, SIMPLE_SERIAL_SHELL_BUFSIZE);
};

/**
* @brief Writes the documentation associated with this command.
*
*
* @param str Stream to write into.
*/
void renderDocumentation(Stream& str) const
Expand Down Expand Up @@ -341,7 +340,7 @@ void SimpleSerialShell::flush()
shellConnection->flush();
}

void SimpleSerialShell::setTokenizer(TokenizerFunction f)
void SimpleSerialShell::setTokenizer(TokenizerFunction f)
{
tokenizer = f;
}