The CommandProcessor is the interface to install a run-time menu into an embedded system.

Dependents:   A_CANAdapter USB2I2C

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers CommandProcessor.h Source File

CommandProcessor.h

Go to the documentation of this file.
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 &copy; 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