A Command Interpreter with support for used defined commands, subsystems, macros, help and parameter parsing.

Files at this revision

API Documentation at this revision

Comitter:
wvd_vegt
Date:
Tue Sep 20 18:14:33 2011 +0000
Parent:
17:7e6a723d65de
Child:
19:9e24566d0b98
Commit message:
1) Made lots of stuff static (including the cmd struct). This is a breaking change (easy to fix though).

Changed in this revision

cmdb.cpp Show annotated file Show diff for this revision Revisions of this file
cmdb.h Show annotated file Show diff for this revision Revisions of this file
--- a/cmdb.cpp	Mon Sep 05 10:05:49 2011 +0000
+++ b/cmdb.cpp	Tue Sep 20 18:14:33 2011 +0000
@@ -3,7 +3,7 @@
 
    Project:     mBed Command Interpreter
    Filename:    cmdb.h
-   Version:     0.5.0
+   Version:     0.80
 _____________________________________________________________________________
    Date         Comment
    -------- --------------------------------------------------------------
@@ -30,6 +30,19 @@
              replace() can be used to replace the complete command vector
              by a changed done. Inserting directly into cmdb's copy fails
              somehow.
+   19092011 -Added PrintSection(), PrintValue() and PrintValuef() for 
+             easier Windows Ini File style output. As I use it to transfer 
+             data back to the PC (Easy parsing AND you can add/remove
+             debug information without breaking PC code).
+   20092011 -Breaking change, Made all cmd object static const like:
+   
+             static const cmd HELP = {"Help",GLOBALCMD,CID_HELP,"%s","Help"};
+
+             this saves just to much ram memory on the heap. 
+             Thanks to Igor Skochinsky.
+             
+            -Made some more const string static.     
+            -v0.80
    -------- --------------------------------------------------------------
    TODO's
    10022011 -Tweak and Review Documentation.
@@ -56,6 +69,9 @@
     echo = true;
     bold = true;
 
+    NoComment = NULL;
+    DefComPos = 72;
+
     subsystem = -1;
 
     user_callback = _callback;
@@ -63,6 +79,10 @@
     init(true);
 }
 
+const char* Cmdb::NoComment;
+
+int Cmdb::DefComPos;
+
 //------------------------------------------------------------------------------
 // Public Stuff.
 //------------------------------------------------------------------------------
@@ -248,6 +268,70 @@
     return serial.printf(msg);
 }
 
+int   Cmdb::printsection(const char *section) {
+    return printf("[%s]\r\n", section);
+}
+
+int   Cmdb::printvaluef(const char *key, const char *format, ...) {
+    char buf[256];
+
+    va_list args;
+    va_start(args, format);
+
+    vsnprintf(buf, sizeof(buf), format, args);
+    
+    va_end(args);
+
+    return printf("%s=%s\r\n",key, buf);
+}
+
+int   Cmdb::printvaluef(const char *key, const int width, const char *comment, const char *format, ...) {
+    printf("%s=",key);
+
+    int  result = 0;
+    char buf[256];
+    int  cnt = 0;
+
+    va_list args;
+    va_start(args, format);
+
+    cnt = vsnprintf(buf, sizeof(buf), format, args);
+    cnt +=strlen(key)+1;
+    
+    va_end(args);
+
+    if (comment!=NULL) {
+        if (cnt<width) {
+            result = printf("%-*s ;%s\r\n", width, buf, comment);
+        } else {
+            result = printf("%s ;%s\r\n", buf, comment);
+        }
+    } else {
+        result = printf("%s\r\n",buf);
+    }
+
+    return result;
+}
+
+int   Cmdb::printvalue(const char *key, const char *value, const char *comment, const int width) {
+    if (comment) {
+        char buf[256];
+        int  cnt = 0;
+
+        memset(buf,'\0',sizeof(buf));
+
+        cnt = snprintf(buf, sizeof(buf), "%s=%s", key, value);
+
+        if (cnt<width) {
+            return printf("%-*s ;%s\r\n", width, buf, comment);
+        } else {
+            return printf("%s ;%s\r\n", buf, comment);
+        }
+    } else {
+        return printf("%s=%s\r\n", key, value);
+    }
+}
+
 char  Cmdb::printch(const char ch) {
     return serial.putc(ch);
 }
