Skip to content
This repository was archived by the owner on Mar 22, 2024. It is now read-only.

Commit 3665854

Browse files
author
kroimon
committed
Lots of functional changes, formatting and refactoring.
1 parent b4e5650 commit 3665854

File tree

5 files changed

+272
-259
lines changed

5 files changed

+272
-259
lines changed

SerialCommand.cpp

+129-135
Original file line numberDiff line numberDiff line change
@@ -1,150 +1,144 @@
1-
/*******************************************************************************
2-
SerialCommand - An Arduino library to tokenize and parse commands received over
3-
a serial port.
4-
Copyright (C) 2011 Steven Cogswell <[email protected]>
5-
http://husks.wordpress.com
6-
7-
Version 20110523B.
8-
9-
See SerialCommand.h for version history.
10-
11-
This library is free software; you can redistribute it and/or
12-
modify it under the terms of the GNU Lesser General Public
13-
License as published by the Free Software Foundation; either
14-
version 2.1 of the License, or (at your option) any later version.
15-
16-
This library is distributed in the hope that it will be useful,
17-
but WITHOUT ANY WARRANTY; without even the implied warranty of
18-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19-
Lesser General Public License for more details.
20-
21-
You should have received a copy of the GNU Lesser General Public
22-
License along with this library; if not, write to the Free Software
23-
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24-
***********************************************************************************/
25-
26-
#include "WProgram.h"
27-
#include <string.h>
1+
/**
2+
* SerialCommand - A Wiring/Arduino library to tokenize and parse commands
3+
* received over a serial port.
4+
*
5+
* Copyright (C) 2012 Stefan Rado
6+
* Copyright (C) 2011 Steven Cogswell <[email protected]>
7+
* http://husks.wordpress.com
8+
*
9+
* Version 20120522
10+
*
11+
* This library is free software: you can redistribute it and/or modify
12+
* it under the terms of the GNU Lesser General Public License as published by
13+
* the Free Software Foundation, either version 3 of the License, or
14+
* (at your option) any later version.
15+
*
16+
* This library is distributed in the hope that it will be useful,
17+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
18+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19+
* GNU Lesser General Public License for more details.
20+
*
21+
* You should have received a copy of the GNU General Public License
22+
* along with this library. If not, see <http://www.gnu.org/licenses/>.
23+
*/
2824
#include "SerialCommand.h"
2925

30-
// Constructor makes sure some things are set.
26+
/**
27+
* Constructor makes sure some things are set.
28+
*/
3129
SerialCommand::SerialCommand()
30+
: commandList(NULL),
31+
commandCount(0),
32+
defaultHandler(NULL),
33+
term('\n'), // default terminator for commands, newline character
34+
last(NULL)
3235
{
33-
strncpy(delim," ",MAXDELIMETER); // strtok_r needs a null-terminated string
34-
term='\r'; // return character, default terminator for commands
35-
numCommand=0; // Number of callback handlers installed
36-
clearBuffer();
36+
strcpy(delim, " "); // strtok_r needs a null-terminated string
37+
clearBuffer();
3738
}
3839

