appkit  1.5.1
RoadNarrows Robotics Application Kit
CommandLine.h
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // Package: RoadNarrows Robotics Application Tool Kit
4 //
5 // Link: https://github.com/roadnarrows-robotics/rnr-sdk
6 //
7 // Library: librnr_appkit
8 //
9 // File: CommandLine.h
10 //
11 /*! \file
12  *
13  * \brief Command line interface class interface.
14  *
15  * \author Robin Knight (robin.knight@roadnarrows.com)
16  *
17  * \par Copyright
18  * \h_copy 2016-2017. RoadNarrows LLC.\n
19  * http://www.roadnarrows.com\n
20  * All Rights Reserved
21  *
22  * \par License:
23  * MIT
24  */
25 /*
26  * @EulaBegin@
27  *
28  * Permission is hereby granted, without written agreement and without
29  * license or royalty fees, to use, copy, modify, and distribute this
30  * software and its documentation for any purpose, provided that
31  * (1) The above copyright notice and the following two paragraphs
32  * appear in all copies of the source code and (2) redistributions
33  * including binaries reproduces these notices in the supporting
34  * documentation. Substantial modifications to this software may be
35  * copyrighted by their authors and need not follow the licensing terms
36  * described here, provided that the new terms are clearly indicated in
37  * all files where they apply.
38  *
39  * IN NO EVENT SHALL THE AUTHOR, ROADNARROWS LLC, OR ANY MEMBERS/EMPLOYEES
40  * OF ROADNARROW LLC OR DISTRIBUTORS OF THIS SOFTWARE BE LIABLE TO ANY
41  * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
42  * DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION,
43  * EVEN IF THE AUTHORS OR ANY OF THE ABOVE PARTIES HAVE BEEN ADVISED OF
44  * THE POSSIBILITY OF SUCH DAMAGE.
45  *
46  * THE AUTHOR AND ROADNARROWS LLC SPECIFICALLY DISCLAIM ANY WARRANTIES,
47  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
48  * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN
49  * "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO
50  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
51  *
52  * @EulaEnd@
53  */
54 ////////////////////////////////////////////////////////////////////////////////
55 
56 #ifndef _RNR_COMMAND_LINE_H
57 #define _RNR_COMMAND_LINE_H
58 
59 #include <unistd.h>
60 #include <stdlib.h>
61 #include <stdio.h>
62 
63 #include <iostream>
64 #include <string>
65 #include <vector>
66 #include <map>
67 
68 #include "rnr/rnrconfig.h"
69 #include "rnr/log.h"
70 
72 #include "rnr/appkit/RegEx.h"
73 #include "rnr/appkit/LogBook.h"
74 #include "rnr/appkit/ReadLine.h"
75 #include "rnr/appkit/Token.h"
76 #include "rnr/appkit/CmdCore.h"
77 #include "rnr/appkit/CmdExtArg.h"
78 #include "rnr/appkit/CmdArgDef.h"
79 #include "rnr/appkit/CmdFormDef.h"
80 #include "rnr/appkit/CmdDef.h"
81 
82 
83 /*!
84  * \brief RoadNarrows Robotics
85  */
86 namespace rnr
87 {
88  /*!
89  * \brief Commands
90  */
91  namespace cmd
92  {
93  //
94  // Forward declarations
95  //
96  class CommandLine;
97 
98  //--------------------------------------------------------------------------
99  // Types and Values
100  //--------------------------------------------------------------------------
101 
102  /*!
103  * \brief Command execution function type, variant 1.
104  *
105  * With this variant, a vector of command line strings argument are
106  * provided to the function.
107  *
108  * The arguments have been validated against the associated extended syntax.
109  *
110  * This function type is provided as a convenience for application
111  * development. It is external to the core CommandLine functionality.
112  *
113  * \param [in] argv Vector of string arguments produced from a successful
114  * return from the relevant readCommand() call. The argv[0]
115  * argument is the command name.
116  *
117  * \return User defined return code.
118  */
119  typedef int (*CmdExec1Func)(const str::StringVec &argv);
120 
121  /*!
122  * \brief Command execution function type, variant 2.
123  *
124  * With this variant, a vector of command line extended arguments are
125  * provided to the function. Each extended argument provide matched command
126  * context. Moreover, each argument has been converted to its basic type.
127  *
128  * The arguments have been validated against the associated extended syntax.
129  *
130  * This function type is provided as a convenience for application
131  * development. It is external to the core CommandLine functionality.
132  *
133  * \param [in] argv Vector of extended arguments produced from a successful
134  * return from the relevant readCommand() call. The argv[0]
135  * argument is the command name.
136  *
137  * \return User defined return code.
138  */
139  typedef int (*CmdExec2Func)(const CmdExtArgVec &argv);
140 
141  /*!
142  * \brief Command execution function type, variant 3.
143  *
144  * This is identical to variant 2, but with the additional parameter
145  * referencing the common-line interface specification.
146  *
147  * \param [in] cli Command-line interface.
148  * \param [in] argv Vector of extended arguments produced from a successful
149  * return from the relevant readCommand() call. The argv[0]
150  * argument is the command name.
151  *
152  * \return User defined return code.
153  */
154  typedef int (*CmdExec3Func)(CommandLine &cli, const CmdExtArgVec &argv);
155 
156 
157  //--------------------------------------------------------------------------
158  // CmdExec Classs
159  //--------------------------------------------------------------------------
160 
161  /*!
162  * \brief Helper class to hold a command line execution function.
163  */
164  struct CmdExec
165  {
166  public:
167  /*!
168  * \brief Default constructor.
169  */
171  {
172  m_uid = NoUid;
174  m_exec.p = NULL;
175  }
176 
177  /*!
178  * \brief Variant 1 constructor.
179  *
180  * \param uid Associated command's unique id.
181  * \param fn Variant 1 execution function.
182  */
183  CmdExec(int uid, CmdExec1Func fn)
184  {
185  m_uid = uid;
187  m_exec.fn1 = fn;
188  }
189 
190  /*!
191  * \brief Variant 2 constructor.
192  *
193  * \param uid Associated command's unique id.
194  * \param fn Variant 2 execution function.
195  */
196  CmdExec(int uid, CmdExec2Func fn)
197  {
198  m_uid = uid;
200  m_exec.fn2 = fn;
201  }
202 
203  /*!
204  * \brief Variant 3 constructor.
205  *
206  * \param uid Associated command's unique id.
207  * \param fn Variant 3 execution function.
208  */
209  CmdExec(int uid, CmdExec3Func fn)
210  {
211  m_uid = uid;
213  m_exec.fn3 = fn;
214  }
215 
216  /*!
217  * \brief Copy constructor.
218  *
219  * \param src Source object.
220  */
221  CmdExec(const CmdExec &src)
222  {
223  m_uid = src.m_uid;
224  m_variant = src.m_variant;
225  m_exec = src.m_exec;
226  }
227 
228  /*!
229  * \brief Execute a comamnd with the given arguments.
230  *
231  * \param argv The list of string arguments.
232  *
233  * \return
234  * Returns a \ref cmd_ecodes on failure to find the associated command or
235  * its execution function. Otherwise, returns the user-define execution
236  * function return value.
237  */
238  int execute(const str::StringVec &argv);
239 
240  /*!
241  * \brief Execute a comamnd with the given arguments.
242  *
243  * \param cli Reference to the command-line interface.
244  * \param argv The list of extended arguments.
245  *
246  * \return
247  * Returns a \ref cmd_ecodes on failure to find the associated command or
248  * its execution function. Otherwise, returns the user-define execution
249  * function return value.
250  */
251  int execute(CommandLine &cli, const CmdExtArgVec &argv);
252 
253  /*!
254  * \brief Get associated command's unique id.
255  *
256  * \return Unique id.
257  */
258  int getUid() const
259  {
260  return m_uid;
261  }
262 
263  /*!
264  * \brief Insert object into output stream.
265  *
266  * \param os Output stream.
267  * \param obj Object to insert.
268  *
269  * \return Reference to output stream.
270  */
271  friend std::ostream &operator<<(std::ostream &os, const CmdExec &obj);
272 
273  protected:
274  /*!
275  * \brief Execution function variant enumeration.
276  */
277  enum Variant
278  {
279  VariantUndef, ///< undefined variant
280  Variant1, ///< variant 1
281  Variant2, ///< variant 2
282  Variant3 ///< variant 3
283  };
284 
285  /*!
286  * \brief Union of all variant execution functions.
287  */
288  union FnVar
289  {
290  void * p; ///< pointer
291  CmdExec1Func fn1; ///< execution function variant 1
292  CmdExec2Func fn2; ///< execution function variant 2
293  CmdExec3Func fn3; ///< execution function variant 3
294  };
295 
296  int m_uid; ///< command unique id associated with this execution
297  Variant m_variant; ///< function variant enum
298  FnVar m_exec; ///< function execution variant
299  };
300 
301 
302  //--------------------------------------------------------------------------
303  // DataSect Classs
304  //--------------------------------------------------------------------------
305 
306  /*!
307  * \brief Command line interface data section class.
308  *
309  * The cli can support multiple data sections, each delineated by a unique
310  * namespace.
311  *
312  * If a data deallocator function is specifed, the section data will be
313  * automatically deleted when the command line data section is is deleted.
314  */
315  class DataSect
316  {
317  public:
318  /*! data section data deallocator function type. */
319  typedef void (*DeallocFunc)(void *);
320 
321  std::string m_strNs; ///< data section namespace
322  void * m_pData; ///< pointer to section data
323  DeallocFunc m_fnDealloc; ///< data deallocator function
324 
325  /*!
326  * \brief Default constructor.
327  */
328  DataSect();
329 
330  /*!
331  * \brief Initialization constructor.
332  *
333  * \param ns ///< data section namespace
334  * \param pData ///< pointer to section data
335  * \param fn ///< data deallocator function
336  */
337  DataSect(const std::string &ns, void *pData, DeallocFunc fn = NULL);
338 
339  /*!
340  * \brief Destructor.
341  */
342  ~DataSect();
343 
344  void set(const std::string &ns, void *pData, DeallocFunc fn = NULL);
345 
346  /*!
347  * \brief Return namespace.
348  *
349  * \return String.
350  */
351  const std::string &ns() const
352  {
353  return m_strNs;
354  }
355 
356  /*!
357  * \brief Return section data.
358  *
359  * \return Void pointer.
360  */
361  void *data()
362  {
363  return m_pData;
364  }
365 
366  /*!
367  * \brief Return section data.
368  *
369  * \return Constant void pointer.
370  */
371  const void *data() const
372  {
373  return m_pData;
374  }
375 
376  /*!
377  * \brief Return deallocator.
378  *
379  * \return Pointer to function.
380  */
381  DeallocFunc deallocator()
382  {
383  return m_fnDealloc;
384  }
385 
386  /*!
387  * \brief Return deallocator.
388  *
389  * \return Constant pointer to function.
390  */
391  const DeallocFunc deallocator() const
392  {
393  return m_fnDealloc;
394  }
395 
396  /*!
397  * \brief Insert object into output stream.
398  *
399  * \param os Output stream.
400  * \param obj Object to insert.
401  *
402  * \return Reference to output stream.
403  */
404  friend std::ostream &operator<<(std::ostream &os, const DataSect &obj);
405 
406  }; // class DataSect
407 
408 
409  //--------------------------------------------------------------------------
410  // Types and Data
411  //--------------------------------------------------------------------------
412 
413  //
414  // Command definitions map.
415  //
416  typedef std::map<unsigned, CmdDef> CmdDefMap; ///< command map type
417  typedef CmdDefMap::iterator CmdDefIter; ///< cmd iterator type
418  typedef CmdDefMap::const_iterator CmdDefCIter; ///< cmd const iter type
419 
420  //
421  // Command execution map.
422  //
423  typedef std::map<unsigned, CmdExec> CmdExecMap; ///< exec map type
424  typedef CmdExecMap::iterator CmdExecIter; ///< exec iterator type
425  typedef CmdExecMap::const_iterator CmdExecCIter; ///< exec const iter type
426 
427  //
428  // Data Section map.
429  //
430  typedef std::map<std::string, DataSect> DataSectMap; ///< section map type
431  typedef DataSectMap::iterator DataSectIter; ///< iterator type
432  typedef DataSectMap::const_iterator DataSectCIter; ///< const iter type
433 
434  typedef str::StringVec PromptStack; ///< prompt stack type
435 
436 
437  //--------------------------------------------------------------------------
438  // CommandLine Class
439  //--------------------------------------------------------------------------
440 
441  /*!
442  * \brief CommandLine class.
443  */
445  {
446  public:
447  /*!
448  * \brief Default initialization constructor.
449  *
450  * \param strName Name of command set and entry into readline's
451  * conditional parsing of the ~/.inputrc file.
452  * \param strPrompt Command line primary prompt string. Prompting occurs
453  * only in interactive mode.
454  * \param bUseRlLib Use the readline library. Note that readline must
455  * be available and in interactive mode. Otherwise a
456  * simple command-line interface will be used.
457  * \param bIgnoreCase Ignore case on comands and arguments.
458  */
459  CommandLine(const std::string strName = "cl",
460  const std::string strPrompt = "> ",
461  bool bUseRlLib = true,
462  bool bIgnoreCase = false);
463 
464  /*!
465  * \brief Destructor.
466  */
467  virtual ~CommandLine();
468 
469  /*
470  * \brief Test if command line is sufficiently defined.
471  *
472  * \return Returns true or false.
473  */
474  bool isDefined() const;
475 
476  /*!
477  * \brief Test if command-line interface is ok to continue.
478  *
479  * \return Returns true or false.
480  */
481  bool ok() const
482  {
483  return !((DataSectCore*)m_dataSects.at(DataSectNsCore).data())->m_bQuit;
484  }
485 
486  /*!
487  * \brief Mark command-line interface to quit.
488  */
489  void quit()
490  {
491  ((DataSectCore *)m_dataSects[DataSectNsCore].data())->m_bQuit = true;
492  }
493 
494  /*!
495  * \brief Test if backtracing is enabled.
496  *
497  * \return Returns true or false.
498  */
499  bool getBtEnable() const
500  {
501  return
502  ((DataSectCore*)m_dataSects.at(DataSectNsCore).data())->m_bBacktrace;
503  }
504 
505  /*!
506  * \brief Enable/disable backtracing.
507  *
508  * \param bEnable Enable(true) or Disable(false).
509  */
510  void setBtEnable(bool bEnable)
511  {
512  ((DataSectCore*)m_dataSects.at(DataSectNsCore).data())->m_bBacktrace =
513  bEnable;
514  }
515 
516 
517  // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
518  // Public Command Addition and Compile Methods
519  // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
520 
521  /*!
522  * \defgroup doc_addcommand
523  * \{
524  * \brief Add a command to the command line interface.
525  *
526  * The command syntax may specify multiple command forms, each separated
527  * by a newline '\\n' character. The command named in each form must be
528  * the identical.
529  *
530  * This is a light-weight function. A call to compile() is necessary to
531  * finalized command syntax processing.
532  *
533  * \param desc Command description (see \ref CmdDesc).
534  * \param strSyntax One or more extended usage syntax separated by
535  * newline characters.
536  * \param fnExec Command execution function of variant 1, 2, or 3.
537  *
538  * \return
539  * On success, returns command's assigned unique id.
540  * Otherwise NoUid is returned.
541  * \}
542  */
543  /*! \copydoc doc_addcommand */
544  virtual int addCommand(const CmdDesc &desc);
545 
546  /*! \copydoc doc_addcommand */
547  virtual int addCommand(const CmdDesc &desc, CmdExec1Func fnExec);
548 
549  /*! \copydoc doc_addcommand */
550  virtual int addCommand(const CmdDesc &desc, CmdExec2Func fnExec);
551 
552  /*! \copydoc doc_addcommand */
553  virtual int addCommand(const CmdDesc &desc, CmdExec3Func fnExec);
554 
555  /*! \copydoc doc_addcommand */
556  virtual int addCommand(const std::string strSyntax);
557 
558  /*! \copydoc doc_addcommand */
559  virtual int addCommand(const std::string strSyntax, CmdExec1Func fnExec);
560 
561  /*! \copydoc doc_addcommand */
562  virtual int addCommand(const std::string strSyntax, CmdExec2Func fnExec);
563 
564  /*! \copydoc doc_addcommand */
565  virtual int addCommand(const std::string strSyntax, CmdExec3Func fnExec);
566 
567  /*!
568  * \brief Remove command from command line interface.
569  *
570  * No re-comiple is necessary.
571  *
572  * \param uid Command unique id.
573  *
574  * \copydoc doc_return_cl
575  */
576  virtual int removeCommand(const int uid);
577 
578  /*!
579  * \brief Remove command from command line interface.
580  *
581  * No re-comiple is necessary.
582  *
583  * \param strName Command name.
584  *
585  * \copydoc doc_return_cl
586  */
587  virtual int removeCommand(const std::string &strName);
588 
589  /*!
590  * \brief Remove all commands from command line interface.
591  *
592  * \copydoc doc_return_cl
593  */
594  virtual int removeAllCommands();
595 
596  /*!
597  * \brief Compile all added commands.
598  *
599  * Compiling essentially parses the command extended usage syntax and
600  * sets the internal data for:
601  * - readline tab completion
602  * - input to command pattern matching
603  * - first-level command validation
604  *
605  * \copydoc doc_return_cl
606  */
607  virtual int compile();
608 
609 
610  // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
611  // Public Command Line Data Section Methods
612  // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
613 
614  /*!
615  * \brief Add a data section to the command-line interface.
616  *
617  * When the section is removed or the interface is deleted, the section
618  * data is automatically deleted if a deallocation function is specified.
619  * Otherwise, the user has responsibility to delete any data.
620  *
621  * \param ns Namespace of data section.
622  * \param pData Pointer to data.
623  * \param fn Deallocator function.
624  *
625  * \copydoc doc_return_cl
626  */
627  int addDataSection(const std::string &ns,
628  void *pData,
629  DataSect::DeallocFunc fn = NULL);
630 
631  /*!
632  * \brief Remove a data section from the command-line interface.
633  *
634  * If a deallocation function was specified, the section data is also
635  * deleted. Otherwise, the data remains intact.
636  *
637  * \param ns Namespace of data section to remove.
638  *
639  * \copydoc doc_return_cl
640  */
641  int removeDataSection(const std::string &ns);
642 
643  /*!
644  * \brief Get the section data under the specified namespace.
645  *
646  * \param ns Namespace of data section to retrieve.
647  *
648  * \return Returns pointer to the data if it exist. NULL is returned if
649  * no namespace is found, or no data has been specified.
650  */
651  void *getDataSection(const std::string &ns);
652 
653  /*!
654  * \brief Test if the namespace is a command-line interface reserved name.
655  *
656  * \param ns Namespace.
657  *
658  * \return Returns true or false.
659  */
660  bool isReservedDataSection(const std::string &ns) const;
661 
662 
663  // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
664  // Public Command Line Interface Methods
665  // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
666 
667  /*!
668  * \brief Read an input line from stdin and match to the best compiled
669  * command.
670  *
671  * Simple string argument version.
672  *
673  * On success, no arguments indicate an empty input line. Otherwise,
674  * the command name argv[0] is guaranteed to be present in the vector.
675  *
676  * \param [out] uid Matched command unique id.
677  * \param [out] iform Matched command form index.
678  * \param [out] argv Vector of arguments, with argv[0] being the
679  * command name.
680  *
681  * \copydoc doc_return_cl
682  */
683  virtual int readCommand(int &uid, int &iform, str::StringVec &argv)
684  {
685  return readCommand(stdin, uid, iform, argv);
686  }
687 
688  /*!
689  * \brief Read an input line from stdin and match to the best compiled
690  * command.
691  *
692  * Extended argument version.
693  *
694  * Each extended argument contains matched command context of:
695  * - the command's unique id and definition
696  * - form definition index
697  * - argument definition index
698  * - argument instance number for (future) argument repetition
699  *
700  * On success, no arguments indicate an empty input line. Otherwise,
701  * the command name argv[0] is guaranteed to be present in the vector.
702  *
703  * Extended arguments gives access to the compiled, matched command
704  * definition data such as number of required, optional, and total
705  * arguments, plus argument specific info such as name, type, etc.
706  *
707  * \param [out] uid Matched command unique id.
708  * \param [out] argv Vector of extended arguments, with argv[0] being the
709  * command name argument.
710  *
711  * \copydoc doc_return_cl
712  */
713  virtual int readCommand(CmdExtArgVec &argv)
714  {
715  return readCommand(stdin, argv);
716  }
717 
718  /*!
719  * \brief Read an input line from file fp and match to the best compiled
720  * command.
721  *
722  * Simple string argument version.
723  *
724  * On success, no arguments indicate an empty input line. Otherwise,
725  * the command name argv[0] is guaranteed to be present in the vector.
726  *
727  * \param fp Input file pointer.
728  * \param [out] uid Matched command unique id.
729  * \param [out] iform Matched command form index.
730  * \param [out] argv Vector of arguments, with argv[0] being the
731  * command name.
732  *
733  * \copydoc doc_return_cl
734  */
735  virtual int readCommand(FILE *fp,
736  int &uid,
737  int &iform,
738  str::StringVec &argv);
739 
740  /*!
741  * \brief Read an input line from file fp and match to the best compiled
742  * command.
743  *
744  * Extended argument version.
745  *
746  * Each extended argument contains matched command context of:
747  * - the command's unique id and definition
748  * - form definition index
749  * - argument definition index
750  * - argument instance number for (future) argument repetition
751  *
752  * On success, no arguments indicate an empty input line. Otherwise,
753  * the command name argv[0] is guaranteed to be present in the vector.
754  *
755  * Extended arguments gives access to the compiled, matched command
756  * definition data such as number of required, optional, and total
757  * arguments, plus argument specific info such as name, type, etc.
758  *
759  * \param fp Input file pointer.
760  * \param [out] argv Vector of extended arguments, with argv[0] being the
761  * command name argument.
762  *
763  * \copydoc doc_return_cl
764  */
765  virtual int readCommand(FILE *fp, CmdExtArgVec &argv);
766 
767  bool kbhit()
768  {
769  return kbhit(stdin);
770  }
771 
772  bool kbhit(FILE *fp);
773 
774  /*!
775  * \brief Execute a comamnd with the given arguments.
776  *
777  * \param argv The list of string arguments.
778  *
779  * \return
780  * Returns a \ref cmd_ecodes on failure to find the associated command or
781  * its execution function. Otherwise, returns the user-define execution
782  * function return value.
783  */
784  virtual int execute(const str::StringVec &argv);
785 
786  /*!
787  * \brief Execute a comamnd with the given arguments.
788  *
789  * \param argv The list of extended arguments.
790  *
791  * \return
792  * Returns a \ref cmd_ecodes on failure to find the associated command or
793  * its execution function. Otherwise, returns the user-define execution
794  * function return value.
795  */
796  virtual int execute(const CmdExtArgVec &argv);
797 
798  /*!
799  * \brief Add command to history.
800  *
801  * Simple string argument version.
802  *
803  * \note Only available if readline is available and enabled, and
804  * input is interactive.
805  *
806  * \param argv Command in argv vector.
807  */
808  virtual void addToHistory(const str::StringVec &argv);
809 
810  /*!
811  * \brief Add command to history.
812  *
813  * Extended argument version.
814  *
815  * \note Only available if readline is available and enabled, and
816  * input is interactive.
817  *
818  * \param argv Command in argv vector.
819  */
820  virtual void addToHistory(const CmdExtArgVec &argv);
821 
822  /*!
823  * \brief Push prompt string onto stack of prompts.
824  *
825  * If in interactive mode, the user will be prompted with the prompt
826  * string found at the top of the prompt stack. If the stack or prompt
827  * string is empty, no prompt will be displayed. Any prompt is written
828  * to standard output (stdout).
829  *
830  * \param strPrompt Prompt string.
831  */
832  void pushPrompt(const std::string &strPrompt);
833 
834  /*!
835  * \brief Pop prompt string from stack of prompts.
836  *
837  * The new top prompt string will be used for user prompting.
838  */
839  void popPrompt();
840 
841  /*!
842  * \brief Get the current prompt string.
843  *
844  * \return String.
845  */
846  const std::string &getPrompt() const;
847 
848  /*!
849  * \brief Get the line number of the last read line.
850  *
851  * \return Line number.
852  */
853  size_t getLineNum() const
854  {
855  return m_readline.getLineNum();
856  }
857 
858  /*!
859  * \brief Set the current line number.
860  *
861  * \param Line number.
862  */
863  void setLineNum(const size_t uLineNum)
864  {
865  m_readline.setLineNum(uLineNum);
866  }
867 
868  /*!
869  * \brief Reset the line number to zero.
870  */
872  {
873  m_readline.resetLineNum();
874  }
875 
876 
877  // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
878  // Public Command Form Info and Argument Access Methods
879  // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
880 
881  /*!
882  * \brief Get the total number of arguments.
883  *
884  * The first argument (argv0) is the command.
885  *
886  * \param uid Matched command unique id.
887  * \param iform Matched command form index.
888  *
889  * \return Number of arguments.
890  */
891  int numOfArgs(int uid, int iform) const;
892 
893  /*!
894  * \brief Get the total number of arguments of matched command.
895  *
896  * The extended argument contains matched command context.
897  *
898  * \param arg Extended argument.
899  *
900  * \return Number of arguments.
901  */
902  int numOfArgs(const CmdExtArg &arg) const;
903 
904  /*!
905  * \brief Get the total number of required arguments.
906  *
907  * The required number includes the command argv0.
908  *
909  * Required arguments start at argument index 0.
910  *
911  * \param uid Matched command unique id.
912  * \param iform Matched command form index.
913  *
914  * \return Number of required arguments.
915  */
916  int numOfRequiredArgs(int uid, int iform) const;
917 
918  /*!
919  * \brief Get the total number of required arguments of matched command.
920  *
921  * The extended argument contains matched command context.
922  *
923  * The required number includes the command argv0.
924  *
925  * Required arguments start at argument index 0.
926  *
927  * \param arg Extended argument.
928  *
929  * \return Number of required arguments.
930  */
931  int numOfRequiredArgs(const CmdExtArg &arg) const;
932 
933  /*!
934  * \brief Get the total number of optional arguments.
935  *
936  * Optional arguments start at argument index numOfRequiredArgs().
937  *
938  * \param uid Matched command unique id.
939  * \param iform Matched command form index.
940  *
941  * \return Number of optional arguments.
942  */
943  int numOfOptionalArgs(int uid, int iform) const;
944 
945  /*!
946  * \brief Get the total number of arguments of matched command.
947  *
948  * The extended argument contains matched command context.
949  *
950  * \param arg Extended argument.
951  *
952  * \return Number of optional arguments.
953  */
954  int numOfOptionalArgs(const CmdExtArg &arg) const;
955 
956  /*!
957  * \brief Get the argument name.
958  *
959  * The extended argument contains matched command context.
960  *
961  * \param arg Extended argument.
962  *
963  * \return Returns argument name on success, empty string on failure.
964  */
965  const std::string &getArgName(const CmdExtArg &arg) const;
966 
967  /*!
968  * \brief Get the argument type.
969  *
970  * The extended argument contains matched command context.
971  *
972  * \note Argument type differs from argument converted type. The former
973  * specifies the argument syntax, while the later specifies converted
974  * basic type such as string, int, etc.
975  *
976  * \param arg Extended argument.
977  *
978  * \return Returns argument type.
979  */
980  CmdArgDef::ArgType getArgDefType(const CmdExtArg &arg) const;
981 
982 
983  // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
984  // Public Input Processing Methods
985  // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
986 
987  /*!
988  * \brief Lexically analyze input string to generate a series of tokens.
989  *
990  * Tokens are separated by whitespace.
991  *
992  * Each tokens is either:
993  * * A contiguous sequence of non-whitespace characters.
994  * * An escapable sequence of characters delineated by double quotes '"'.
995  *
996  * ~~~~~~~~
997  * <token-list> ::= <token>
998  * | <token-list> <token>
999  *
1000  * <token> ::= <word>
1001  * | <quoted-string>
1002  *
1003  * <word> ::= {NONWHITE_CHAR}+
1004  *
1005  * <qouted-string> ::= '"' {ESCAPABLE_CHAR}* '"'
1006  * ~~~~~~~~
1007  *
1008  * \param [in] strInput Input string to analyze.
1009  * \param [out] tokens Generated tokens.
1010  *
1011  * \copydoc doc_return_ssize
1012  */
1013  virtual ssize_t tokenizeInput(const std::string &strInput,
1014  TokenVec &tokens);
1015 
1016  /*!
1017  * \brief Lexically analyze input string to generate a series of string
1018  * tokens.
1019  *
1020  * See \ref tokenize()
1021  *
1022  * \param [in] strInput Input string to analyze.
1023  * \param [out] tokens Generated string tokens.
1024  *
1025  * \copydoc doc_return_ssize
1026  */
1027  virtual ssize_t tokenizeInput(const std::string &strInput,
1028  str::StringVec &tokens);
1029 
1030 
1031  // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1032  // Public Attribute and Data Access Methods
1033  // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1034 
1035  /*!
1036  * \brief Get command line interface's name.
1037  *
1038  * \return Name string.
1039  */
1040  const std::string &getName() const
1041  {
1042  return m_strName;
1043  }
1044 
1045  /*!
1046  * \brief Test if command exists.
1047  *
1048  * \param uid Command unique id.
1049  *
1050  * \return Returns true or false.
1051  */
1052  bool hasCmd(const int uid) const;
1053 
1054  /*!
1055  * \brief Test if command exists.
1056  *
1057  * \param strName Command name.
1058  *
1059  * \return Returns true or false.
1060  */
1061  bool hasCmd(const std::string &strName) const;
1062 
1063  /*!
1064  * \brief Get the command definition with the unique id.
1065  *
1066  * \param uid Command unique id.
1067  *
1068  * \return Command definition reference.
1069  */
1070  const CmdDef &at(const int uid) const;
1071 
1072  /*!
1073  * \brief Get command definition with the argv0 name.
1074  *
1075  * \param strName Command name.
1076  *
1077  * \return Command definition reference.
1078  */
1079  const CmdDef &at(const std::string &strName) const;
1080 
1081  /*!
1082  * \brief Index operator.
1083  *
1084  * Get the command definition with the unique id.
1085  *
1086  * \param uid Command unique id.
1087  *
1088  * \return Command definition reference.
1089  */
1090  const CmdDef &operator[](const int uid) const;
1091 
1092  /*!
1093  * \brief Index operator.
1094  *
1095  * Get the command definition with the unique id.
1096  *
1097  * \param strName Command name.
1098  *
1099  * \return Command definition reference.
1100  */
1101  const CmdDef &operator[](const std::string &strName) const;
1102 
1103  /*!
1104  * \brief Get the total number of added commands.
1105  *
1106  * \return Number of commands.
1107  */
1108  int numOfCmds() const
1109  {
1110  return (int)m_cmdDefs.size();
1111  }
1112 
1113  /*!
1114  * \brief Return a constant iterator pointing to the first element of
1115  * the list of command definitions.
1116  *
1117  * \return Constant Iterator.
1118  */
1119  CmdDefCIter begin() const
1120  {
1121  return m_cmdDefs.begin();
1122  }
1123 
1124  /*!
1125  * \brief Return a constant iterator referring to the past-the-end
1126  * element of the list of command definitions.
1127  *
1128  * \return Constant Iterator.
1129  */
1130  CmdDefCIter end() const
1131  {
1132  return m_cmdDefs.end();
1133  }
1134 
1135  /*!
1136  * \brief Get the most recent error.
1137  *
1138  * \return Error string.
1139  */
1140  const std::string &getErrorStr() const;
1141 
1142  /*!
1143  * \brief Insert trace and error log backtrace into output stream.
1144  *
1145  * \param os Output stream.
1146  * \param bAll If true, backtrace all of log. Otherwise backtrace to
1147  * last major execution mark.
1148  *
1149  * \return Reference to output stream.
1150  */
1151  std::ostream &backtrace(std::ostream &os, const bool bAll = false) const;
1152 
1153 
1154  // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1155  // Output Methods and Operators
1156  // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1157 
1158  /*!
1159  * \brief Insert object into output stream.
1160  *
1161  * \param os Output stream.
1162  * \param cl Object to insert.
1163  *
1164  * \return Reference to output stream.
1165  */
1166  friend std::ostream &operator<<(std::ostream &os, const CommandLine &cl);
1167 
1168 
1169  // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1170  // Static Convenience Methods
1171  // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1172 
1173  /*!
1174  * \brief Canonicalization of a string.
1175  *
1176  * \note The name c14n is an cute abbreviation where 14 represents the
1177  * number of letters between the 'c' and 'n' in the word
1178  * "canonicalization".
1179  *
1180  * \param tokens Tokens to canonicalize.
1181  *
1182  * \return Return string holding canonical form.
1183  */
1184  static std::string c14n(const TokenVec &tokens);
1185 
1186  protected:
1187  std::string m_strName; ///< name of this command line
1188  bool m_bIgnoreCase; ///< do [not] ignore case on commands
1189  int m_nUidCnt; ///< unique id counter
1190  bool m_bIsCompiled; ///< has [not] been successfully compiled
1191  CmdDefMap m_cmdDefs; ///< map of added command definitions
1192  CmdExecMap m_cmdExecs; ///< map of added command executions
1193  PromptStack m_prompts; ///< stack of prompt strings
1194  ReadLine m_readline; ///< readline interface
1195  LogBook m_log; ///< trace and error log
1196  DataSectMap m_dataSects; ///< data sections
1197 
1198  /*!
1199  * \brief Get modifiable command definition with the given unique id.
1200  *
1201  * Protected version of at().
1202  *
1203  * \param uid Command unique id.
1204  *
1205  * \return Command definition reference.
1206  */
1207  CmdDef &cmdAt(const int uid);
1208 
1209  /*!
1210  * \brief Get modifiable command definition with the given argv0 name.
1211  *
1212  * Protected version of at().
1213  *
1214  * \param strName Command name.
1215  *
1216  * \return Command definition reference.
1217  */
1218  CmdDef &cmdAt(const std::string &strName);
1219 
1220 
1221  // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1222  // Lexical Analyzer Methods
1223  // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1224 
1225  /*!
1226  * \brief Lexically analyze extened usage syntax string to generate a
1227  * series of tokens.
1228  *
1229  * Tokens are separated by either whitespace, parenthetical blocks,
1230  * or syntax special characters.
1231  *
1232  * \param [in] strSyntax Syntax string to analyze.
1233  * \param [out] tokens Generated tokens.
1234  *
1235  * \copydoc doc_return_ssize
1236  */
1237  virtual ssize_t tokenizeSyntax(const std::string &strSyntax,
1238  TokenVec &tokens);
1239 
1240  /*!
1241  * \brief Syntax word lexical analyzer.
1242  *
1243  * A syntax word is defined as any contiguous sequence of non-whitespace,
1244  * non-syntax-special symbol characters.
1245  *
1246  * On success, the generated <word> token is placed at the end of the
1247  * vector.
1248  *
1249  * \param [in] strSyntax Syntax string to analyze.
1250  * \param [in] cursor Character position along syntax string.
1251  * \param [in,out] tokens Vector of generated tokens.
1252  *
1253  * \return
1254  * On success, returns new cursor position.
1255  * Otherwise a negative error code is returned.
1256  */
1257  virtual ssize_t lexSyntaxWord(const std::string &strSyntax,
1258  ssize_t cursor,
1259  TokenVec &tokens);
1260 
1261  /*!
1262  * \brief Syntax parenthetical expression lexical analyzer.
1263  *
1264  * A syntax parenthetical expression isdefined as any contiguous sequence
1265  * block of character delineated by a balanced pair of parentheses. A
1266  * backslash escaped parenthesis does to factor into the paentheses
1267  * countiog.
1268  *
1269  * On success,the generated tokens '(', <paren-tok>, and ')' are placed
1270  * at the end of the vector.
1271  *
1272  * \par Syntax:
1273  * ~~~~~~~~
1274  * <paren-expr-def> ::= '(' <paren-tok> ')'
1275  * ~~~~~~~~
1276  *
1277  * \param [in] strSyntax Syntax string to analyze.
1278  * \param [in] cursor Character position along syntax string.
1279  * \param [in,out] tokens Vector of generated tokens.
1280  *
1281  * \return
1282  * On success, returns new cursor position.
1283  * Otherwise a negative error code is returned.
1284  */
1285  virtual ssize_t lexSyntaxParenExpr(const std::string &strSyntax,
1286  ssize_t cursor,
1287  TokenVec &tokens);
1288 
1289  /*!
1290  * \brief Word lexical analyzer.
1291  *
1292  * A word is defined as any contiguous sequence of non-whitespace
1293  * characters.
1294  *
1295  * On success, the generated <word> token is placed at the end of the
1296  * vector.
1297  *
1298  * \param [in] strInput Input string to analyze.
1299  * \param [in] cursor Character position along input string.
1300  * \param [in,out] tokens Vector of generated tokens.
1301  *
1302  * \return
1303  * On success, returns new cursor position.
1304  * Otherwise a negative error code is returned.
1305  */
1306  virtual ssize_t lexWord(const std::string &strInput,
1307  ssize_t cursor,
1308  TokenVec &tokens);
1309 
1310  /*!
1311  * \brief Quoted string lexical analyzer.
1312  *
1313  * The unescaped double quotes are not included in the token. Escape
1314  * sequences interpreted.
1315  *
1316  * On success, the generated <interp-char-seq> token is placed at the end
1317  * of the vector.
1318  *
1319  * \par Syntax:
1320  * ~~~~~~~~
1321  * <quoted-string> ::= '"' <interp-char-seq> '"'
1322  *
1323  * <interp-char-seq> ::= <interp-char>
1324  * | <interp-char-seq> <interp-char>
1325  *
1326  * <interp-char> ::= NON_BACKSLASH_CHAR
1327  * | <interp-esc-char>
1328  *
1329  * <interp-esc-char> ::= '\' CHAR
1330  * | '\' 'x' HEXDIGIT
1331  * | '\' 'x' HEXDIGIT HEXDIGIT
1332  * ~~~~~~~~
1333  *
1334  * \param [in] strInput Input string to analyze.
1335  * \param [in] cursor Character position along input string.
1336  * \param [in,out] tokens Vector of generated tokens.
1337  *
1338  * \return
1339  * On success, returns new cursor position.
1340  * Otherwise a negative error code is returned.
1341  */
1342  virtual ssize_t lexQuotedString(const std::string &strInput,
1343  ssize_t cursor,
1344  TokenVec &tokens);
1345 
1346  /*!
1347  * \brief Log lexigraphical token.
1348  *
1349  * \param strSource Source string of tokens.
1350  * \param start Start token character position in source.
1351  * \param cursor Cursor position in source.
1352  * \param [in,out] tokens Vector of lexical tokens.
1353  * \param bLoc If true, then include line number and token
1354  * characater positions.
1355  */
1356  virtual void logLexToken(const std::string &strSource,
1357  const size_t start,
1358  const ssize_t cursor,
1359  TokenVec &tokens,
1360  const bool bLoc = false);
1361 
1362  /*!
1363  * \brief Push token to the end of the generated tokens.
1364  *
1365  * \param strSource Source string of tokens.
1366  * \param start Start token character position in source.
1367  * \param cursor Cursor position in source.
1368  * \param [in,out] tokens Vector of lexical tokens.
1369  */
1370  void pushToken(const std::string &strSource,
1371  const size_t start,
1372  const ssize_t cursor,
1373  TokenVec &tokens);
1374 
1375 
1376  // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1377  // Command Addition and Compile Methods
1378  // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1379 
1380  /*!
1381  * \brief Compile a command.
1382  *
1383  * \sa CommandLine::compile()
1384  *
1385  * \param cmddef Command definition.
1386  *
1387  * \copydoc doc_return_cl
1388  */
1389  virtual int compile(CmdDef &cmddef);
1390 
1391  /*!
1392  * \brief Finalize command compilation.
1393  *
1394  * \copydoc doc_return_cl
1395  */
1396  int finalize();
1397 
1398 
1399  // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1400  // Extended Usage Syntax Parsing Methods
1401  // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1402 
1403  /*!
1404  * \brief Parse command syntax.
1405  *
1406  * The parsed, generated internal data are used for readline tab
1407  * completion, input - command pattern matching, and first-level
1408  * validation.
1409  *
1410  * The parseSyntax() function [in]directly calls the CommandLine::parse
1411  * family of member functions. Each function takes, at a minimum, four
1412  * parameters:
1413  *
1414  * Parameter | Description
1415  * --------- | -----------
1416  * cmddef | Definition of an added command. It may be modified.
1417  * form | Definition of a command form. It may be modified.
1418  * tokens | Lexical tokens generated from the extended usage syntax.
1419  * pos | The parse cursor position. On input, it specifies
1420  * ^ | the starting position in the tokens vector. On a
1421  * ^ | succesful parse, the cursor position is advanced
1422  * ^ | to the first token after the relevant syntax block.
1423  *
1424  *
1425  * \par Syntax:
1426  * ~~~~~~~~
1427  * <command> ::= <argv0> [<required-arg-list>] [<optional-arg-list>]
1428  * ~~~~~~~~
1429  *
1430  * \param [in,out] cmddef Command definition.
1431  * \param [in,out] form Command form definition.
1432  * \param [in] tokens Lexical tokens generated from the syntax usage.
1433  *
1434  * \copydoc doc_return_cl
1435  */
1436  virtual int parseSyntax(CmdDef &cmddef,
1437  CmdFormDef &form,
1438  const TokenVec &tokens);
1439 
1440  /*!
1441  * \brief Parse argument 0 (command name) syntax.
1442  *
1443  * Argv0 is a special argument that defines the command name. Only
1444  * literal and variable arguments types are valid.
1445  *
1446  * \par Syntax:
1447  * ~~~~~~~~
1448  * <argv0> ::= <literal-arg>
1449  * | <variable-arg>
1450  * ~~~~~~~~
1451  *
1452  * \param [in,out] cmddef Command definition.
1453  * \param [in,out] form Command form definition.
1454  * \param [in] tokens Lexical tokens generated from the syntax usage.
1455  * \param [in,out] pos The parse cursor position. \sa parseSyntax().
1456  *
1457  * \return Returns true on a successful parse, false otherwise.
1458  */
1459  bool parseArgv0(CmdDef &cmddef,
1460  CmdFormDef &form,
1461  const TokenVec &tokens,
1462  size_t &pos);
1463 
1464  /*!
1465  * \brief Parse required argument list syntax.
1466  *
1467  * \par Syntax:
1468  * ~~~~~~~~
1469  * <required-arg-list> ::= <arg>
1470  * | <required-arg-list> <arg>
1471  * ~~~~~~~~
1472  *
1473  * \param [in,out] cmddef Command definition.
1474  * \param [in,out] form Command form definition.
1475  * \param [in] tokens Lexical tokens generated from the syntax usage.
1476  * \param [in,out] pos The parse cursor position. \sa parseSyntax().
1477  *
1478  * \return Returns true on a successful parse, false otherwise.
1479  */
1480  bool parseRequiredArgList(CmdDef &cmddef,
1481  CmdFormDef &form,
1482  const TokenVec &tokens,
1483  size_t &pos);
1484 
1485  /*!
1486  * \brief Parse optional argument list syntax.
1487  *
1488  * \par Syntax:
1489  * ~~~~~~~~
1490  * <optional-arg-list> ::= '[' <arg> ']'
1491  * | <optional-arg-list> '[' <arg> ']'
1492  * ~~~~~~~~
1493  *
1494  * \param [in,out] cmddef Command definition.
1495  * \param [in,out] form Command form definition.
1496  * \param [in] tokens Lexical tokens generated from the syntax usage.
1497  * \param [in,out] pos The parse cursor position. \sa parseSyntax().
1498  *
1499  * \return Returns true on a successful parse, false otherwise.
1500  */
1501  bool parseOptionalArgList(CmdDef &cmddef,
1502  CmdFormDef &form,
1503  const TokenVec &tokens,
1504  size_t &pos);
1505 
1506  /*!
1507  * \brief Parse argument syntax.
1508  *
1509  * \par Syntax:
1510  * ~~~~~~~~
1511  * <arg> ::= <xor-list-arg>
1512  * | <variable-arg>
1513  * | <literal-arg>
1514  * ~~~~~~~~
1515  *
1516  * \param [in,out] cmddef Command definition.
1517  * \param [in,out] form Command form definition.
1518  * \param [in] tokens Lexical tokens generated from the syntax usage.
1519  * \param [in,out] pos The parse cursor position. \sa parseSyntax().
1520  *
1521  * \return Returns true on a successful parse, false otherwise.
1522  */
1523  bool parseArg(CmdDef &cmddef,
1524  CmdFormDef &form,
1525  const TokenVec &tokens,
1526  size_t &pos);
1527 
1528  /*!
1529  * \brief Parse mutually exclusive argument values syntax.
1530  *
1531  * A CmdArgDef object is added to the CmdDef
1532  *
1533  * \par Syntax:
1534  * ~~~~~~~~
1535  * <xor-list-arg> ::= '{' <xor-list> '}'
1536  * ~~~~~~~~
1537  *
1538  * \param [in,out] cmddef Command definition.
1539  * \param [in,out] form Command form definition.
1540  * \param [in] tokens Lexical tokens generated from the syntax usage.
1541  * \param [in,out] pos The parse cursor position. \sa parseSyntax().
1542  *
1543  * \return Returns true on a successful parse, false otherwise.
1544  */
1545  bool parseXorListArg(CmdDef &cmddef,
1546  CmdFormDef &form,
1547  const TokenVec &tokens,
1548  size_t &pos);
1549 
1550  /*!
1551  * \brief Parse variable argument syntax.
1552  *
1553  * A CmdArgDef object is added to the CmdDef
1554  *
1555  * \par Syntax:
1556  * ~~~~~~~~
1557  * <variable-arg> ::= '<' <identifier> '>'
1558  * | '<' <identifier> ':' <var-modifier> '>'
1559  * ~~~~~~~~
1560  *
1561  * \param [in,out] cmddef Command definition.
1562  * \param [in,out] form Command form definition.
1563  * \param [in] tokens Lexical tokens generated from the syntax usage.
1564  * \param [in,out] pos The parse cursor position. \sa parseSyntax().
1565  *
1566  * \return Returns true on a successful parse, false otherwise.
1567  */
1568  bool parseVariableArg(CmdDef &cmddef,
1569  CmdFormDef &form,
1570  const TokenVec &tokens,
1571  size_t &pos);
1572 
1573  /*!
1574  * \brief Parse literal, fixed-valued argument syntax.
1575  *
1576  * A CmdArgDef object is added to the CmdDef
1577  *
1578  * \par Syntax:
1579  * ~~~~~~~~
1580  * <literal-arg> ::= <literal>
1581  * ~~~~~~~~
1582  *
1583  * \param [in,out] cmddef Command definition.
1584  * \param [in,out] form Command form definition.
1585  * \param [in] tokens Lexical tokens generated from the syntax usage.
1586  * \param [in,out] pos The parse cursor position. \sa parseSyntax().
1587  *
1588  * \return Returns true on a successful parse, false otherwise.
1589  */
1590  bool parseLiteralArg(CmdDef &cmddef,
1591  CmdFormDef &form,
1592  const TokenVec &tokens,
1593  size_t &pos);
1594 
1595  /*!
1596  * \brief Parse mutually exclusive list.
1597  *
1598  * \par Syntax:
1599  * ~~~~~~~~
1600  * <xor-list> ::= <literal>
1601  * | <xor-list> '|' <literal>
1602  * ~~~~~~~~
1603  *
1604  * \param [in,out] cmddef Command definition.
1605  * \param [in,out] form Command form definition.
1606  * \param [in] tokens Lexical tokens generated from syntax usage.
1607  * \param [in,out] pos The parse cursor position. \sa parseSyntax().
1608  * \param [out] literals Vector of literals.
1609  *
1610  * \return Returns true on a successful parse, false otherwise.
1611  */
1612  bool parseXorList(CmdDef &cmddef,
1613  CmdFormDef &form,
1614  const TokenVec &tokens,
1615  size_t &pos,
1616  str::StringVec &literals);
1617 
1618  /*!
1619  * \brief Parse identifier.
1620  *
1621  * \par Syntax:
1622  * ~~~~~~~~
1623  * <identifier> ::= ALPHA {ALPHANUMERIC}*
1624  * | '_' {ALPHANUMERIC}*
1625  * ~~~~~~~~
1626  *
1627  * \param [in,out] cmddef Command definition.
1628  * \param [in,out] form Command form definition.
1629  * \param [in] tokens Lexical tokens generated from syntax usage.
1630  * \param [in,out] pos The parse cursor position. \sa parseSyntax().
1631  * \param [out] strIdent Identity string.
1632  *
1633  * \return Returns true on a successful parse, false otherwise.
1634  */
1635  bool parseIdentifier(CmdDef &cmddef,
1636  CmdFormDef &form,
1637  const TokenVec &tokens,
1638  size_t &pos,
1639  std::string &strIdent);
1640 
1641  /*!
1642  * \brief Parse variable modifier.
1643  *
1644  * \par Syntax:
1645  * ~~~~~~~~
1646  * <var-modifier> ::= <var-type>
1647  * | <var-type> <var-paren-expr>
1648  *
1649  * <var-paren-expr> ::= '(' <range-expr> ')'
1650  * | '(' <regex> ')'
1651  * ~~~~~~~~
1652  *
1653  * \param [in,out] cmddef Command definition.
1654  * \param [in,out] form Command form definition.
1655  * \param [in] tokens Lexical tokens generated from the syntax usage.
1656  * \param [in,out] pos The parse cursor position. \sa parseSyntax().
1657  * \param [out] eType Type enum.
1658  * \param [out] ranges Vector of ranges.
1659  * \param [out] re Regular expression.
1660  *
1661  * \return Returns true on a successful parse, false otherwise.
1662  */
1663  bool parseVarMod(CmdDef &cmddef,
1664  CmdFormDef &form,
1665  const TokenVec &tokens,
1666  size_t &pos,
1667  CmdArgDef::ArgType &eType,
1668  CmdArgDef::RangeVec &ranges,
1669  RegEx &re);
1670 
1671  /*!
1672  * \brief Parse variable type.
1673  *
1674  * \par Syntax:
1675  * ~~~~~~~~
1676  * <var-type> ::= word | multiword | identifier | bool |
1677  * int | fpn | re | file
1678  * ~~~~~~~~
1679  *
1680  * \param [in,out] cmddef Command definition.
1681  * \param [in,out] form Command form definition.
1682  * \param [in] tokens Lexical tokens generated from the syntax usage.
1683  * \param [in,out] pos The parse cursor position. \sa parseSyntax().
1684  * \param [out] eType Type enum.
1685  *
1686  * \return Returns true on a successful parse, false otherwise.
1687  */
1688  bool parseVarType(CmdDef &cmddef,
1689  CmdFormDef &form,
1690  const TokenVec &tokens,
1691  size_t &pos,
1692  CmdArgDef::ArgType &eType);
1693 
1694  /*!
1695  * \brief Parse variable range expression.
1696  *
1697  * \par Syntax:
1698  * ~~~~~~~~
1699  * <range-expr> ::= <range>
1700  * | <range-expr> ',' <range>
1701  *
1702  * <range> ::= NUMBER
1703  * | NUMBER ':' NUMBER
1704  * ~~~~~~~~
1705  *
1706  * \param [in,out] cmddef Command definition.
1707  * \param [in,out] form Command form definition.
1708  * \param [in] tokens Lexical tokens generated from the syntax usage.
1709  * \param [in,out] pos The parse cursor position. \sa parseSyntax().
1710  * \param [out] ranges Vector of ranges.
1711  *
1712  * \return Returns true on a successful parse, false otherwise.
1713  */
1714  bool parseVarRangeExpr(CmdDef &cmddef,
1715  CmdFormDef &form,
1716  const TokenVec &tokens,
1717  size_t &pos,
1718  CmdArgDef::RangeVec &ranges);
1719 
1720  /*!
1721  * \brief Parse variable regular expression.
1722  *
1723  * \par Syntax:
1724  * ~~~~~~~~
1725  * <regex> ::= REGEX
1726  * ~~~~~~~~
1727  *
1728  * \param [in,out] cmddef Command definition.
1729  * \param [in,out] form Command form definition.
1730  * \param [in] tokens Lexical tokens generated from the syntax usage.
1731  * \param [in,out] pos The parse cursor position. \sa parseSyntax().
1732  * \param [out] re Regular expression.
1733  *
1734  * \return Returns true on a successful parse, false otherwise.
1735  */
1736  bool parseVarRegExpr(CmdDef &cmddef,
1737  CmdFormDef &form,
1738  const TokenVec &tokens,
1739  size_t &pos,
1740  RegEx &re);
1741 
1742  /*!
1743  * \brief Parse literal value.
1744  *
1745  * \par Syntax:
1746  * ~~~~~~~~
1747  * <literal> ::= {NON_SPECIAL_CHAR}+
1748  * ~~~~~~~~
1749  *
1750  * \param [in,out] cmddef Command definition.
1751  * \param [in,out] form Command form definition.
1752  * \param [in] tokens Lexical tokens generated from syntax usage.
1753  * \param [in,out] pos The parse cursor position. \sa parseSyntax().
1754  * \param [out] strValue Value string.
1755  *
1756  * \return Returns true on a successful parse, false otherwise.
1757  */
1758  bool parseLiteralValue(CmdDef &cmddef,
1759  CmdFormDef &form,
1760  const TokenVec &tokens,
1761  size_t &pos,
1762  std::string &strValue);
1763 
1764  /*!
1765  * \brief Test if token at position is equal to string.
1766  *
1767  * If equal, the position cursor is advanced on position. If not equal,
1768  * an error message will be logged.
1769  *
1770  * \param [in] strCmp String to compare token against.
1771  * \param [in] tokens Lexical tokens generated from the syntax usage.
1772  * \param [in,out] pos The position in the token vector.
1773  * Advanced 1 position if equal.
1774  *
1775  * \return Returns true on equal, false otherwise.
1776  */
1777  bool tokEq(const std::string strCmp, const TokenVec &tokens, size_t &pos);
1778 
1779  /*!
1780  * \brief Peek if token is equal to string.
1781  *
1782  * The position cursor is not advance nor any error message logged.
1783  *
1784  * \param [in] strCmp String to compare token against.
1785  * \param [in] token Lexical token.
1786  *
1787  * \return Returns true on equal, false otherwise.
1788  */
1789  bool peekEq(const std::string strCmp, const Token &token) const
1790  {
1791  return token.value() == strCmp;
1792  }
1793 
1794  /*!
1795  * \brief Test if string has valid identifier syntax.
1796  *
1797  * \param [in] tokens Lexical tokens generated from the syntax usage.
1798  * \param [in,out] pos The position in the token vector.
1799  * Advanced 1 position if valid identifier.
1800  *
1801  * \return Returns true or false.
1802  */
1803  bool tokIdentifier(const TokenVec &tokens, size_t &pos);
1804 
1805 
1806  // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1807  // Command Line Interface Support Methods
1808  // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1809 
1810  /*!
1811  * \brief Process a line of input.
1812  *
1813  * The line is tokenized and matched to the command with the best fit.
1814  *
1815  * \param [in] strLine Line of input.
1816  * \param [out] argv Vector of extended arguments, with argv[0] being
1817  * the command name argument.
1818  *
1819  * \copydoc doc_return_cl
1820  */
1821  int processInput(const std::string &strLine, CmdExtArgVec &argv);
1822 
1823  /*!
1824  * \brief Match the input tokens to the compiled commands to find the
1825  * best fit.
1826  *
1827  * \param [in] tokens Vector of input tokens.
1828  * \param [out] argv Vector of extended arguments, with argv[0] being
1829  * the command name argument.
1830  *
1831  * \copydoc doc_return_cl
1832  */
1833  int match(const TokenVec &tokens, CmdExtArgVec &argv);
1834 
1835  /*!
1836  * \brief Match best command form against input line argument list.
1837  *
1838  * \param [in] cmddef Compiled command definition.
1839  * \param [in] tokens Vector of arguments.
1840  * \param [out] argv Vector of extended arguments, with argv[0] being
1841  * the command name argument.
1842  * \param [out] fFitness Fitness of match [0.0 - 1.0].
1843  *
1844  * \copydoc doc_return_cl
1845  */
1846  int matchCommand(const CmdDef &cmddef,
1847  const TokenVec &tokens,
1848  CmdExtArgVec &argv,
1849  double &fFitness);
1850 
1851  /*!
1852  * \brief Match command form against input line argument list.
1853  *
1854  * \param [in] form Compiled command form definition.
1855  * \param [in] tokens Vector of arguments.
1856  * \param [out] argv Vector of extended arguments, with argv[0] being
1857  * the command name argument.
1858  * \param [out] fFitness Fitness of match [0.0 - 1.0].
1859  *
1860  * \copydoc doc_return_cl
1861  */
1862  int matchCommandForm(const CmdFormDef &form,
1863  const TokenVec &tokens,
1864  CmdExtArgVec &argv,
1865  double &fFitness);
1866 
1867  /*!
1868  * \brief Check read input result.
1869  *
1870  * \copydoc doc_return_cl
1871  */
1872  int checkReadResult();
1873 
1874  /*!
1875  * \brief Convert extended argument vector to string argument vector.
1876  *
1877  * \param [in] v1 Extended argument vector.
1878  * \param [out] v2 String argument vector.
1879  */
1880  void toVec(const CmdExtArgVec &v1, str::StringVec &v2);
1881 
1882 
1883  // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1884  // ReadLine Generator Methods
1885  // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1886 
1887  /*!
1888  * \brief Perform any necessary pre-processing to prepare for command line
1889  * TAB completion.
1890  *
1891  * \note Nothing is needed for the CommandLine base class.
1892  *
1893  * \copydoc doc_return_cl
1894  */
1895  virtual int rlBuildReadLineGenerator();
1896 
1897  /*!
1898  * \brief Static TAB completion generator wrapper.
1899  *
1900  * See \ref ReadLine::AltAppGenFunc for description of a ReadLine
1901  * generator.
1902  *
1903  * \param pAppArg Pointer to this CommandLine object.
1904  * \param strText Partial text string to complete.
1905  * \param nIndex Match candidate index starting from 0.
1906  * \param strContext Generator context (i.e. input buffer).
1907  * \param nStart Starting index in context of text.
1908  * \param nEnd Ending index in context of the position
1909  * immediately after the end of text. If nStart
1910  * equals nEnd, then empty text.
1911  * \param [out] uFlags TAB completion modifier flags.
1912  *
1913  * \return Match or empty string.
1914  */
1915  static const std::string rlGeneratorWrapper(void *pAppArg,
1916  const std::string &strText,
1917  int nIndex,
1918  const std::string &strContext,
1919  int nStart,
1920  int nEnd,
1921  unsigned &uFlags);
1922 
1923  /*!
1924  * \brief TAB completion generator.
1925  *
1926  * See \ref ReadLine::AltAppGenFunc for description of a ReadLine
1927  * generator.
1928  *
1929  * \param strText Partial text string to complete.
1930  * \param nIndex Match candidate index starting from 0.
1931  * \param strContext Generator context (i.e. input buffer).
1932  * \param nStart Starting index in context of text.
1933  * \param nEnd Ending index in context of the position
1934  * immediately after the end of text. If nStart
1935  * equals nEnd, then empty text.
1936  * \param [out] uFlags TAB completion modifier flags.
1937  *
1938  * \return Match or empty string.
1939  */
1940  virtual const std::string rlGenerator(const std::string &strText,
1941  int nIndex,
1942  const std::string &strContext,
1943  int nStart,
1944  int nEnd,
1945  unsigned &uFlags);
1946 
1947  /*!
1948  * \brief Build list of all command argument definitions that match
1949  * completed subtext.
1950  *
1951  * \param [in] strSubtext Complete subtext string.
1952  * \param [out] argdefs List of matched argument definitions.
1953  */
1954  void rlArgDefs(const std::string &strSubtext,
1955  std::vector<CmdArgDef*> &argdefs);
1956 
1957  /*!
1958  * \brief Build TAB completion list and set appropriate readline
1959  * modifiers.
1960  *
1961  * \param [in] strText Partial text string to complete.
1962  * \param [in] argdefs List of matched argument definitions.
1963  * \param [out] tabList List of TAB completion matches.
1964  * \param [out] uFlags TAB completion modifier flags.
1965  */
1966  void rlTabList(const std::string &strText,
1967  std::vector<CmdArgDef*> &argdefs,
1968  str::StringVec &tabList,
1969  unsigned &uFlags);
1970 
1971  /*!
1972  * \brief Match partial text agains literal string.
1973  *
1974  * Ignore case is taken into account when strings are compared.
1975  *
1976  * \param [in] strText Partial text string to complete.
1977  * \param [in] strLiteral Literal text string to compare.
1978  * \param [in] uLen Number of characters to match.
1979  *
1980  * \return Returns true on partial match, false otherwise.
1981  */
1982  bool rlPartialMatch(const std::string &strText,
1983  const std::string strLiteral,
1984  const size_t uLen);
1985 
1986  }; // class CommandLine
1987 
1988  } // namespace cmd
1989 } // namespace rnr
1990 
1991 #endif // _RNR_COMMAND_LINE_H
Command line command form definition class interface.
Command line extended argument interface.
Command EXTended ARGument class holding parsed command context and the raw and converted argmument va...
Definition: CmdExtArg.h:91
CmdExecMap::iterator CmdExecIter
exec iterator type
Definition: CommandLine.h:424
std::vector< std::string > StringVec
Useful types.
Definition: StringTheory.h:83
std::string m_strName
name of this command line
Definition: CommandLine.h:1187
CmdExec(int uid, CmdExec2Func fn)
Variant 2 constructor.
Definition: CommandLine.h:196
CmdDefMap::const_iterator CmdDefCIter
cmd const iter type
Definition: CommandLine.h:418
LogBook m_log
trace and error log
Definition: CommandLine.h:1195
CmdExec(const CmdExec &src)
Copy constructor.
Definition: CommandLine.h:221
virtual int readCommand(CmdExtArgVec &argv)
Read an input line from stdin and match to the best compiled command.
Definition: CommandLine.h:713
const void * data() const
Return section data.
Definition: CommandLine.h:371
CmdDefCIter begin() const
Return a constant iterator pointing to the first element of the list of command definitions.
Definition: CommandLine.h:1119
ReadLine m_readline
readline interface
Definition: CommandLine.h:1194
Command line interface data section class.
Definition: CommandLine.h:315
CmdExec2Func fn2
execution function variant 2
Definition: CommandLine.h:292
size_t getLineNum() const
Get the line number of the last read line.
Definition: CommandLine.h:853
bool m_bIsCompiled
has [not] been successfully compiled
Definition: CommandLine.h:1190
bool getBtEnable() const
Test if backtracing is enabled.
Definition: CommandLine.h:499
Variant
Execution function variant enumeration.
Definition: CommandLine.h:277
void quit()
Mark command-line interface to quit.
Definition: CommandLine.h:489
Variant m_variant
function variant enum
Definition: CommandLine.h:297
bool peekEq(const std::string strCmp, const Token &token) const
Peek if token is equal to string.
Definition: CommandLine.h:1789
const char *const DataSectNsCore
Reserved command line data section namespaces.
Definition: CmdCore.h:141
CmdDefCIter end() const
Return a constant iterator referring to the past-the-end element of the list of command definitions...
Definition: CommandLine.h:1130
int(* CmdExec2Func)(const CmdExtArgVec &argv)
Command execution function type, variant 2.
Definition: CommandLine.h:139
Regular Express Class.
Definition: RegEx.h:84
std::map< unsigned, CmdExec > CmdExecMap
exec map type
Definition: CommandLine.h:423
const int NoUid
Special values.
Definition: CmdCore.h:116
int numOfCmds() const
Get the total number of added commands.
Definition: CommandLine.h:1108
CmdExec(int uid, CmdExec3Func fn)
Variant 3 constructor.
Definition: CommandLine.h:209
Of string spaces and their strangian operators.
User available command description structure.
Definition: CmdCore.h:85
int m_uid
command unique id associated with this execution
Definition: CommandLine.h:296
CmdExec()
Default constructor.
Definition: CommandLine.h:170
void * m_pData
pointer to section data
Definition: CommandLine.h:322
std::map< std::string, DataSect > DataSectMap
section map type
Definition: CommandLine.h:430
std::vector< Token > TokenVec
vector of tokens type
Definition: Token.h:222
Compiled command definition class.
Definition: CmdDef.h:88
const std::string & value() const
Return token string.
Definition: Token.h:149
LogBook class interface.
int execute(const str::StringVec &argv)
Execute a comamnd with the given arguments.
std::vector< CmdExtArg > CmdExtArgVec
vector of ext args type
Definition: CmdExtArg.h:397
CmdExecMap m_cmdExecs
map of added command executions
Definition: CommandLine.h:1192
CmdDefMap::iterator CmdDefIter
cmd iterator type
Definition: CommandLine.h:417
DeallocFunc m_fnDealloc
data deallocator function
Definition: CommandLine.h:323
FnVar m_exec
function execution variant
Definition: CommandLine.h:298
The thin ReadLine wrapper class interface.
CmdExec(int uid, CmdExec1Func fn)
Variant 1 constructor.
Definition: CommandLine.h:183
std::string m_strNs
data section namespace
Definition: CommandLine.h:321
friend std::ostream & operator<<(std::ostream &os, const CmdExec &obj)
Insert object into output stream.
Command line command definition class interface.
Helper class to hold a command line execution function.
Definition: CommandLine.h:164
const std::string & ns() const
Return namespace.
Definition: CommandLine.h:351
ArgType
Argument type enumeration.
Definition: CmdArgDef.h:95
std::map< unsigned, CmdDef > CmdDefMap
command map type
Definition: CommandLine.h:416
Command line argument definition class interface.
DataSectMap::iterator DataSectIter
iterator type
Definition: CommandLine.h:431
void setBtEnable(bool bEnable)
Enable/disable backtracing.
Definition: CommandLine.h:510
int(* CmdExec3Func)(CommandLine &cli, const CmdExtArgVec &argv)
Command execution function type, variant 3.
Definition: CommandLine.h:154
int(* CmdExec1Func)(const str::StringVec &argv)
Command execution function type, variant 1.
Definition: CommandLine.h:119
virtual int readCommand(int &uid, int &iform, str::StringVec &argv)
Read an input line from stdin and match to the best compiled command.
Definition: CommandLine.h:683
PromptStack m_prompts
stack of prompt strings
Definition: CommandLine.h:1193
const DeallocFunc deallocator() const
Return deallocator.
Definition: CommandLine.h:391
DeallocFunc deallocator()
Return deallocator.
Definition: CommandLine.h:381
CmdExecMap::const_iterator CmdExecCIter
exec const iter type
Definition: CommandLine.h:425
CmdExec3Func fn3
execution function variant 3
Definition: CommandLine.h:293
ReadLine class provides a C++ wrapper around the readline C library.
Definition: ReadLine.h:112
void(* DeallocFunc)(void *)
Definition: CommandLine.h:319
Union of all variant execution functions.
Definition: CommandLine.h:288
Command line core data types.
bool ok() const
Test if command-line interface is ok to continue.
Definition: CommandLine.h:481
std::vector< range > RangeVec
vector of subranges
Definition: CmdArgDef.h:129
const std::string & getName() const
Get command line interface&#39;s name.
Definition: CommandLine.h:1040
Parsed token container class.
Definition: Token.h:84
The Regular Expression Class interface.
void setLineNum(const size_t uLineNum)
Set the current line number.
Definition: CommandLine.h:863
void * data()
Return section data.
Definition: CommandLine.h:361
DataSectMap::const_iterator DataSectCIter
const iter type
Definition: CommandLine.h:432
DataSectMap m_dataSects
data sections
Definition: CommandLine.h:1196
std::string c14n(const std::string &str)
Simple canonicalization of a string.
bool m_bIgnoreCase
do [not] ignore case on commands
Definition: CommandLine.h:1188
RoadNarrows Robotics.
Definition: Camera.h:74
str::StringVec PromptStack
prompt stack type
Definition: CommandLine.h:434
int m_nUidCnt
unique id counter
Definition: CommandLine.h:1189
Compiled command form defintion class.
Definition: CmdFormDef.h:91
CommandLine class.
Definition: CommandLine.h:444
Core data section type.
Definition: CmdCore.h:148
int getUid() const
Get associated command&#39;s unique id.
Definition: CommandLine.h:258
void resetLineNum()
Reset the line number to zero.
Definition: CommandLine.h:871
Simple, token container class interface.
CmdDefMap m_cmdDefs
map of added command definitions
Definition: CommandLine.h:1191
CmdExec1Func fn1
execution function variant 1
Definition: CommandLine.h:291