A light Command Dispatcher Library with commands linked to your functions.

Dependents:   Rocket

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);
}
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?

UserRevisionLine numberNew 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 }