39-
//
40-
// Initialize the command buffer being processed to all null characters
41-
//
42-
void SerialCommand::clearBuffer()
43-
{
44-
for (int i=0; i<SERIALCOMMANDBUFFER; i++)
45-
{
46-
buffer[i]='\0';
47-
}
48-
bufPos=0;
40+
/**
41+
* Adds a "command" and a handler function to the list of available commands.
42+
* This is used for matching a found token in the buffer, and gives the pointer
43+
* to the handler function to deal with it.
44+
*/
45+
void SerialCommand::addCommand(const char *command, void (*function)()) {
46+
#ifdef SERIALCOMMAND_DEBUG
47+
Serial.print("Adding command (");
48+
Serial.print(commandCount);
49+
Serial.print("): ");
50+
Serial.println(command);
51+
#endif
52+
53+
commandList = (SerialCommandCallback *) realloc(commandList, (commandCount + 1) * sizeof(SerialCommandCallback));
54+
strncpy(commandList[commandCount].command, command, SERIALCOMMAND_MAXCOMMANDLENGTH);
55+
commandList[commandCount].function = function;
56+
commandCount++;
4957
}
5058

51-
// Retrieve the next token ("word" or "argument") from the Command buffer.
52-
// returns a NULL if no more tokens exist.
53-
char *SerialCommand::next()
54-
{
55-
char *nextToken;
56-
nextToken = strtok_r(NULL, delim, &last);
57-
return nextToken;
59+
/**
60+
* This sets up a handler to be called in the event that the receveived command string
61+
* isn't in the list of commands.
62+
*/
63+
void SerialCommand::setDefaultHandler(void (*function)(const char *)) {
64+
defaultHandler = function;
5865
}
5966

60-
// This checks the Serial stream for characters, and assembles them into a buffer.
61-
// When the terminator character (default '\r') is seen, it starts parsing the
62-
// buffer for a prefix command, and calls handlers setup by addCommand() member
63-
void SerialCommand::readSerial()
64-
{
65-
while (Serial.available() > 0)
66-
{
67-
int i;
68-
boolean matched;
69-
inChar=Serial.read(); // Read single available character, there may be more waiting
70-
#ifdef SERIALCOMMANDDEBUG
71-
Serial.print(inChar); // Echo back to serial stream
72-
#endif
73-
if (inChar==term) { // Check for the terminator (default '\r') meaning end of command
74-
#ifdef SERIALCOMMANDDEBUG
75-
Serial.print("Received: ");
76-
Serial.println(buffer);
77-
#endif
78-
bufPos=0; // Reset to start of buffer
79-
token = strtok_r(buffer,delim,&last); // Search for command at start of buffer
80-
if (token == NULL) return;
81-
matched=false;
82-
for (i=0; i<numCommand; i++) {
83-
#ifdef SERIALCOMMANDDEBUG
84-
Serial.print("Comparing [");
85-
Serial.print(token);
86-
Serial.print("] to [");
87-
Serial.print(CommandList[i].command);
88-
Serial.println("]");
89-
#endif
90-
// Compare the found command against the list of known commands for a match
91-
if (strncmp(token,CommandList[i].command,SERIALCOMMANDBUFFER) == 0)
92-
{
93-
#ifdef SERIALCOMMANDDEBUG
94-
Serial.print("Matched Command: ");
95-
Serial.println(token);
96-
#endif
97-
// Execute the stored handler function for the command
98-
(*CommandList[i].function)();
99-
clearBuffer();
100-
matched=true;
101-
break;
102-
}
103-
}
104-
if (matched==false) {
105-
(*defaultHandler)();
106-
clearBuffer();
107-
}
10867

109-
}
110-
if (isprint(inChar)) // Only printable characters into the buffer
111-
{
112-
buffer[bufPos++]=inChar; // Put character into buffer
113-
buffer[bufPos]='\0'; // Null terminate
114-
if (bufPos > SERIALCOMMANDBUFFER-1) bufPos=0; // wrap buffer around if full
115-
}
116-
}
68+
/**
69+
* This checks the Serial stream for characters, and assembles them into a buffer.
70+
* When the terminator character (default '\n') is seen, it starts parsing the
71+
* buffer for a prefix command, and calls handlers setup by addCommand() member
72+
*/
73+
void SerialCommand::readSerial() {
74+
while (Serial.available() > 0) {
75+
char inChar = Serial.read(); // Read single available character, there may be more waiting
76+
#ifdef SERIALCOMMAND_DEBUG
77+
Serial.print(inChar); // Echo back to serial stream
78+
#endif
79+
80+
if (inChar == term) { // Check for the terminator (default '\r') meaning end of command
81+
#ifdef SERIALCOMMAND_DEBUG
82+
Serial.print("Received: ");
83+
Serial.println(buffer);
84+
#endif
85+
86+
char *command = strtok_r(buffer, delim, &last); // Search for command at start of buffer
87+
if (command != NULL) {
88+
boolean matched = false;
89+
for (int i = 0; i < commandCount; i++) {
90+
#ifdef SERIALCOMMAND_DEBUG
91+
Serial.print("Comparing [");
92+
Serial.print(command);
93+
Serial.print("] to [");
94+
Serial.print(commandList[i].command);
95+
Serial.println("]");
96+
#endif
97+
98+
// Compare the found command against the list of known commands for a match
99+
if (strncmp(command, commandList[i].command, SERIALCOMMAND_MAXCOMMANDLENGTH) == 0) {
100+
#ifdef SERIALCOMMAND_DEBUG
101+
Serial.print("Matched Command: ");
102+
Serial.println(command);
103+
#endif
104+
105+
// Execute the stored handler function for the command
106+
(*commandList[i].function)();
107+
matched = true;
108+
break;
109+
}
110+
}
111+
if (!matched && (defaultHandler != NULL)) {
112+
(*defaultHandler)(command);
113+
}
114+
}
115+
clearBuffer();
116+
}
117+
else if (isprint(inChar)) { // Only printable characters into the buffer
118+
if (bufPos < SERIALCOMMAND_BUFFER) {
119+
buffer[bufPos++] = inChar; // Put character into buffer
120+
buffer[bufPos] = '\0'; // Null terminate
121+
} else {
122+
#ifdef SERIALCOMMAND_DEBUG
123+
Serial.println("Line buffer is full - increase SERIALCOMMAND_BUFFER");
124+
#endif
125+
}
126+
}
127+
}
117128
}
118129

119-
// Adds a "command" and a handler function to the list of available commands.
120-
// This is used for matching a found token in the buffer, and gives the pointer
121-
// to the handler function to deal with it.
122-
void SerialCommand::addCommand(char command[], void (*function)())
123-
{
124-
if (numCommand < MAXSERIALCOMMANDS) {
125-
#ifdef SERIALCOMMANDDEBUG
126-
Serial.print(numCommand);
127-
Serial.print("-");
128-
Serial.print("Adding command for ");
129-
Serial.println(command);
130-
#endif
131-
132-
strncpy(CommandList[numCommand].command,command,SERIALCOMMANDBUFFER);
133-
CommandList[numCommand].function = function;
134-
numCommand++;
135-
} else {
136-
// In this case, you tried to push more commands into the buffer than it is compiled to hold.
137-
// Not much we can do since there is no real visible error assertion, we just ignore adding
138-
// the command
139-
#ifdef SERIALCOMMANDDEBUG
140-
Serial.println("Too many handlers - recompile changing MAXSERIALCOMMANDS");
141-
#endif
142-
}
130+
/*
131+
* Clear the input buffer.
132+
*/
133+
void SerialCommand::clearBuffer() {
134+
buffer[0] = '\0';
135+
bufPos = 0;
143136
}
144137

145-
// This sets up a handler to be called in the event that the receveived command string
146-
// isn't in the list of things with handlers.
147-
void SerialCommand::addDefaultHandler(void (*function)())
148-
{
149-
defaultHandler = function;
150-
}
138+
/**
139+
* Retrieve the next token ("word" or "argument") from the command buffer.
140+
* Returns NULL if no more tokens exist.
141+
*/
142+
char *SerialCommand::next() {
143+
return strtok_r(NULL, delim, &last);
144+
}

0 commit comments

Comments
 (0)