A light Command Dispatcher Library with commands linked to your functions.
You can register your commands and the functions linked.
On each execution of a command (char array), it will parse the array and send all the parameters to the functions.
Here is a quick example :
#include "mbed.h" #include "CommandDispatcher.h" Serial pc(USBTX, USBRX); void echoCommand(unsigned int argc, char* argv[], char* result); int main() { CommandDispatcher disp = CommandDispatcher(); char buffer[50]; char result[50]; int i=0; // register a command disp.addCommand("echo", echoCommand); pc.printf("Example Command Dispatcher\n\n"); while(true) { // get a complete line from serial buffer[i++] = pc.getc(); if (buffer[i-1]=='\n') { buffer[i-1]='\0'; i=0; // send it to the dispatcher and print result if (disp.executeCommand(buffer, result)) { pc.printf("%s\n", result); } else { pc.printf("Command not found.\n"); } } } } // the actual function called void echoCommand(unsigned int argc, char* argv[], char* result) { int i; sprintf(result, ""); for (i=1; i<argc; i++) { sprintf(result, "%s %s", result, argv[i]); } sprintf(result, "%s\n", result); }
CommandServer.cpp@4:ca5d575c03c8, 2014-09-03 (annotated)
- Committer:
- rominos2
- Date:
- Wed Sep 03 19:33:41 2014 +0000
- Revision:
- 4:ca5d575c03c8
- Parent:
- 3:8784fbd35d29
Add #ifndef on headers
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
rominos2 | 3:8784fbd35d29 | 1 | /* |
rominos2 | 3:8784fbd35d29 | 2 | Copyright (c) 2014 Romain Berrada |
rominos2 | 3:8784fbd35d29 | 3 | |
rominos2 | 3:8784fbd35d29 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software |
rominos2 | 3:8784fbd35d29 | 5 | and associated documentation files (the "Software"), to deal in the Software without restriction, |
rominos2 | 3:8784fbd35d29 | 6 | including without limitation the rights to use, copy, modify, merge, publish, distribute, |
rominos2 | 3:8784fbd35d29 | 7 | sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is |
rominos2 | 3:8784fbd35d29 | 8 | furnished to do so, subject to the following conditions: |
rominos2 | 3:8784fbd35d29 | 9 | |
rominos2 | 3:8784fbd35d29 | 10 | The above copyright notice and this permission notice shall be included in all copies or |
rominos2 | 3:8784fbd35d29 | 11 | substantial portions of the Software. |
rominos2 | 3:8784fbd35d29 | 12 | |
rominos2 | 3:8784fbd35d29 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING |
rominos2 | 3:8784fbd35d29 | 14 | BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
rominos2 | 3:8784fbd35d29 | 15 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
rominos2 | 3:8784fbd35d29 | 16 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
rominos2 | 3:8784fbd35d29 | 17 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
rominos2 | 3:8784fbd35d29 | 18 | */ |
rominos2 | 3:8784fbd35d29 | 19 | |
rominos2 | 0:1bfd6f4c0dbb | 20 | #include "mbed.h" |
rominos2 | 1:855efbf6d7ae | 21 | #include "CommandDispatcher.h" |
rominos2 | 0:1bfd6f4c0dbb | 22 | |
rominos2 | 1:855efbf6d7ae | 23 | CommandDispatcher::CommandDispatcher() : _first_command(NULL) { |
rominos2 | 0:1bfd6f4c0dbb | 24 | } |
rominos2 | 0:1bfd6f4c0dbb | 25 | |
rominos2 | 1:855efbf6d7ae | 26 | void CommandDispatcher::addCommand(char* commandName, void(*command_function)(unsigned int argc, char* argv[], char* result)) { |
rominos2 | 1:855efbf6d7ae | 27 | CommandDispatcher::Command* com = new CommandDispatcher::Command(); |
rominos2 | 3:8784fbd35d29 | 28 | com->_name = new char[strlen(commandName)+1]; // +1 for the \0 |
rominos2 | 0:1bfd6f4c0dbb | 29 | strcpy(com->_name, commandName); |
rominos2 | 0:1bfd6f4c0dbb | 30 | com->_function = command_function; |
rominos2 | 0:1bfd6f4c0dbb | 31 | com->_next = _first_command; |
rominos2 | 0:1bfd6f4c0dbb | 32 | _first_command = com; |
rominos2 | 0:1bfd6f4c0dbb | 33 | } |
rominos2 | 0:1bfd6f4c0dbb | 34 | |
rominos2 | 1:855efbf6d7ae | 35 | void CommandDispatcher::cleanCommands() { |
rominos2 | 1:855efbf6d7ae | 36 | CommandDispatcher::Command* com = _first_command; |
rominos2 | 0:1bfd6f4c0dbb | 37 | while (com!=NULL) { |
rominos2 | 0:1bfd6f4c0dbb | 38 | _first_command = com->_next; |
rominos2 | 3:8784fbd35d29 | 39 | delete[] com->_name; |
rominos2 | 0:1bfd6f4c0dbb | 40 | delete com; |
rominos2 | 0:1bfd6f4c0dbb | 41 | } |
rominos2 | 0:1bfd6f4c0dbb | 42 | } |
rominos2 | 0:1bfd6f4c0dbb | 43 | |
rominos2 | 1:855efbf6d7ae | 44 | bool CommandDispatcher::executeCommand(char* command, char* result) { |
rominos2 | 1:855efbf6d7ae | 45 | CommandDispatcher::Command* command_ptr; |
rominos2 | 0:1bfd6f4c0dbb | 46 | bool function_return = false; |
rominos2 | 1:855efbf6d7ae | 47 | unsigned int argc; |
rominos2 | 0:1bfd6f4c0dbb | 48 | char** argv; |
rominos2 | 0:1bfd6f4c0dbb | 49 | char* buffer; |
rominos2 | 0:1bfd6f4c0dbb | 50 | |
rominos2 | 0:1bfd6f4c0dbb | 51 | buffer = new char[strlen(command)+1]; // + 1 for the \0 |
rominos2 | 0:1bfd6f4c0dbb | 52 | strcpy(buffer, command); |
rominos2 | 0:1bfd6f4c0dbb | 53 | |
rominos2 | 0:1bfd6f4c0dbb | 54 | argc = parse_buffer(buffer, &argv); |
rominos2 | 0:1bfd6f4c0dbb | 55 | toLowerCase(argv[0]); |
rominos2 | 0:1bfd6f4c0dbb | 56 | |
rominos2 | 0:1bfd6f4c0dbb | 57 | for (command_ptr=_first_command; command_ptr!=NULL; command_ptr = command_ptr->_next) { |
rominos2 | 0:1bfd6f4c0dbb | 58 | if (strcmp(argv[0], command_ptr->_name)==0) { |
rominos2 | 0:1bfd6f4c0dbb | 59 | command_ptr->_function(argc, argv, result); |
rominos2 | 0:1bfd6f4c0dbb | 60 | function_return = true; |
rominos2 | 0:1bfd6f4c0dbb | 61 | break; |
rominos2 | 0:1bfd6f4c0dbb | 62 | } |
rominos2 | 0:1bfd6f4c0dbb | 63 | } |
rominos2 | 0:1bfd6f4c0dbb | 64 | |
rominos2 | 0:1bfd6f4c0dbb | 65 | delete[] argv; |
rominos2 | 0:1bfd6f4c0dbb | 66 | delete[] buffer; |
rominos2 | 0:1bfd6f4c0dbb | 67 | return function_return; |
rominos2 | 0:1bfd6f4c0dbb | 68 | } |
rominos2 | 0:1bfd6f4c0dbb | 69 | |
rominos2 | 1:855efbf6d7ae | 70 | int CommandDispatcher::parse_buffer(char* buffer, char*** argv) { |
rominos2 | 1:855efbf6d7ae | 71 | unsigned int i; |
rominos2 | 1:855efbf6d7ae | 72 | unsigned int word_count; |
rominos2 | 1:855efbf6d7ae | 73 | bool letter_found; |
rominos2 | 1:855efbf6d7ae | 74 | unsigned int buffer_size = strlen(buffer); |
rominos2 | 1:855efbf6d7ae | 75 | unsigned int argc; |
rominos2 | 0:1bfd6f4c0dbb | 76 | char** argv_tab; |
rominos2 | 0:1bfd6f4c0dbb | 77 | |
rominos2 | 0:1bfd6f4c0dbb | 78 | // 1st cycle, counting the number of words |
rominos2 | 1:855efbf6d7ae | 79 | letter_found = false; |
rominos2 | 0:1bfd6f4c0dbb | 80 | word_count = 0; |
rominos2 | 0:1bfd6f4c0dbb | 81 | for (i=0; i<buffer_size; i++) { |
rominos2 | 0:1bfd6f4c0dbb | 82 | if (buffer[i]==' ' && letter_found) { |
rominos2 | 0:1bfd6f4c0dbb | 83 | word_count++; |
rominos2 | 1:855efbf6d7ae | 84 | letter_found=false; |
rominos2 | 1:855efbf6d7ae | 85 | } else letter_found=true; |
rominos2 | 0:1bfd6f4c0dbb | 86 | } |
rominos2 | 1:855efbf6d7ae | 87 | if (letter_found) word_count++; // to get last word |
rominos2 | 0:1bfd6f4c0dbb | 88 | |
rominos2 | 0:1bfd6f4c0dbb | 89 | // create the array of words |
rominos2 | 0:1bfd6f4c0dbb | 90 | argv_tab = new char*[word_count]; |
rominos2 | 0:1bfd6f4c0dbb | 91 | argc = word_count; |
rominos2 | 0:1bfd6f4c0dbb | 92 | |
rominos2 | 0:1bfd6f4c0dbb | 93 | // 2nd cycle, putting words into the array |
rominos2 | 1:855efbf6d7ae | 94 | letter_found = false; |
rominos2 | 0:1bfd6f4c0dbb | 95 | word_count = 0; |
rominos2 | 0:1bfd6f4c0dbb | 96 | for (i=0; i<buffer_size; i++) { |
rominos2 | 0:1bfd6f4c0dbb | 97 | if (buffer[i]==' ') { |
rominos2 | 0:1bfd6f4c0dbb | 98 | buffer[i] = '\0'; |
rominos2 | 1:855efbf6d7ae | 99 | letter_found = false; |
rominos2 | 0:1bfd6f4c0dbb | 100 | } else if (!letter_found) { |
rominos2 | 0:1bfd6f4c0dbb | 101 | argv_tab[word_count++]=&buffer[i]; |
rominos2 | 1:855efbf6d7ae | 102 | letter_found=true; |
rominos2 | 0:1bfd6f4c0dbb | 103 | } |
rominos2 | 0:1bfd6f4c0dbb | 104 | } |
rominos2 | 0:1bfd6f4c0dbb | 105 | |
rominos2 | 0:1bfd6f4c0dbb | 106 | *argv = argv_tab; |
rominos2 | 0:1bfd6f4c0dbb | 107 | return argc; |
rominos2 | 0:1bfd6f4c0dbb | 108 | } |
rominos2 | 0:1bfd6f4c0dbb | 109 | |
rominos2 | 1:855efbf6d7ae | 110 | void CommandDispatcher::toLowerCase(char* word) { |
rominos2 | 0:1bfd6f4c0dbb | 111 | int i; |
rominos2 | 0:1bfd6f4c0dbb | 112 | for (i=0; i<strlen(word); i++) { |
rominos2 | 0:1bfd6f4c0dbb | 113 | if (word[i]>=65 && word[i]<=90) { // if between A-Z |
rominos2 | 0:1bfd6f4c0dbb | 114 | word[i] += 32; |
rominos2 | 0:1bfd6f4c0dbb | 115 | } |
rominos2 | 0:1bfd6f4c0dbb | 116 | } |
rominos2 | 0:1bfd6f4c0dbb | 117 | } |