The CommandProcessor is the interface to install a run-time menu into an embedded system.
Dependents: A_CANAdapter USB2I2C
CommandProcessor.h
00001 /// @file CommandProcessor.h defined the interface to the CommandProcessor 00002 /// 00003 /// @mainpage The CommandProcessor 00004 /// 00005 /// The CommandProcessor is the interface to install a run-time menu into an embedded system. 00006 /// This contains the complete interface to the CommandProcessor. 00007 /// 00008 /// @version 1.05 00009 /// 00010 /// @note The CommandProcessor is text-based, because it is intended to interact with a 00011 /// user. 00012 /// 00013 /// The menu is designed to be interactively accessed, perhaps via a console interface 00014 /// or a serial port. The actual interface to the user is provided by the application 00015 /// during initialization, so it can be connected to a serial port, or it could 00016 /// be interface to CAN, telnet, or by some other method. 00017 /// 00018 /// The CommandProcessor has a few special features: 00019 /// \li If the minimum number of characters of a command have been entered, the 00020 /// user does not have to type the entire command. (e.g. 'He' will execute 00021 /// the command for 'Help', if no other command beings with 'He'). 00022 /// \li If the user does not type the entire set of characters, the command 00023 /// will be rewritten to the output device with the entire command word. 00024 /// \li The user is not permitted to enter an incorrect command (e.g. If 'Help' 00025 /// is the only command started with 'Hel', the user cannot enter 'Heu'. 00026 /// The CommandProcessor will trap the 'u' and issue a beep). 00027 /// \li Simple editing of parameters to commands is permitted with <bs> to 00028 /// erase incorrect text. 00029 /// \li Tab completion of a command is available - so long as the user has 00030 /// typed at least the minimum number of unique characters. (e.g. 'He<tab>' 00031 /// will be replaced with 'Help') 00032 /// \li Command cancellation is available - just enter the <esc> key and 00033 /// the buffer is erased. 00034 /// \li The user is not permitted to enter text longer than the defined buffer, 00035 /// to avoid buffer overrun and the possible memory damaging results. 00036 /// 00037 /// The CommandProcessor is designed as a set of C functions, which makes it 00038 /// reusable in more systems (as C++ compilers are not always available for 00039 /// all micros). 00040 /// 00041 /// Example: 00042 /// @code 00043 /// extern "C" { 00044 /// #include "CommandProcessor.h" 00045 /// } 00046 /// 00047 /// RUNRESULT_T SignOnBanner(char *p); 00048 /// const CMD_T SignOnBannerCmd = { 00049 /// "About", "About this program ('About ?' for more details)", 00050 /// SignOnBanner, invisible}; 00051 /// 00052 /// RUNRESULT_T Who(char *p); 00053 /// const CMD_T WhoCmd = { 00054 /// "who", "Shows who is logged on, or 'who id' for specifics", 00055 /// Who, visible}; 00056 /// 00057 /// RUNRESULT_T SignOnBanner(char *p) 00058 /// { 00059 /// puts("\r\nThis great program was built " __DATE__ " " __TIME__ "."); 00060 /// if (*p == '?') 00061 /// puts("\r\nMore details shown here.\r\n"); 00062 /// return runok; 00063 /// } 00064 /// RUNRESULT_T Who(char *p) 00065 /// { 00066 /// printf("\r\nwho...\r\n"); 00067 /// if (*p) 00068 /// printf(" Sorry, no help for [%s]\r\n", p); 00069 /// return runok; 00070 /// } 00071 /// 00072 /// int main(int argc, char* argv[]) 00073 /// { 00074 /// CMDP_T * cp = GetCommandProcessor(); 00075 /// cp->Init(&SignOnBanner, 00076 /// CFG_ENABLE_TERMINATE | CFG_ENABLE_SYSTEM, 00077 /// 50, _kbhit, _getch, _putch, printf); 00078 /// cp->Add(&WhoCmd); 00079 /// 00080 /// while (cp->Run()) 00081 /// { 00082 /// ; 00083 /// } 00084 /// cp->End(); 00085 /// return 0; 00086 /// } 00087 /// @endcode 00088 /// 00089 /// 00090 /// @note Copyright &copr; 2011 by Smartware Computing, all rights reserved. 00091 /// Individuals may use this application for evaluation or non-commercial 00092 /// purposes. Within this restriction, changes may be made to this application 00093 /// as long as this copyright notice is retained. The user shall make 00094 /// clear that their work is a derived work, and not the original. 00095 /// Users of this application and sources accept this application "as is" and 00096 /// shall hold harmless Smartware Computing, for any undesired results while 00097 /// using this application - whether real or imagined. 00098 /// 00099 /// @author David Smart, Smartware Computing 00100 /// 00101 /// @note 00102 /// History 00103 /// v1.05 20111030 00104 /// \li Added support for VT100 cursor code for up/down history access 00105 /// \li Fixed a bug related to not entering any parameters - causing it to think 00106 /// there were parameters anyway. 00107 /// v1.04 1 October 2011 00108 /// \li Added configurable command line history for easy recall of previous commands 00109 /// \li Clean up dead-code 00110 /// v1.03 29 May 2011 00111 /// \li Slightly improved internal documentation. No external interfaces affected. 00112 /// v1.02 2 May 2011 00113 /// \li Track the longest command when added, so that the help printout 00114 /// is more nicely formatted. 00115 /// v1.01 22 April 2011 00116 /// \li Moving 'About' content into the extended help, 00117 /// to free 'About' for application code that uses this library. 00118 /// \li Altered the _init api to permit a signon banner of the users choice 00119 /// and a config parameter for other features. 00120 /// 00121 /// v1.0 March 2011 00122 /// \li Initial version 00123 /// 00124 #ifndef COMMANDPROCESSOR_H 00125 #define COMMANDPROCESSOR_H 00126 00127 #define VERSION "1.05" 00128 00129 #ifndef TRUE 00130 #define TRUE 1 ///< Definition for TRUE, if not already provided 00131 #define FALSE 0 ///< Definition for FALSE, if not already provided 00132 #endif 00133 00134 /// @brief This type determines if menu items are visible to the Help system, or hidden. 00135 /// @details This is used in the definition of the menu item. 00136 typedef enum 00137 { 00138 invisible, ///< use this value to have invisible (hidden) a menu in the Help 00139 visible ///< use this value to have visible a menu in the Help 00140 } VISIBLE_T; ///< This determines if menu items are made visible in the Help system. 00141 00142 /// Callbacks that are executed return a value to indicate if the menu 00143 /// should remain active 00144 typedef enum 00145 { 00146 runexit, ///< use this return value to cause the menu (perhaps the program) to exit 00147 runok ///< use this return value to keep the menu running 00148 } RUNRESULT_T; 00149 00150 /// Adding items to the menu can succeed, or fail. 00151 typedef enum 00152 { 00153 addfailed, ///< this indicates the menu was not added (usually failure to allocate memory) 00154 addok ///< this indicates the menu was successfully added 00155 } ADDRESULT_T; 00156 00157 /// Initialization can succeed, or fail. 00158 typedef enum 00159 { 00160 initfailed, ///< this indicates that the menu system was not initialized (usually failure to allocate memory) 00161 initok ///< this indicates that the menu system was successfully initialized 00162 } INITRESULT_T; 00163 00164 /// Configuration options to control startup and some runtime behavior 00165 /// 00166 /// Permissible values are created by combining 00167 /// \li CFG_ENABLE_TERMINATE 00168 /// \li CFG_ENABLE_SYSTEM 00169 /// \li CFG_ECHO_ON 00170 /// \li CFG_CASE_INSENSITIVE 00171 typedef unsigned long CONFIG_T; 00172 00173 #define CFG_ENABLE_TERMINATE 0x0001 ///<- Enable the exit option 00174 #define CFG_ENABLE_SYSTEM 0x0002 ///<- Enable various system options (help, etc) 00175 #define CFG_ECHO_ON 0x2000 ///<- Initialize with command prompt Echo on 00176 #define CFG_CASE_INSENSITIVE 0x4000 ///<- Enable case insensitive command entry 00177 00178 00179 /// This is the type for the basic callback, when a menu pick is activated. 00180 /// 00181 /// The callback function is executed when a command is entered on the menu and <enter> 00182 /// is signaled. If there is any additional text entered on the commandline, it is 00183 /// passed to the callback. 00184 /// 00185 /// example: 00186 /// "Test1 ab c 123 567" 00187 /// If "Test1" is a valid command, the corresponding function would be called 00188 /// passing to that function the string "ab c 123 567". Note that the delimiter space 00189 /// was removed. 00190 /// 00191 /// @param p is a pointer to a character string 00192 /// @returns RUNRESULT_T to indicate if the CommandProcessor should continue 00193 /// 00194 typedef RUNRESULT_T (*MENU_CALLBACK)(char *p); 00195 00196 /// This defines the type for a single item to be added to the CommandProcessor menu. 00197 /// 00198 /// This is defined in the application code, and a pointer to this item is passed to the 00199 /// CommandProcessor to add this item to the menu system. 00200 /// 00201 /// example: 00202 /// @code 00203 /// const CMD_T WhoCmd = {"who", "Shows who is logged on, or 'who id' for specifics", Who, visible}; 00204 /// @endcode 00205 /// 00206 typedef const struct 00207 { 00208 char * command; ///< a pointer to the command to match (e.g. 'Help') 00209 char * helptext; ///< a pointer to some text to show when user types 'Help' 00210 MENU_CALLBACK callback; ///< the function to call when user enters this command 00211 VISIBLE_T visible; ///< a flag that determines if this command is visible in Help. 00212 } CMD_T; 00213 00214 /// This is the CommandProcessor interface from the user application. 00215 /// 00216 /// The user aquires a handle to this set of functions with the GetCommandProcessor command. 00217 /// After this, the user may then initialize the CommandProcessor, add items to the menu, 00218 /// cause the CommandProcessor to run periodically, and if need be the application can end 00219 /// the CommandProcessor. 00220 /// 00221 typedef const struct 00222 { 00223 /// Init is the first function to call to configure the CommandProcessor. 00224 /// 00225 /// This function has a number of parameters, which make the CommandProcessor quite flexible. 00226 /// 00227 /// @param SignOnBanner function, which is used as a signon banner 00228 /// @param config enables various default menu items, based on the bit values, combine the following: 00229 /// \li CFG_ENABLE_TERMINATE - enables the Exit command 00230 /// \li CFG_ENABLE_SYSTEM - enables system commands Echo, Help, etc. 00231 /// \li CFG_ECHO_ON - initialize with echo on 00232 /// \li CFG_CASE_INSENSITIVE - Command Parser is case insensitive 00233 /// @param maxCmdLen sizes the buffer, and is the maximum number of characters in a single 00234 /// command, including all command arguments 00235 /// @param historyLen sets the number of items that can be recalled from history 00236 /// @param kbhit is a user provided function to detect if a character is available for the CommandProcessor, 00237 /// and when using standard io, you can typically use kbhit, or _kbhit as your system provides. 00238 /// @param getch is a user provided function that provides a single character to the CommandProcessor 00239 /// @param putch is a user provided function that permits the CommandProcessor to output a character 00240 /// @param puts is a user provided function that permits the CommandProcessor to output a string 00241 /// to which is automatically appended a \\n 00242 /// @returns INITRESULT_T to indicate if the init was successful or failed 00243 /// 00244 INITRESULT_T (*Init)( 00245 CMD_T *SignOnBanner, 00246 CONFIG_T config, 00247 int maxCmdLen, 00248 int historyLen, 00249 int (*kbhit)(void), 00250 int (*getch)(void), 00251 int (*putch)(int ch), 00252 int (*puts)(const char * s) 00253 ); 00254 00255 /// Add is called to add an item to the CommandProcessor menu 00256 /// 00257 /// This passes in a reference to a user provided CMD_T item, which is 00258 /// added to the menu system. 00259 /// 00260 /// @param m is a pointer to the user provided menu 00261 /// @returns ADDRESULT_T to indicate if the add was successful or failed 00262 /// 00263 ADDRESULT_T (*Add)(CMD_T * m); 00264 00265 /// Run is the primary runtime entry point for the CommandProcessor. 00266 /// 00267 /// This function should be called periodically - fast enough not to miss user input. 00268 /// This function always returns, so if not character is available for the CommandProcessor 00269 /// it will return very fast. If there is a character (as detected by the kbhit callback), 00270 /// then it will process that character and determine what to do. It may then execute one 00271 /// of the menu functions. In this case, CPU cycles spent are based on the function 00272 /// being executed. 00273 /// 00274 /// @returns RUNRESULT_T to indicate if the CommandProcessor should remain active or if the 00275 /// command that was executed is requesting the CommandProcessor to exit. 00276 /// 00277 RUNRESULT_T (*Run)(void); 00278 00279 /// Echo command permits turning the echo on and off 00280 /// 00281 /// When interactive with the user, it is best to have echo on, so they can see 00282 /// the prompt, but if this is simply slaved to another program, then the echo 00283 /// might need to be off to best manage the stream. 00284 /// 00285 /// @param echo turns the echo on (non-zero) or off (zero) 00286 /// @returns RUNRESULT_T to indicate if the CommandProcessor should remain active or if the 00287 /// command that was executed is requesting the CommandProcessor to exit. 00288 /// 00289 RUNRESULT_T (*Echo)(int echo); 00290 00291 /// End if the function to be called when you want to gracefully end the CommandProcessor. 00292 /// 00293 /// Calling this function causes the CommandProcessor to free any memory that was previously 00294 /// allocated by the Init and Add functions. 00295 RUNRESULT_T (*End)(void); ///< Called to shutdown the processor 00296 } CMDP_T; 00297 00298 00299 /// The CommandProcessor is the interface to install a run-time menu into an embedded system. 00300 /// This contains the complete interface to the CommandProcessor. 00301 /// 00302 /// @version 1.05 00303 /// 00304 /// @note The CommandProcessor is text-based, because it is intended to interact with a 00305 /// user. 00306 /// 00307 /// The menu is designed to be interactively accessed, perhaps via a console interface 00308 /// or a serial port. The actual interface to the user is provided by the application 00309 /// during initialization, so it can be connected to a serial port, or it could 00310 /// be interface to CAN, telnet, or by some other method. 00311 /// 00312 /// The CommandProcessor has a few special features: 00313 /// \li If the minimum number of characters of a command have been entered, the 00314 /// user does not have to type the entire command. (e.g. 'He' will execute 00315 /// the command for 'Help', if no other command beings with 'He'). 00316 /// \li If the user does not type the entire set of characters, the command 00317 /// will be rewritten to the output device with the entire command word. 00318 /// \li The user is not permitted to enter an incorrect command (e.g. If 'Help' 00319 /// is the only command started with 'Hel', the user cannot enter 'Heu'. 00320 /// The CommandProcessor will trap the 'u' and issue a beep). 00321 /// \li Simple editing of parameters to commands is permitted with <bs> to 00322 /// erase incorrect text. 00323 /// \li Tab completion of a command is available - so long as the user has 00324 /// typed at least the minimum number of unique characters. (e.g. 'He<tab>' 00325 /// will be replaced with 'Help') 00326 /// \li Command cancellation is available - just enter the <esc> key and 00327 /// the buffer is erased. 00328 /// \li The user is not permitted to enter text longer than the defined buffer, 00329 /// to avoid buffer overrun and the possible memory damaging results. 00330 /// 00331 /// The CommandProcessor is designed as a set of C functions, which makes it 00332 /// reusable in more systems (as C++ compilers are not always available for 00333 /// all micros). 00334 /// 00335 /// Example: 00336 /// @code 00337 /// extern "C" { 00338 /// #include "CommandProcessor.h" 00339 /// } 00340 /// 00341 /// RUNRESULT_T About(char *p); 00342 /// const CMD_T AboutCmd = {"About", "About this program", About, invisible}; 00343 /// RUNRESULT_T Who(char *p); 00344 /// const CMD_T WhoCmd = {"who", "Shows who is logged on, or 'who id' for specifics", Who, visible}; 00345 /// 00346 /// RUNRESULT_T About(char *p) 00347 /// { 00348 /// (void)p; 00349 /// puts("\r\nThis program does really good things for the user.\r\n"); 00350 /// } 00351 /// 00352 /// RUNRESULT_T Who(char *p) 00353 /// { 00354 /// printf("\r\nwho...\r\n"); 00355 /// if (*p) 00356 /// printf(" Sorry, no help for [%s]\r\n", p); 00357 /// return runok; 00358 /// } 00359 /// 00360 /// int main(int argc, char* argv[]) 00361 /// { 00362 /// CMDP_T * cp = GetCommandProcessor(); 00363 /// cp->Init(AboutCmd, CFG_ENABLE_TERMINATE | CFG_ENABLE_SYSTEM | CFG_SIGNON_BANNER, 00364 /// 50, 00365 /// _kbhit, _getch, _putch, printf); 00366 /// cp->Add(&WhoCmd); 00367 /// 00368 /// while (cp->Run()) 00369 /// { 00370 /// ; 00371 /// } 00372 /// cp->End(); 00373 /// return 0; 00374 /// } 00375 /// @endcode 00376 /// 00377 /// @note Copyright © 2011 by Smartware Computing, all rights reserved. 00378 /// This program may be used by others as long as this copyright notice 00379 /// remains intact. 00380 /// @author David Smart 00381 /// 00382 /// GetCommandProcessor is called to get a handle to the CommandProcessor itself. 00383 /// 00384 /// Call this function to get a handle to the CommandProcessor. After this is done, then 00385 /// you can use that handle to activate the CommandProcessor methods. 00386 /// 00387 /// example: 00388 /// @code 00389 /// CMDP_T * cp = GetCommandProcessor(); 00390 /// cp->Init(AboutCmd, CFG_ENABLE_TERMINATE | CFG_ENABLE_SYSTEM | CFG_SIGNON_BANNER, 00391 /// 50, 00392 /// _kbhit, _getch, _putch, printf); 00393 /// @endcode 00394 /// 00395 /// @returns CMDP_T a handle to the CommandProcessor 00396 /// 00397 #ifdef WIN32 00398 extern CMDP_T * GetCommandProcessor(void); 00399 #else // This is necessary for the mbed - not sure why. 00400 extern CMDP_T * GetCommandProcessor(void); 00401 #endif 00402 00403 #endif // COMMANDPROCESSOR_H
Generated on Wed Jul 13 2022 14:17:53 by 1.7.2