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
15 changes: 15 additions & 0 deletions debug_cli/DbgCliCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,24 @@

#include <DbgCliCommand.h>

#ifdef ARDUINO
#include <Arduino.h>
#else
#include <stdio.h>
#endif

DbgCli_Command::DbgCli_Command(const char* parentPath, const char* nodeName, const char* helpText)
: DbgCli_Node(parentPath, nodeName, helpText)
{ }

DbgCli_Command::~DbgCli_Command()
{ }

void DbgCli_Command::execute(unsigned int argc, const char** args, unsigned int idxToFirstArgToHandle)
{
#ifdef ARDUINO
Serial.println(getHelpText());
#else
printf("%s\n", getHelpText());
#endif
}
10 changes: 7 additions & 3 deletions debug_cli/DbgCliCommand.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,12 @@

#include <DbgCliNode.h>

/**
* Composite Pattern: Abstract Command Class, acts as the leaf node of the tree, has to be implemented by the client.
*/
class DbgCli_Command: public DbgCli_Node
{
public:
public: // abstract class - constructor must not be accessible
/**
* Constructor for a leaf node in the Command tree.
* @param parentPath Parent path string, each token is space separated.
Expand All @@ -21,19 +24,20 @@ class DbgCli_Command: public DbgCli_Node
*/
DbgCli_Command(const char* parentPath, const char* nodeName, const char* helpText);

public:
/**
* Destructor.
*/
virtual ~DbgCli_Command();

/**
* Execute the debug command.
* Pure virtual method, to be implemented by the application.
* Pure virtual method, to be implemented by the client application.
* @param argc
* @param args
* @param idxToFirstArgToHandle Index to the first argument in args array to be handled as parameter (this is the first parameter to be passed to the method that gets called by this command)
*/
virtual void execute(unsigned int argc, char* args[], unsigned int idxToFirstArgToHandle) = 0;
virtual void execute(unsigned int argc, const char** args, unsigned int idxToFirstArgToHandle);

private: // forbidden default functions
DbgCli_Command& operator= (const DbgCli_Command& src); // assignment operator
Expand Down
33 changes: 32 additions & 1 deletion debug_cli/DbgCliNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,34 @@
* Author: niklausd
*/

#include <DbgCliTopic.h>
#include <DbgCliNode.h>
#include <string.h>

DbgCli_Node* DbgCli_Node::s_rootNode = 0;

void DbgCli_Node::AssignRootNode(DbgCli_Node* rootNode)
{
s_rootNode = rootNode;
}

DbgCli_Node* DbgCli_Node::RootNode()
{
return s_rootNode;
}

DbgCli_Node::DbgCli_Node(const char* parentPath, const char* nodeName, const char* helpText)
: m_parentPath(parentPath)
, m_nodeName(nodeName)
, m_helpText(helpText)
{ }
, m_sibling(0)
{
DbgCli_Node* rootNode = DbgCli_Node::RootNode();
if (0 != rootNode)
{
rootNode->addNode(this);
}
}

DbgCli_Node::~DbgCli_Node()
{ }
Expand All @@ -30,3 +51,13 @@ const char* DbgCli_Node::getHelpText()
{
return m_helpText;
}

DbgCli_Node* DbgCli_Node::getNextSibling()
{
return m_sibling;
}

void DbgCli_Node::setNextSibling(DbgCli_Node* nextSibling)
{
m_sibling = nextSibling;
}
48 changes: 40 additions & 8 deletions debug_cli/DbgCliNode.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,38 +19,70 @@ class DbgCli_Node
public:
virtual ~DbgCli_Node();

public:
/**
* Add a new node to the tree.
* @param node Pointer to the DbgCli_Node to be added.
* Add a node to the tree.
* Location is given by the parentPath set for the node.
* @param node Pointer to the node to be added.
*/
virtual void addNode(DbgCli_Node* node) { }

protected:
/**
* Get the node at the particular path.
* @param cmdPath Path string addressing the node.
* @param cmdPathStrLen Length of the Path string
* @return DbgCli_Node Pointer to the object found, null pointer otherwise
* Add a child node to this node.
* @param childNode Pointer the node to be added as a child.
*/
virtual DbgCli_Node* getNode(const char* cmdPath, unsigned int cmdPathStrLen) = 0;
virtual void addChildNode(DbgCli_Node* childNode) { }

public:
/**
* Get a child node by name (no grandchildren).
* Command nodes return always null, since these objects don't have any children.
* @param nodeName Child node object name.
* @return DbgCli_Node Pointer to the object found, null pointer otherwise.
*/
virtual DbgCli_Node* getNode(const char* nodeName) { return 0; }

public:
/**
* Execute the debug command.
* Pure virtual method, to be implemented for leaf nodes (i.e. commands) by the application.
* @param argc
* @param args
* @param idxToFirstArgToHandle Index to the first argument in args array to be handled as parameter (this is the first parameter to be passed to the method that gets called by this command)
*/
virtual void execute(unsigned int argc, char* args[], unsigned int idxToFirstArgToHandle) = 0;
virtual void execute(unsigned int argc, const char** args, unsigned int idxToFirstArgToHandle) = 0;

const char* getParentPath();
const char* getNodeName();
const char* getHelpText();

/**
* Get next sibling.
* @return DbgCli_Node Pointer to the next sibling object, null pointer if none is available.
*/
DbgCli_Node* getNextSibling();

/**
* Set specific node as next sibling.
* @param nextSibling Pointer to the next sibling object to be assigned.
*/
void setNextSibling(DbgCli_Node* nextSibling);

public:
static void AssignRootNode(DbgCli_Node* rootNode);
static DbgCli_Node* RootNode();

private:
static DbgCli_Node* s_rootNode;

private:
const char* m_parentPath;
const char* m_nodeName;
const char* m_helpText;

DbgCli_Node* m_sibling;

private: // forbidden default functions
DbgCli_Node& operator= (const DbgCli_Node& src); // assignment operator
DbgCli_Node(const DbgCli_Node& src); // copy constructor
Expand Down
152 changes: 127 additions & 25 deletions debug_cli/DbgCliTopic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,52 +6,154 @@
*/

#include <DbgCliTopic.h>
#include <string.h>
#include <stdlib.h>

DbgCli_Topic* DbgCli_Topic::RootNode()
{
if (0 == s_rootNode)
{
s_rootNode = new DbgCli_Topic("/", "", "Root Node");
}
return s_rootNode;
}

#ifdef ARDUINO
#include "Arduino.h"
#else
#include <stdio.h>
#endif

DbgCli_Topic::DbgCli_Topic(const char* parentPath, const char* nodeName, const char* helpText)
: DbgCli_Node(parentPath, nodeName, helpText)
, m_child(0)
, m_sibling(0)
, m_firstChild(0)
{ }

DbgCli_Topic::~DbgCli_Topic()
{ }

void DbgCli_Topic::addNode(DbgCli_Node* node)
{
// TODO: search the parent node according to the provided parentPath given by the node object.
const char* parentPath = node->getParentPath();
if (0 != node)
{
const char* nodeParentPath = node->getParentPath();
unsigned int strLen = 50;
char str[strLen];
strncpy(str, nodeParentPath, strLen);

unsigned int nbrOfTokens = 0;
char nodeParentPathTokens[10][50];

char* token;
token = strtok(str, " /.-");
while (0 != token)
{
strncpy(nodeParentPathTokens[nbrOfTokens], token, 50);
nbrOfTokens++;
token = strtok(0, " /.-");
}

// find name of this in parent path of node to add
bool found = false;
const char* thisNodeName = this->getNodeName();
unsigned int tokenIterator = 0; // range: 0..nbrOfTokens-1
while ((tokenIterator < nbrOfTokens) && !found)
{
char* nodePathToken = nodeParentPathTokens[tokenIterator];
found = (strcmp(nodePathToken, thisNodeName) == 0);
tokenIterator++;
}

if (found)
{
if ((tokenIterator) == nbrOfTokens)
{
// node shall be a child of this
this->addChildNode(node);
}
else
{
char* childNodeName = nodeParentPathTokens[tokenIterator];
// node shall be a grand-child (or deeper) of this
// find continued path in own family
DbgCli_Node* childNode = this->getNode(childNodeName);
if (0 != childNode)
{
childNode->addNode(node);
}
else
{
// not yet existing intermediate node, create it
unsigned int strLen = 50;
const char* thisParentPath = this->getParentPath();
char parentPathForChild[strLen];
strncpy(parentPathForChild, thisParentPath, strLen);
if (strlen(thisParentPath) > 0)
{
strcat(parentPathForChild, " ");
}
strcat(parentPathForChild, thisNodeName);

DbgCli_Node* childNode = new DbgCli_Topic(parentPathForChild, childNodeName, "");
this->addChildNode(childNode);
childNode->addNode(node);
}
}
}
else
{

}
}
}

DbgCli_Node* DbgCli_Topic::getNode(const char* cmdPath, unsigned int cmdPathStrLen)
void DbgCli_Topic::addChildNode(DbgCli_Node* node)
{
// TODO: search the node according to the provided cmdPath and return the pointer to the object if found.
return 0;
if (0 == m_firstChild)
{
m_firstChild = node;
}
else
{
DbgCli_Node* next = m_firstChild;

while (0 != next->getNextSibling())
{
next = next->getNextSibling();
}
next->setNextSibling(node);
}
}

void DbgCli_Topic::execute(unsigned int arg_cnt, char* args[], unsigned int idxToFirstArgToHandle)
DbgCli_Node* DbgCli_Topic::getNode(const char* nodeName)
{
// TODO: Finds its path according to the args array's tokens.
// TODO: Calls the execute method of the right child node if found, increments the index to the first parameter to handle accordingly.
bool found = false;
DbgCli_Node* tmpNode = m_firstChild;
while ((0 != tmpNode) && !found)
{
found = (strcmp(tmpNode->getNodeName(), nodeName) == 0);
if (!found)
{
tmpNode = tmpNode->getNextSibling();
}
}
return tmpNode;
}

void DbgCli_Topic::addChildNode(DbgCli_Node* node)
void DbgCli_Topic::execute(unsigned int argc, const char** args, unsigned int idxToFirstArgToHandle)
{
DbgCli_Topic* tmpTopic = m_child;
while (0 != tmpTopic)
const char* nodeName = args[idxToFirstArgToHandle];
#ifdef ARDUINO
Serial.print("DbgCli_Topic::execute, curNodeName: ");
Serial.print(this->getNodeName());
Serial.print(", nodeName: ");
Serial.println(nodeName);
#endif

DbgCli_Node* tmpNode = getNode(nodeName);
if (0 != tmpNode)
{
tmpTopic = tmpTopic->m_sibling;
idxToFirstArgToHandle++;
tmpNode->execute(argc, args, idxToFirstArgToHandle);
}
else
{
// not found
#ifdef ARDUINO
Serial.println(getHelpText());
#else
printf("%s\n", getHelpText());
#endif
}
tmpTopic->addNode(node);
}

Loading