@@ -291,7 +375,7 @@
 int  Cmdb::cmdid_search(char *cmdstr) {
     //Warning, we return the ID but somewhere assume it's equal to the array index!
     for (int i=0; i<cmds.size(); i++) {
-        if ((stricmp(cmds[i].cmdstr, cmdstr) == 0) && ((cmds[i].subs == subsystem) || (cmds[i].subs<0)))
+        if ((stricmp((char*)cmds[i].cmdstr, cmdstr) == 0) && ((cmds[i].subs == subsystem) || (cmds[i].subs<0)))
             return (cmds[i].cid);
     }
 
--- a/cmdb.h	Mon Sep 05 10:05:49 2011 +0000
+++ b/cmdb.h	Tue Sep 20 18:14:33 2011 +0000
@@ -114,96 +114,63 @@
  */
 struct cmd {
 public:
-    char *cmdstr;
+    const char *cmdstr;
     int  subs;
     int  cid;
-    char *parms;
-    char *cmddescr;
-    char *parmdescr;
-
-    /** Default Constructor.
-     */
-    cmd() {
-    }
-
-    /** Command Constructor.
-     *
-     * @parm _cmdstr the command, not case sensitive.
-     * @parm _subs subsystem id
-     * @parm _cid the command id that will be passed to the dispatcher.
-     * @parm _parms a scanf alike pattern.
-     * @parm _cmddescr command description.
-     * @parm _parmdescr parameter description.
-     */
-    cmd(char *_cmdstr, int _subs, int _cid, char *_parms, char *_cmddescr, char *_parmdescr = "") {
-        cmdstr = (char*)malloc(strlen(_cmdstr)+1);
-        strcpy(cmdstr,_cmdstr);
-
-        subs = _subs;
-        cid = _cid;
-
-        parms = (char*)malloc(strlen(_parms)+1);
-        strcpy(parms,_parms);
-
-        cmddescr = (char*)malloc(strlen(_cmddescr)+1);
-        strcpy(cmddescr,_cmddescr);
-
-        parmdescr = (char*)malloc(strlen(_parmdescr)+1);
-        strcpy(parmdescr,_parmdescr);
-
-        //printf("%d:%d\r\n", subs, cid);
-    }
+    const char *parms;
+    const char *cmddescr;
+    const char *parmdescr;
 };
 
 //------------------------------------------------------------------------------
 
 /** Cr.
  */
-const char cr           = '\r';
+static const char cr           = '\r';
 
 /** Lf.
  */
-const char lf           = '\n';
+static const char lf           = '\n';
 
 /** Bell.
  */
-const char bell         = '\7';
+static const char bell         = '\7';
 
 /** Escape.
  */
-const char esc          = '\033';
+static const char esc          = '\033';
 
 /** Space.
  */
-const char sp           = ' ';
+static const char sp           = ' ';
 
 /** CrLf.
  */
-const char crlf[]       = "\r\n";
+static const char crlf[]       = "\r\n";
 
 /** Backspace that 'tries' to wipe the last character.
  */
-const char bs[]         = "\b \b";
+static const char bs[]         = "\b \b";
 
 /** VT100 Bold Command.
  */
-const char boldon[]     = "\033[1m";
+static const char boldon[]     = "\033[1m";
 
 /** VT100 Normal Command.
  */
-const char boldoff[]    = "\033[0m";
+static const char boldoff[]    = "\033[0m";
 
 /** VT100 Cls Command.
  */
-const char cls[]        = "\033[2J";
+static const char cls[]        = "\033[2J";
 
 /** VT100 Home Command.
  */
-const char home[]       = "\033[H";
+static const char home[]       = "\033[H";
 
 /** The default command prompt.
  */
-const char PROMPT[]     = "CMD>";
+static const char PROMPT[]     = "CMD>";
 
 //------------------------------------------------------------------------------
 
@@ -290,61 +257,61 @@
  *
  * Optional.
  */
-const cmd COMMANDS("Commands",GLOBALCMD,CID_COMMANDS,"","Dump Commands");
+static const cmd COMMANDS = {"Commands",GLOBALCMD,CID_COMMANDS,"","Dump Commands"};
 
 /** The Boot Command.
  *
  * Optional.
  */
-const cmd BOOT("Boot",GLOBALCMD,CID_BOOT,"","Boot mBed");
+static const cmd BOOT = {"Boot",GLOBALCMD,CID_BOOT,"","Boot mBed"};
 
 /** The Macro Command.
  *
  * Optional.
  */
-const cmd MACRO("Macro",GLOBALCMD,CID_MACRO,"%s","Define macro (sp->_, cr->|)","command(s)");
+static const cmd MACRO = {"Macro",GLOBALCMD,CID_MACRO,"%s","Define macro (sp->_, cr->|)","command(s)"};
 
 /** The Run Command.
  *
  * Optional.
  */
-const cmd RUN("Run",GLOBALCMD,CID_RUN,"","Run a macro");
+static const cmd RUN = {"Run",GLOBALCMD,CID_RUN,"","Run a macro"};
 
 /** The Macros Command.
  *
  * Optional.
  */
-const cmd MACROS("Macros",GLOBALCMD,CID_MACROS,"","List macro(s)");
+static const cmd MACROS = {"Macros",GLOBALCMD,CID_MACROS,"","List macro(s)"};
 
 /** The Echo Command.
  *
  * Optional.
  */
-const cmd ECHO("Echo",GLOBALCMD,CID_ECHO,"%bu","Echo On|Off (1|0)","state");
+static const cmd ECHO = {"Echo",GLOBALCMD,CID_ECHO,"%bu","Echo On|Off (1|0)","state"};
 
 /** The Bold Command.
  *
  * Optional.
  */
-const cmd BOLD("Bold",GLOBALCMD,CID_BOLD,"%bu","Bold On|Off (1|0)","state");
+static const cmd BOLD = {"Bold",GLOBALCMD,CID_BOLD,"%bu","Bold On|Off (1|0)","state"};
 
 /** The Cls Command.
  *
  * Optional.
  */
-const cmd CLS("Cls",GLOBALCMD,CID_CLS,"","Clears the terminal screen");
+static const cmd CLS = {"Cls",GLOBALCMD,CID_CLS,"","Clears the terminal screen"};
 
 /** The Idle Command.
  *
  * Mandatory if you use subsystems.
  */
-const cmd IDLE("Idle",GLOBALCMD,CID_IDLE,"","Deselect Subsystems");
+static const cmd IDLE = {"Idle",GLOBALCMD,CID_IDLE,"","Deselect Subsystems"};
 
 /** The Help Command.
  *
  * Mandatory.
  */
-const cmd HELP("Help",GLOBALCMD,CID_HELP,"%s","Help");
+static const cmd HELP = {"Help",GLOBALCMD,CID_HELP,"%s","Help"};
 
 //------------------------------------------------------------------------------
 
@@ -371,7 +338,7 @@
 
 /** The Escape Codes Table.
  */
-const struct esc esc_tbl [ESC_TBL_LEN] = {
+static const struct esc esc_tbl [ESC_TBL_LEN] = {
     { "\033[A",    EID_CURSOR_UP    },
     { "\033[B",    EID_CURSOR_DOWN  },
     { "\033[C",    EID_CURSOR_RIGHT },
@@ -382,7 +349,7 @@
 
 /** The Command Interpreter Version.
  */
-#define CMDB_VERSION     0.78
+#define CMDB_VERSION     0.80
 
 //------------------------------------------------------------------------------
 
@@ -429,6 +396,14 @@
         return CMDB_VERSION;
     }
 
+    /** NULL is used as No Comment Value.
+      */
+    static const char* NoComment;
+
+    /** Column 72 is used as Default Comment Starting Position.
+      */
+    static int DefComPos;
+
     /** Checks if the macro buffer has any characters left.
      *
      * @returns true if any characters left.
@@ -511,6 +486,69 @@
      */
     char printch(const char ch);
 
+    /** printsection prints an inifile Section Header
+     *  like:
+     *
+     *  [Section]\r\n
+     *
+     *  Usage: cmdb.printsection("GP");
+     *
+     *  @parm section the section to print.
+     *
+     *  @returns the printf return value.
+     */
+    int printsection(const char *section);
+
+    /** printvalue prints an inifile Key/Value Pair
+     *  like:
+     *
+     *  Key=Value   ;comment\r\n
+     *
+     *  Note: the Comment is (if present) located at position 72.
+     *
+     *  Usage: cmdb.printvaluef("Value", Cmdb::DefComPos, "Hex", "0x%8.8X", LPC_RTC->GPREG0);
+     *
+     * @parm key the key to print.
+     * @parm comment the comment to print.
+     * @parm width the location of the comment to print.
+     * @parm format the value to print.
+     * @parm parameter to print.
+     *
+     * @returns the printf return value.
+     */
+    int printvaluef(const char *key, const int width, const char *comment, const char *format, ...);
+
+    /** printvalue prints an inifile Key/Value Pair
+     *  like:
+     *
+     *  Key=Value\r\n
+     *
+     *  Usage: cmdb.printvaluef("Value", "0x%8.8X", LPC_RTC->GPREG0);
+     *
+     * @parm key the key to print.
+     * @parm format the value to print.
+     * @parm parameter to print.
+     *
+     * @returns the printf return value.
+     */
+    int printvaluef(const char *key, const char *format, ...);
+
+    /** printvalue prints an inifile Key/Value Pair
+     *  like:
+     *
+     *  Key=Value   ;comment\r\n
+     *
+     *  Note the Comment is (if present) located at position 72.
+     *
+     * @parm key the key to print.
+     * @parm value the value to print.
+     * @parm comment the comment to print.
+     * @parm width the location of the comment to print.
+     *
+     * @returns the printf return value.
+     */
+    int printvalue(const char *key, const char *value, const char *comment = NoComment, const int width = DefComPos);
+
 //------------------------------------------------------------------------------
 
     /** Initializes the parser (called by the constructor).