The CommandProcessor is the interface to install a run-time menu into an embedded system.
Dependents: A_CANAdapter USB2I2C
Diff: CommandProcessor.c
- Revision:
- 10:9e52bd1a4a71
- Parent:
- 9:41046d2fd8e7
- Child:
- 11:4a3cd3f2183b
diff -r 41046d2fd8e7 -r 9e52bd1a4a71 CommandProcessor.c --- a/CommandProcessor.c Sun Apr 10 21:04:49 2011 +0000 +++ b/CommandProcessor.c Sat Apr 23 14:04:19 2011 +0000 @@ -8,7 +8,7 @@ /// /// Even though it is a c interface, it is somewhat object oriented. /// -/// @version 1.0 +/// @version 1.01 /// /// @note Copyright © 2011 by Smartware Computing, all rights reserved. /// This program may be used by others as long as this copyright notice @@ -46,6 +46,8 @@ static char *buffer; // buffer space must be allocated based on the longest command static struct { + CMD_T *SignOnBanner; + int showSignOnBanner; // Shows the sign-on banner at startup int caseinsensitive; // FALSE=casesensitive, TRUE=insensitive int echo; // TRUE=echo on, FALSE=echo off int bufferSize; // size of the buffer @@ -56,9 +58,8 @@ } cfg; static INITRESULT_T CommandProcessor_Init( - int defaultMenu, - int caseinsensitive, - int echo, + CMD_T *SignOnBanner, + CONFIG_T config, int maxCmdLen, int (*kbhit)(void), int (*getch)(void), @@ -87,12 +88,12 @@ static RUNRESULT_T Help(char *p); static RUNRESULT_T Echo(char *p); static RUNRESULT_T Exit(char *p); -static RUNRESULT_T About(char *p); +//static RUNRESULT_T About(char *p); static CMD_T HelpMenu = {"Help", "Help or '?' shows this help, 'Help ?' shows more details.", Help, visible}; static CMD_T QuestionMenu = {"?", "Shows this help, '? ?' shows more details.", Help, invisible}; static CMD_T EchoMenu = {"Echo", "Echo [1|on|0|off] turns echo on or off.", Echo, visible}; -static CMD_T AboutMenu = {"About", "About this CommandProcessor", About, visible}; +//static CMD_T AboutMenu = {"About", "About this CommandProcessor", About, visible}; static CMD_T ExitMenu = {"Exit", "Exits the program", Exit, visible}; /// Gets a handle to the CommandProcessor @@ -113,6 +114,7 @@ /// none for this function. /// @returns runok /// +#if 0 static RUNRESULT_T About(char *p) { cfg.puts("\r\n About this CommandProcessor:\r\n" " This CommandProcessor provides an easy facility for creating a\r\n" @@ -122,6 +124,7 @@ ); return runok; } +#endif /// Turns command prompt echo on and off /// @@ -158,8 +161,8 @@ CMDLINK_T *link = head; char buffer[100]; cfg.puts("\r\n"); - sprintf(buffer, " %-10s: %s", "Command", "Description"); - cfg.puts(buffer); + //sprintf(buffer, " %-10s: %s", "Command", "Description"); + //cfg.puts(buffer); while (link && link->menu) { if (link->menu->visible) { if (strlen(link->menu->command) + strlen(link->menu->helptext) + 5 < sizeof(buffer)) { @@ -171,10 +174,10 @@ } cfg.puts(""); if (*p == '?') { - cfg.puts("\r\n Extended Help\r\n" + cfg.puts("\r\n Extended Help:\r\n" " The general form for entering commands is:\r\n" " >command option1 option2 ...\r\n" - " [note that note all commands support optional parameters]\r\n" + " [note that not all commands support optional parameters]\r\n" " * Abbreviations of commands may be entered so long as there\r\n" " is exactly one match in the list of commands. For example,\r\n" " 'he' is the same as 'help', if there is no other command \r\n" @@ -183,6 +186,11 @@ " * <esc> can be used to cancel a command.\r\n" " * <tab> can be used to complete the entry of a partial command.\r\n" ""); + cfg.puts("\r\n About this CommandProcessor:\r\n" + " This CommandProcessor provides an easy facility for creating an\r\n" + " interactive runtime interpreter in an embedded system.\r\n" + " Copyright (c) 2011 by Smartware Computing, all rights reserved.\r\n" + " Author: David Smart, Smartware Computing\r\n"); } return runok; } @@ -265,43 +273,58 @@ return foundCount; } -/// Initialize the CommandProcessor +/// Init is the first function to call to configure the CommandProcessor. /// -/// This initializes the CommandProcessor by adding the built-in menus +/// This function has a number of parameters, which make the CommandProcessor +/// quite flexible. /// -/// @param addDefaultMenu configures it to add the Help, About, and Exit menus -/// @param bufSize configures the size of the longest command, which must be -/// greater than 6 (the size of "About\0"). -/// @returns initok if it successfully initialized the CommandProcessor -/// @returns initfailed if it could not allocate memory +/// @param SignOnBanner function, which is used as a signon banner +/// @param config enables various default menu items, based on the bit values, combine the following: +/// \li CFG_ENABLE_TERMINATE - enables the Exit command +/// \li CFG_ENABLE_SYSTEM - enables system commands Echo, Help, etc. +/// \li CFG_ECHO_ON - initialize with echo on +/// \li CFG_CASE_INSENSITIVE - Command Parser is case insensitive +/// @param maxCmdLen sizes the buffer, and is the maximum number of characters in a single +/// command, including all command arguments +/// @param kbhit is a user provided function to detect if a character is available for the CommandProcessor, +/// and when using standard io, you can typically use kbhit, or _kbhit as your system provides. +/// @param getch is a user provided function that provides a single character to the CommandProcessor +/// @param putch is a user provided function that permits the CommandProcessor to output a character +/// @param puts is a user provided function that permits the CommandProcessor to output a string +/// to which is automatically appended a \\n +/// @returns INITRESULT_T to indicate if the init was successful or failed /// INITRESULT_T CommandProcessor_Init( - int addDefaultMenu, - int caseinsensitive, - int echo, + CMD_T (*SignOnBanner), + CONFIG_T config, int maxCmdLen, int (*kbhit)(void), int (*getch)(void), int (*putch)(int ch), int (*puts)(const char * s) ) { + if (SignOnBanner) { + CommandProcessor.Add(SignOnBanner); + cfg.SignOnBanner = SignOnBanner; + cfg.showSignOnBanner = 1; + } if (maxCmdLen < 6) maxCmdLen = 6; buffer = (char *)malloc(maxCmdLen+1); cfg.bufferSize = maxCmdLen; if (buffer) { - if (addDefaultMenu & 0x0008) + if (config & CFG_ENABLE_SYSTEM) + { CommandProcessor.Add(&QuestionMenu); - if (addDefaultMenu & 0x0008) CommandProcessor.Add(&HelpMenu); - if (addDefaultMenu & 0x0004) CommandProcessor.Add(&EchoMenu); - if (addDefaultMenu & 0x0002) - CommandProcessor.Add(&AboutMenu); - if (addDefaultMenu & 0x0001) + } + if (config & CFG_ENABLE_TERMINATE) CommandProcessor.Add(&ExitMenu); - cfg.caseinsensitive = caseinsensitive; - cfg.echo = echo; + //if (addDefaultMenu & 0x0002) + // CommandProcessor.Add(&AboutMenu); + cfg.caseinsensitive = (config & CFG_CASE_INSENSITIVE) ? 1 : 0; + cfg.echo = (config & CFG_ECHO_ON) ? 1 : 0; cfg.kbhit = kbhit; cfg.getch = getch; cfg.putch = putch; @@ -344,9 +367,14 @@ prev = ptr; ptr = ptr->next; } - prev->next = temp; - prev = temp; - prev->next = ptr; + if (prev == head) { + head = temp; + head->next = prev; + } else { + prev->next = temp; + prev = temp; + prev->next = ptr; + } return addok; } @@ -371,6 +399,10 @@ CMD_T *cbk = NULL; char * params = NULL; + if (cfg.showSignOnBanner) { + cfg.SignOnBanner->callback(""); + cfg.showSignOnBanner = 0; + } if (showPrompt && cfg.echo) { cfg.putch('>'); showPrompt = FALSE; @@ -452,7 +484,6 @@ return val; } - static RUNRESULT_T CommandProcessor_Echo(int echo) { cfg.echo = echo; return runok;