The CommandProcessor is the interface to install a run-time menu into an embedded system.
Dependents: A_CANAdapter USB2I2C
CommandProcessor.h@15:5f30da93e3e2, 2011-10-30 (annotated)
- Committer:
- WiredHome
- Date:
- Sun Oct 30 19:57:39 2011 +0000
- Revision:
- 15:5f30da93e3e2
- Parent:
- 14:7971c8bd3f11
- Child:
- 16:4ce4f55213ac
v1.05 Adapted for ANSI (VT100) cursor keys to access the history.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
WiredHome | 0:198f53da1bc8 | 1 | /// @file CommandProcessor.h defined the interface to the CommandProcessor |
WiredHome | 0:198f53da1bc8 | 2 | /// |
WiredHome | 10:9e52bd1a4a71 | 3 | /// @mainpage The CommandProcessor |
WiredHome | 10:9e52bd1a4a71 | 4 | /// |
WiredHome | 0:198f53da1bc8 | 5 | /// The CommandProcessor is the interface to install a run-time menu into an embedded system. |
WiredHome | 0:198f53da1bc8 | 6 | /// This contains the complete interface to the CommandProcessor. |
WiredHome | 0:198f53da1bc8 | 7 | /// |
WiredHome | 15:5f30da93e3e2 | 8 | /// @version 1.05 |
WiredHome | 0:198f53da1bc8 | 9 | /// |
WiredHome | 0:198f53da1bc8 | 10 | /// @note The CommandProcessor is text-based, because it is intended to interact with a |
WiredHome | 0:198f53da1bc8 | 11 | /// user. |
WiredHome | 0:198f53da1bc8 | 12 | /// |
WiredHome | 0:198f53da1bc8 | 13 | /// The menu is designed to be interactively accessed, perhaps via a console interface |
WiredHome | 0:198f53da1bc8 | 14 | /// or a serial port. The actual interface to the user is provided by the application |
WiredHome | 0:198f53da1bc8 | 15 | /// during initialization, so it can be connected to a serial port, or it could |
WiredHome | 0:198f53da1bc8 | 16 | /// be interface to CAN, telnet, or by some other method. |
WiredHome | 0:198f53da1bc8 | 17 | /// |
WiredHome | 0:198f53da1bc8 | 18 | /// The CommandProcessor has a few special features: |
WiredHome | 0:198f53da1bc8 | 19 | /// \li If the minimum number of characters of a command have been entered, the |
WiredHome | 0:198f53da1bc8 | 20 | /// user does not have to type the entire command. (e.g. 'He' will execute |
WiredHome | 0:198f53da1bc8 | 21 | /// the command for 'Help', if no other command beings with 'He'). |
WiredHome | 0:198f53da1bc8 | 22 | /// \li If the user does not type the entire set of characters, the command |
WiredHome | 0:198f53da1bc8 | 23 | /// will be rewritten to the output device with the entire command word. |
WiredHome | 0:198f53da1bc8 | 24 | /// \li The user is not permitted to enter an incorrect command (e.g. If 'Help' |
WiredHome | 0:198f53da1bc8 | 25 | /// is the only command started with 'Hel', the user cannot enter 'Heu'. |
WiredHome | 0:198f53da1bc8 | 26 | /// The CommandProcessor will trap the 'u' and issue a beep). |
WiredHome | 0:198f53da1bc8 | 27 | /// \li Simple editing of parameters to commands is permitted with \<bs\> to |
WiredHome | 0:198f53da1bc8 | 28 | /// erase incorrect text. |
WiredHome | 0:198f53da1bc8 | 29 | /// \li Tab completion of a command is available - so long as the user has |
WiredHome | 4:283e35536097 | 30 | /// typed at least the minimum number of unique characters. (e.g. 'He\<tab\>' |
WiredHome | 0:198f53da1bc8 | 31 | /// will be replaced with 'Help') |
WiredHome | 14:7971c8bd3f11 | 32 | /// \li Command cancellation is available - just enter the \<esc\> key and |
WiredHome | 0:198f53da1bc8 | 33 | /// the buffer is erased. |
WiredHome | 0:198f53da1bc8 | 34 | /// \li The user is not permitted to enter text longer than the defined buffer, |
WiredHome | 0:198f53da1bc8 | 35 | /// to avoid buffer overrun and the possible memory damaging results. |
WiredHome | 0:198f53da1bc8 | 36 | /// |
WiredHome | 0:198f53da1bc8 | 37 | /// The CommandProcessor is designed as a set of C functions, which makes it |
WiredHome | 0:198f53da1bc8 | 38 | /// reusable in more systems (as C++ compilers are not always available for |
WiredHome | 0:198f53da1bc8 | 39 | /// all micros). |
WiredHome | 0:198f53da1bc8 | 40 | /// |
WiredHome | 0:198f53da1bc8 | 41 | /// Example: |
WiredHome | 0:198f53da1bc8 | 42 | /// @code |
WiredHome | 0:198f53da1bc8 | 43 | /// extern "C" { |
WiredHome | 0:198f53da1bc8 | 44 | /// #include "CommandProcessor.h" |
WiredHome | 0:198f53da1bc8 | 45 | /// } |
WiredHome | 0:198f53da1bc8 | 46 | /// |
WiredHome | 10:9e52bd1a4a71 | 47 | /// RUNRESULT_T SignOnBanner(char *p); |
WiredHome | 10:9e52bd1a4a71 | 48 | /// const CMD_T SignOnBannerCmd = { |
WiredHome | 10:9e52bd1a4a71 | 49 | /// "About", "About this program ('About ?' for more details)", |
WiredHome | 10:9e52bd1a4a71 | 50 | /// SignOnBanner, invisible}; |
WiredHome | 10:9e52bd1a4a71 | 51 | /// |
WiredHome | 0:198f53da1bc8 | 52 | /// RUNRESULT_T Who(char *p); |
WiredHome | 7:0f058d664b21 | 53 | /// const CMD_T WhoCmd = { |
WiredHome | 10:9e52bd1a4a71 | 54 | /// "who", "Shows who is logged on, or 'who id' for specifics", |
WiredHome | 10:9e52bd1a4a71 | 55 | /// Who, visible}; |
WiredHome | 10:9e52bd1a4a71 | 56 | /// |
WiredHome | 10:9e52bd1a4a71 | 57 | /// RUNRESULT_T SignOnBanner(char *p) |
WiredHome | 10:9e52bd1a4a71 | 58 | /// { |
WiredHome | 15:5f30da93e3e2 | 59 | /// puts("\r\nThis great program was built " __DATE__ " " __TIME__ "."); |
WiredHome | 10:9e52bd1a4a71 | 60 | /// if (*p == '?') |
WiredHome | 10:9e52bd1a4a71 | 61 | /// puts("\r\nMore details shown here.\r\n"); |
WiredHome | 15:5f30da93e3e2 | 62 | /// return runok; |
WiredHome | 10:9e52bd1a4a71 | 63 | /// } |
WiredHome | 0:198f53da1bc8 | 64 | /// RUNRESULT_T Who(char *p) |
WiredHome | 0:198f53da1bc8 | 65 | /// { |
WiredHome | 4:283e35536097 | 66 | /// printf("\r\nwho...\r\n"); |
WiredHome | 4:283e35536097 | 67 | /// if (*p) |
WiredHome | 4:283e35536097 | 68 | /// printf(" Sorry, no help for [%s]\r\n", p); |
WiredHome | 4:283e35536097 | 69 | /// return runok; |
WiredHome | 0:198f53da1bc8 | 70 | /// } |
WiredHome | 0:198f53da1bc8 | 71 | /// |
WiredHome | 0:198f53da1bc8 | 72 | /// int main(int argc, char* argv[]) |
WiredHome | 0:198f53da1bc8 | 73 | /// { |
WiredHome | 4:283e35536097 | 74 | /// CMDP_T * cp = GetCommandProcessor(); |
WiredHome | 10:9e52bd1a4a71 | 75 | /// cp->Init(&SignOnBanner, |
WiredHome | 10:9e52bd1a4a71 | 76 | /// CFG_ENABLE_TERMINATE | CFG_ENABLE_SYSTEM, |
WiredHome | 10:9e52bd1a4a71 | 77 | /// 50, _kbhit, _getch, _putch, printf); |
WiredHome | 4:283e35536097 | 78 | /// cp->Add(&WhoCmd); |
WiredHome | 0:198f53da1bc8 | 79 | /// |
WiredHome | 4:283e35536097 | 80 | /// while (cp->Run()) |
WiredHome | 4:283e35536097 | 81 | /// { |
WiredHome | 4:283e35536097 | 82 | /// ; |
WiredHome | 4:283e35536097 | 83 | /// } |
WiredHome | 4:283e35536097 | 84 | /// cp->End(); |
WiredHome | 4:283e35536097 | 85 | /// return 0; |
WiredHome | 0:198f53da1bc8 | 86 | /// } |
WiredHome | 0:198f53da1bc8 | 87 | /// @endcode |
WiredHome | 0:198f53da1bc8 | 88 | /// |
WiredHome | 12:a8c56bf811b9 | 89 | /// |
WiredHome | 12:a8c56bf811b9 | 90 | /// @note Copyright &copr; 2011 by Smartware Computing, all rights reserved. |
WiredHome | 12:a8c56bf811b9 | 91 | /// Individuals may use this application for evaluation or non-commercial |
WiredHome | 12:a8c56bf811b9 | 92 | /// purposes. Within this restriction, changes may be made to this application |
WiredHome | 12:a8c56bf811b9 | 93 | /// as long as this copyright notice is retained. The user shall make |
WiredHome | 12:a8c56bf811b9 | 94 | /// clear that their work is a derived work, and not the original. |
WiredHome | 12:a8c56bf811b9 | 95 | /// Users of this application and sources accept this application "as is" and |
WiredHome | 12:a8c56bf811b9 | 96 | /// shall hold harmless Smartware Computing, for any undesired results while |
WiredHome | 12:a8c56bf811b9 | 97 | /// using this application - whether real or imagined. |
WiredHome | 12:a8c56bf811b9 | 98 | /// |
WiredHome | 12:a8c56bf811b9 | 99 | /// @author David Smart, Smartware Computing |
WiredHome | 0:198f53da1bc8 | 100 | /// |
WiredHome | 10:9e52bd1a4a71 | 101 | /// @note |
WiredHome | 10:9e52bd1a4a71 | 102 | /// History |
WiredHome | 15:5f30da93e3e2 | 103 | /// v1.05 20111030 |
WiredHome | 15:5f30da93e3e2 | 104 | /// \li Added support for VT100 cursor code for up/down history access |
WiredHome | 14:7971c8bd3f11 | 105 | /// v1.04 1 October 2011 |
WiredHome | 14:7971c8bd3f11 | 106 | /// \li Added configurable command line history for easy recall of previous commands |
WiredHome | 14:7971c8bd3f11 | 107 | /// \li Clean up dead-code |
WiredHome | 12:a8c56bf811b9 | 108 | /// v1.03 29 May 2011 |
WiredHome | 12:a8c56bf811b9 | 109 | /// \li Slightly improved internal documentation. No external interfaces affected. |
WiredHome | 12:a8c56bf811b9 | 110 | /// v1.02 2 May 2011 |
WiredHome | 12:a8c56bf811b9 | 111 | /// \li Track the longest command when added, so that the help printout |
WiredHome | 12:a8c56bf811b9 | 112 | /// is more nicely formatted. |
WiredHome | 10:9e52bd1a4a71 | 113 | /// v1.01 22 April 2011 |
WiredHome | 10:9e52bd1a4a71 | 114 | /// \li Moving 'About' content into the extended help, |
WiredHome | 10:9e52bd1a4a71 | 115 | /// to free 'About' for application code that uses this library. |
WiredHome | 10:9e52bd1a4a71 | 116 | /// \li Altered the _init api to permit a signon banner of the users choice |
WiredHome | 10:9e52bd1a4a71 | 117 | /// and a config parameter for other features. |
WiredHome | 10:9e52bd1a4a71 | 118 | /// |
WiredHome | 10:9e52bd1a4a71 | 119 | /// v1.0 March 2011 |
WiredHome | 10:9e52bd1a4a71 | 120 | /// \li Initial version |
WiredHome | 10:9e52bd1a4a71 | 121 | /// |
WiredHome | 0:198f53da1bc8 | 122 | #ifndef COMMANDPROCESSOR_H |
WiredHome | 0:198f53da1bc8 | 123 | #define COMMANDPROCESSOR_H |
WiredHome | 0:198f53da1bc8 | 124 | |
WiredHome | 15:5f30da93e3e2 | 125 | #define VERSION "1.05" |
WiredHome | 15:5f30da93e3e2 | 126 | |
WiredHome | 0:198f53da1bc8 | 127 | #ifndef TRUE |
WiredHome | 4:283e35536097 | 128 | #define TRUE 1 ///< Definition for TRUE, if not already provided |
WiredHome | 4:283e35536097 | 129 | #define FALSE 0 ///< Definition for FALSE, if not already provided |
WiredHome | 0:198f53da1bc8 | 130 | #endif |
WiredHome | 0:198f53da1bc8 | 131 | |
WiredHome | 0:198f53da1bc8 | 132 | /// @brief This type determines if menu items are visible to the Help system, or hidden. |
WiredHome | 0:198f53da1bc8 | 133 | /// @details This is used in the definition of the menu item. |
WiredHome | 0:198f53da1bc8 | 134 | typedef enum |
WiredHome | 0:198f53da1bc8 | 135 | { |
WiredHome | 4:283e35536097 | 136 | invisible, ///< use this value to have invisible (hidden) a menu in the Help |
WiredHome | 4:283e35536097 | 137 | visible ///< use this value to have visible a menu in the Help |
WiredHome | 4:283e35536097 | 138 | } VISIBLE_T; ///< This determines if menu items are made visible in the Help system. |
WiredHome | 0:198f53da1bc8 | 139 | |
WiredHome | 0:198f53da1bc8 | 140 | /// Callbacks that are executed return a value to indicate if the menu |
WiredHome | 0:198f53da1bc8 | 141 | /// should remain active |
WiredHome | 0:198f53da1bc8 | 142 | typedef enum |
WiredHome | 0:198f53da1bc8 | 143 | { |
WiredHome | 4:283e35536097 | 144 | runexit, ///< use this return value to cause the menu (perhaps the program) to exit |
WiredHome | 4:283e35536097 | 145 | runok ///< use this return value to keep the menu running |
WiredHome | 0:198f53da1bc8 | 146 | } RUNRESULT_T; |
WiredHome | 0:198f53da1bc8 | 147 | |
WiredHome | 0:198f53da1bc8 | 148 | /// Adding items to the menu can succeed, or fail. |
WiredHome | 0:198f53da1bc8 | 149 | typedef enum |
WiredHome | 0:198f53da1bc8 | 150 | { |
WiredHome | 4:283e35536097 | 151 | addfailed, ///< this indicates the menu was not added (usually failure to allocate memory) |
WiredHome | 4:283e35536097 | 152 | addok ///< this indicates the menu was successfully added |
WiredHome | 0:198f53da1bc8 | 153 | } ADDRESULT_T; |
WiredHome | 0:198f53da1bc8 | 154 | |
WiredHome | 0:198f53da1bc8 | 155 | /// Initialization can succeed, or fail. |
WiredHome | 0:198f53da1bc8 | 156 | typedef enum |
WiredHome | 0:198f53da1bc8 | 157 | { |
WiredHome | 4:283e35536097 | 158 | initfailed, ///< this indicates that the menu system was not initialized (usually failure to allocate memory) |
WiredHome | 4:283e35536097 | 159 | initok ///< this indicates that the menu system was successfully initialized |
WiredHome | 0:198f53da1bc8 | 160 | } INITRESULT_T; |
WiredHome | 0:198f53da1bc8 | 161 | |
WiredHome | 11:4a3cd3f2183b | 162 | /// Configuration options to control startup and some runtime behavior |
WiredHome | 11:4a3cd3f2183b | 163 | /// |
WiredHome | 11:4a3cd3f2183b | 164 | /// Permissible values are created by combining |
WiredHome | 11:4a3cd3f2183b | 165 | /// \li CFG_ENABLE_TERMINATE |
WiredHome | 11:4a3cd3f2183b | 166 | /// \li CFG_ENABLE_SYSTEM |
WiredHome | 11:4a3cd3f2183b | 167 | /// \li CFG_ECHO_ON |
WiredHome | 11:4a3cd3f2183b | 168 | /// \li CFG_CASE_INSENSITIVE |
WiredHome | 10:9e52bd1a4a71 | 169 | typedef unsigned long CONFIG_T; |
WiredHome | 10:9e52bd1a4a71 | 170 | |
WiredHome | 11:4a3cd3f2183b | 171 | #define CFG_ENABLE_TERMINATE 0x0001 ///<- Enable the exit option |
WiredHome | 11:4a3cd3f2183b | 172 | #define CFG_ENABLE_SYSTEM 0x0002 ///<- Enable various system options (help, etc) |
WiredHome | 11:4a3cd3f2183b | 173 | #define CFG_ECHO_ON 0x2000 ///<- Initialize with command prompt Echo on |
WiredHome | 11:4a3cd3f2183b | 174 | #define CFG_CASE_INSENSITIVE 0x4000 ///<- Enable case insensitive command entry |
WiredHome | 10:9e52bd1a4a71 | 175 | |
WiredHome | 10:9e52bd1a4a71 | 176 | |
WiredHome | 0:198f53da1bc8 | 177 | /// This is the type for the basic callback, when a menu pick is activated. |
WiredHome | 0:198f53da1bc8 | 178 | /// |
WiredHome | 0:198f53da1bc8 | 179 | /// The callback function is executed when a command is entered on the menu and \<enter\> |
WiredHome | 0:198f53da1bc8 | 180 | /// is signaled. If there is any additional text entered on the commandline, it is |
WiredHome | 0:198f53da1bc8 | 181 | /// passed to the callback. |
WiredHome | 0:198f53da1bc8 | 182 | /// |
WiredHome | 0:198f53da1bc8 | 183 | /// example: |
WiredHome | 4:283e35536097 | 184 | /// "Test1 ab c 123 567" |
WiredHome | 0:198f53da1bc8 | 185 | /// If "Test1" is a valid command, the corresponding function would be called |
WiredHome | 4:283e35536097 | 186 | /// passing to that function the string "ab c 123 567". Note that the delimiter space |
WiredHome | 10:9e52bd1a4a71 | 187 | /// was removed. |
WiredHome | 0:198f53da1bc8 | 188 | /// |
WiredHome | 10:9e52bd1a4a71 | 189 | /// @param p is a pointer to a character string |
WiredHome | 10:9e52bd1a4a71 | 190 | /// @returns RUNRESULT_T to indicate if the CommandProcessor should continue |
WiredHome | 0:198f53da1bc8 | 191 | /// |
WiredHome | 0:198f53da1bc8 | 192 | typedef RUNRESULT_T (*MENU_CALLBACK)(char *p); |
WiredHome | 0:198f53da1bc8 | 193 | |
WiredHome | 0:198f53da1bc8 | 194 | /// This defines the type for a single item to be added to the CommandProcessor menu. |
WiredHome | 0:198f53da1bc8 | 195 | /// |
WiredHome | 0:198f53da1bc8 | 196 | /// This is defined in the application code, and a pointer to this item is passed to the |
WiredHome | 0:198f53da1bc8 | 197 | /// CommandProcessor to add this item to the menu system. |
WiredHome | 0:198f53da1bc8 | 198 | /// |
WiredHome | 0:198f53da1bc8 | 199 | /// example: |
WiredHome | 10:9e52bd1a4a71 | 200 | /// @code |
WiredHome | 0:198f53da1bc8 | 201 | /// const CMD_T WhoCmd = {"who", "Shows who is logged on, or 'who id' for specifics", Who, visible}; |
WiredHome | 0:198f53da1bc8 | 202 | /// @endcode |
WiredHome | 0:198f53da1bc8 | 203 | /// |
WiredHome | 0:198f53da1bc8 | 204 | typedef const struct |
WiredHome | 0:198f53da1bc8 | 205 | { |
WiredHome | 4:283e35536097 | 206 | char * command; ///< a pointer to the command to match (e.g. 'Help') |
WiredHome | 4:283e35536097 | 207 | char * helptext; ///< a pointer to some text to show when user types 'Help' |
WiredHome | 4:283e35536097 | 208 | MENU_CALLBACK callback; ///< the function to call when user enters this command |
WiredHome | 4:283e35536097 | 209 | VISIBLE_T visible; ///< a flag that determines if this command is visible in Help. |
WiredHome | 0:198f53da1bc8 | 210 | } CMD_T; |
WiredHome | 0:198f53da1bc8 | 211 | |
WiredHome | 0:198f53da1bc8 | 212 | /// This is the CommandProcessor interface from the user application. |
WiredHome | 0:198f53da1bc8 | 213 | /// |
WiredHome | 10:9e52bd1a4a71 | 214 | /// The user aquires a handle to this set of functions with the GetCommandProcessor command. |
WiredHome | 0:198f53da1bc8 | 215 | /// After this, the user may then initialize the CommandProcessor, add items to the menu, |
WiredHome | 0:198f53da1bc8 | 216 | /// cause the CommandProcessor to run periodically, and if need be the application can end |
WiredHome | 0:198f53da1bc8 | 217 | /// the CommandProcessor. |
WiredHome | 0:198f53da1bc8 | 218 | /// |
WiredHome | 0:198f53da1bc8 | 219 | typedef const struct |
WiredHome | 0:198f53da1bc8 | 220 | { |
WiredHome | 4:283e35536097 | 221 | /// Init is the first function to call to configure the CommandProcessor. |
WiredHome | 4:283e35536097 | 222 | /// |
WiredHome | 4:283e35536097 | 223 | /// This function has a number of parameters, which make the CommandProcessor quite flexible. |
WiredHome | 4:283e35536097 | 224 | /// |
WiredHome | 15:5f30da93e3e2 | 225 | /// @param SignOnBanner function, which is used as a signon banner |
WiredHome | 10:9e52bd1a4a71 | 226 | /// @param config enables various default menu items, based on the bit values, combine the following: |
WiredHome | 15:5f30da93e3e2 | 227 | /// \li CFG_ENABLE_TERMINATE - enables the Exit command |
WiredHome | 15:5f30da93e3e2 | 228 | /// \li CFG_ENABLE_SYSTEM - enables system commands Echo, Help, etc. |
WiredHome | 15:5f30da93e3e2 | 229 | /// \li CFG_ECHO_ON - initialize with echo on |
WiredHome | 15:5f30da93e3e2 | 230 | /// \li CFG_CASE_INSENSITIVE - Command Parser is case insensitive |
WiredHome | 15:5f30da93e3e2 | 231 | /// @param maxCmdLen sizes the buffer, and is the maximum number of characters in a single |
WiredHome | 15:5f30da93e3e2 | 232 | /// command, including all command arguments |
WiredHome | 15:5f30da93e3e2 | 233 | /// @param historyLen sets the number of items that can be recalled from history |
WiredHome | 10:9e52bd1a4a71 | 234 | /// @param kbhit is a user provided function to detect if a character is available for the CommandProcessor, |
WiredHome | 10:9e52bd1a4a71 | 235 | /// and when using standard io, you can typically use kbhit, or _kbhit as your system provides. |
WiredHome | 10:9e52bd1a4a71 | 236 | /// @param getch is a user provided function that provides a single character to the CommandProcessor |
WiredHome | 10:9e52bd1a4a71 | 237 | /// @param putch is a user provided function that permits the CommandProcessor to output a character |
WiredHome | 10:9e52bd1a4a71 | 238 | /// @param puts is a user provided function that permits the CommandProcessor to output a string |
WiredHome | 4:283e35536097 | 239 | /// to which is automatically appended a \\n |
WiredHome | 4:283e35536097 | 240 | /// @returns INITRESULT_T to indicate if the init was successful or failed |
WiredHome | 15:5f30da93e3e2 | 241 | /// |
WiredHome | 4:283e35536097 | 242 | INITRESULT_T (*Init)( |
WiredHome | 15:5f30da93e3e2 | 243 | CMD_T *SignOnBanner, |
WiredHome | 10:9e52bd1a4a71 | 244 | CONFIG_T config, |
WiredHome | 6:1a0512faa75d | 245 | int maxCmdLen, |
WiredHome | 15:5f30da93e3e2 | 246 | int historyLen, |
WiredHome | 4:283e35536097 | 247 | int (*kbhit)(void), |
WiredHome | 4:283e35536097 | 248 | int (*getch)(void), |
WiredHome | 4:283e35536097 | 249 | int (*putch)(int ch), |
WiredHome | 4:283e35536097 | 250 | int (*puts)(const char * s) |
WiredHome | 4:283e35536097 | 251 | ); |
WiredHome | 0:198f53da1bc8 | 252 | |
WiredHome | 4:283e35536097 | 253 | /// Add is called to add an item to the CommandProcessor menu |
WiredHome | 4:283e35536097 | 254 | /// |
WiredHome | 4:283e35536097 | 255 | /// This passes in a reference to a user provided CMD_T item, which is |
WiredHome | 4:283e35536097 | 256 | /// added to the menu system. |
WiredHome | 4:283e35536097 | 257 | /// |
WiredHome | 6:1a0512faa75d | 258 | /// @param m is a pointer to the user provided menu |
WiredHome | 6:1a0512faa75d | 259 | /// @returns ADDRESULT_T to indicate if the add was successful or failed |
WiredHome | 4:283e35536097 | 260 | /// |
WiredHome | 4:283e35536097 | 261 | ADDRESULT_T (*Add)(CMD_T * m); |
WiredHome | 0:198f53da1bc8 | 262 | |
WiredHome | 4:283e35536097 | 263 | /// Run is the primary runtime entry point for the CommandProcessor. |
WiredHome | 4:283e35536097 | 264 | /// |
WiredHome | 4:283e35536097 | 265 | /// This function should be called periodically - fast enough not to miss user input. |
WiredHome | 4:283e35536097 | 266 | /// This function always returns, so if not character is available for the CommandProcessor |
WiredHome | 4:283e35536097 | 267 | /// it will return very fast. If there is a character (as detected by the kbhit callback), |
WiredHome | 4:283e35536097 | 268 | /// then it will process that character and determine what to do. It may then execute one |
WiredHome | 4:283e35536097 | 269 | /// of the menu functions. In this case, CPU cycles spent are based on the function |
WiredHome | 4:283e35536097 | 270 | /// being executed. |
WiredHome | 4:283e35536097 | 271 | /// |
WiredHome | 4:283e35536097 | 272 | /// @returns RUNRESULT_T to indicate if the CommandProcessor should remain active or if the |
WiredHome | 4:283e35536097 | 273 | /// command that was executed is requesting the CommandProcessor to exit. |
WiredHome | 4:283e35536097 | 274 | /// |
WiredHome | 4:283e35536097 | 275 | RUNRESULT_T (*Run)(void); |
WiredHome | 6:1a0512faa75d | 276 | |
WiredHome | 6:1a0512faa75d | 277 | /// Echo command permits turning the echo on and off |
WiredHome | 6:1a0512faa75d | 278 | /// |
WiredHome | 6:1a0512faa75d | 279 | /// When interactive with the user, it is best to have echo on, so they can see |
WiredHome | 6:1a0512faa75d | 280 | /// the prompt, but if this is simply slaved to another program, then the echo |
WiredHome | 6:1a0512faa75d | 281 | /// might need to be off to best manage the stream. |
WiredHome | 6:1a0512faa75d | 282 | /// |
WiredHome | 6:1a0512faa75d | 283 | /// @param echo turns the echo on (non-zero) or off (zero) |
WiredHome | 6:1a0512faa75d | 284 | /// @returns RUNRESULT_T to indicate if the CommandProcessor should remain active or if the |
WiredHome | 6:1a0512faa75d | 285 | /// command that was executed is requesting the CommandProcessor to exit. |
WiredHome | 6:1a0512faa75d | 286 | /// |
WiredHome | 6:1a0512faa75d | 287 | RUNRESULT_T (*Echo)(int echo); |
WiredHome | 0:198f53da1bc8 | 288 | |
WiredHome | 4:283e35536097 | 289 | /// End if the function to be called when you want to gracefully end the CommandProcessor. |
WiredHome | 4:283e35536097 | 290 | /// |
WiredHome | 4:283e35536097 | 291 | /// Calling this function causes the CommandProcessor to free any memory that was previously |
WiredHome | 4:283e35536097 | 292 | /// allocated by the Init and Add functions. |
WiredHome | 4:283e35536097 | 293 | RUNRESULT_T (*End)(void); ///< Called to shutdown the processor |
WiredHome | 0:198f53da1bc8 | 294 | } CMDP_T; |
WiredHome | 0:198f53da1bc8 | 295 | |
WiredHome | 3:7c9993cac92b | 296 | |
WiredHome | 3:7c9993cac92b | 297 | /// The CommandProcessor is the interface to install a run-time menu into an embedded system. |
WiredHome | 3:7c9993cac92b | 298 | /// This contains the complete interface to the CommandProcessor. |
WiredHome | 3:7c9993cac92b | 299 | /// |
WiredHome | 15:5f30da93e3e2 | 300 | /// @version 1.05 |
WiredHome | 3:7c9993cac92b | 301 | /// |
WiredHome | 3:7c9993cac92b | 302 | /// @note The CommandProcessor is text-based, because it is intended to interact with a |
WiredHome | 3:7c9993cac92b | 303 | /// user. |
WiredHome | 3:7c9993cac92b | 304 | /// |
WiredHome | 3:7c9993cac92b | 305 | /// The menu is designed to be interactively accessed, perhaps via a console interface |
WiredHome | 3:7c9993cac92b | 306 | /// or a serial port. The actual interface to the user is provided by the application |
WiredHome | 3:7c9993cac92b | 307 | /// during initialization, so it can be connected to a serial port, or it could |
WiredHome | 3:7c9993cac92b | 308 | /// be interface to CAN, telnet, or by some other method. |
WiredHome | 3:7c9993cac92b | 309 | /// |
WiredHome | 3:7c9993cac92b | 310 | /// The CommandProcessor has a few special features: |
WiredHome | 3:7c9993cac92b | 311 | /// \li If the minimum number of characters of a command have been entered, the |
WiredHome | 3:7c9993cac92b | 312 | /// user does not have to type the entire command. (e.g. 'He' will execute |
WiredHome | 3:7c9993cac92b | 313 | /// the command for 'Help', if no other command beings with 'He'). |
WiredHome | 3:7c9993cac92b | 314 | /// \li If the user does not type the entire set of characters, the command |
WiredHome | 3:7c9993cac92b | 315 | /// will be rewritten to the output device with the entire command word. |
WiredHome | 3:7c9993cac92b | 316 | /// \li The user is not permitted to enter an incorrect command (e.g. If 'Help' |
WiredHome | 3:7c9993cac92b | 317 | /// is the only command started with 'Hel', the user cannot enter 'Heu'. |
WiredHome | 3:7c9993cac92b | 318 | /// The CommandProcessor will trap the 'u' and issue a beep). |
WiredHome | 3:7c9993cac92b | 319 | /// \li Simple editing of parameters to commands is permitted with \<bs\> to |
WiredHome | 3:7c9993cac92b | 320 | /// erase incorrect text. |
WiredHome | 3:7c9993cac92b | 321 | /// \li Tab completion of a command is available - so long as the user has |
WiredHome | 4:283e35536097 | 322 | /// typed at least the minimum number of unique characters. (e.g. 'He\<tab\>' |
WiredHome | 3:7c9993cac92b | 323 | /// will be replaced with 'Help') |
WiredHome | 4:283e35536097 | 324 | /// \li Command cancellation is available - just enter the \<esc\> key and |
WiredHome | 3:7c9993cac92b | 325 | /// the buffer is erased. |
WiredHome | 3:7c9993cac92b | 326 | /// \li The user is not permitted to enter text longer than the defined buffer, |
WiredHome | 3:7c9993cac92b | 327 | /// to avoid buffer overrun and the possible memory damaging results. |
WiredHome | 3:7c9993cac92b | 328 | /// |
WiredHome | 3:7c9993cac92b | 329 | /// The CommandProcessor is designed as a set of C functions, which makes it |
WiredHome | 3:7c9993cac92b | 330 | /// reusable in more systems (as C++ compilers are not always available for |
WiredHome | 3:7c9993cac92b | 331 | /// all micros). |
WiredHome | 3:7c9993cac92b | 332 | /// |
WiredHome | 3:7c9993cac92b | 333 | /// Example: |
WiredHome | 3:7c9993cac92b | 334 | /// @code |
WiredHome | 3:7c9993cac92b | 335 | /// extern "C" { |
WiredHome | 3:7c9993cac92b | 336 | /// #include "CommandProcessor.h" |
WiredHome | 3:7c9993cac92b | 337 | /// } |
WiredHome | 3:7c9993cac92b | 338 | /// |
WiredHome | 10:9e52bd1a4a71 | 339 | /// RUNRESULT_T About(char *p); |
WiredHome | 10:9e52bd1a4a71 | 340 | /// const CMD_T AboutCmd = {"About", "About this program", About, invisible}; |
WiredHome | 3:7c9993cac92b | 341 | /// RUNRESULT_T Who(char *p); |
WiredHome | 3:7c9993cac92b | 342 | /// const CMD_T WhoCmd = {"who", "Shows who is logged on, or 'who id' for specifics", Who, visible}; |
WiredHome | 3:7c9993cac92b | 343 | /// |
WiredHome | 10:9e52bd1a4a71 | 344 | /// RUNRESULT_T About(char *p) |
WiredHome | 10:9e52bd1a4a71 | 345 | /// { |
WiredHome | 10:9e52bd1a4a71 | 346 | /// (void)p; |
WiredHome | 10:9e52bd1a4a71 | 347 | /// puts("\r\nThis program does really good things for the user.\r\n"); |
WiredHome | 10:9e52bd1a4a71 | 348 | /// } |
WiredHome | 10:9e52bd1a4a71 | 349 | /// |
WiredHome | 3:7c9993cac92b | 350 | /// RUNRESULT_T Who(char *p) |
WiredHome | 3:7c9993cac92b | 351 | /// { |
WiredHome | 4:283e35536097 | 352 | /// printf("\r\nwho...\r\n"); |
WiredHome | 4:283e35536097 | 353 | /// if (*p) |
WiredHome | 4:283e35536097 | 354 | /// printf(" Sorry, no help for [%s]\r\n", p); |
WiredHome | 4:283e35536097 | 355 | /// return runok; |
WiredHome | 3:7c9993cac92b | 356 | /// } |
WiredHome | 3:7c9993cac92b | 357 | /// |
WiredHome | 3:7c9993cac92b | 358 | /// int main(int argc, char* argv[]) |
WiredHome | 3:7c9993cac92b | 359 | /// { |
WiredHome | 4:283e35536097 | 360 | /// CMDP_T * cp = GetCommandProcessor(); |
WiredHome | 10:9e52bd1a4a71 | 361 | /// cp->Init(AboutCmd, CFG_ENABLE_TERMINATE | CFG_ENABLE_SYSTEM | CFG_SIGNON_BANNER, |
WiredHome | 10:9e52bd1a4a71 | 362 | /// 50, |
WiredHome | 10:9e52bd1a4a71 | 363 | /// _kbhit, _getch, _putch, printf); |
WiredHome | 4:283e35536097 | 364 | /// cp->Add(&WhoCmd); |
WiredHome | 3:7c9993cac92b | 365 | /// |
WiredHome | 4:283e35536097 | 366 | /// while (cp->Run()) |
WiredHome | 4:283e35536097 | 367 | /// { |
WiredHome | 4:283e35536097 | 368 | /// ; |
WiredHome | 4:283e35536097 | 369 | /// } |
WiredHome | 4:283e35536097 | 370 | /// cp->End(); |
WiredHome | 4:283e35536097 | 371 | /// return 0; |
WiredHome | 3:7c9993cac92b | 372 | /// } |
WiredHome | 3:7c9993cac92b | 373 | /// @endcode |
WiredHome | 3:7c9993cac92b | 374 | /// |
WiredHome | 3:7c9993cac92b | 375 | /// @note Copyright © 2011 by Smartware Computing, all rights reserved. |
WiredHome | 3:7c9993cac92b | 376 | /// This program may be used by others as long as this copyright notice |
WiredHome | 3:7c9993cac92b | 377 | /// remains intact. |
WiredHome | 3:7c9993cac92b | 378 | /// @author David Smart |
WiredHome | 3:7c9993cac92b | 379 | /// |
WiredHome | 0:198f53da1bc8 | 380 | /// GetCommandProcessor is called to get a handle to the CommandProcessor itself. |
WiredHome | 0:198f53da1bc8 | 381 | /// |
WiredHome | 0:198f53da1bc8 | 382 | /// Call this function to get a handle to the CommandProcessor. After this is done, then |
WiredHome | 0:198f53da1bc8 | 383 | /// you can use that handle to activate the CommandProcessor methods. |
WiredHome | 0:198f53da1bc8 | 384 | /// |
WiredHome | 0:198f53da1bc8 | 385 | /// example: |
WiredHome | 0:198f53da1bc8 | 386 | /// @code |
WiredHome | 4:283e35536097 | 387 | /// CMDP_T * cp = GetCommandProcessor(); |
WiredHome | 10:9e52bd1a4a71 | 388 | /// cp->Init(AboutCmd, CFG_ENABLE_TERMINATE | CFG_ENABLE_SYSTEM | CFG_SIGNON_BANNER, |
WiredHome | 10:9e52bd1a4a71 | 389 | /// 50, |
WiredHome | 10:9e52bd1a4a71 | 390 | /// _kbhit, _getch, _putch, printf); |
WiredHome | 0:198f53da1bc8 | 391 | /// @endcode |
WiredHome | 0:198f53da1bc8 | 392 | /// |
WiredHome | 1:1c81feb2f8bd | 393 | /// @returns CMDP_T a handle to the CommandProcessor |
WiredHome | 0:198f53da1bc8 | 394 | /// |
WiredHome | 0:198f53da1bc8 | 395 | #ifdef WIN32 |
WiredHome | 13:e1880be590c4 | 396 | extern CMDP_T * GetCommandProcessor(void); |
WiredHome | 0:198f53da1bc8 | 397 | #else // This is necessary for the mbed - not sure why. |
WiredHome | 0:198f53da1bc8 | 398 | extern "C" CMDP_T * GetCommandProcessor(void); |
WiredHome | 0:198f53da1bc8 | 399 | #endif |
WiredHome | 0:198f53da1bc8 | 400 | |
WiredHome | 1:1c81feb2f8bd | 401 | #endif // COMMANDPROCESSOR_H |