xorp

cli_command.hh

00001 // -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*-
00002 
00003 // Copyright (c) 2001-2011 XORP, Inc and Others
00004 //
00005 // This program is free software; you can redistribute it and/or modify
00006 // it under the terms of the GNU General Public License, Version 2, June
00007 // 1991 as published by the Free Software Foundation. Redistribution
00008 // and/or modification of this program under the terms of any other
00009 // version of the GNU General Public License is not permitted.
00010 // 
00011 // This program is distributed in the hope that it will be useful, but
00012 // WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For more details,
00014 // see the GNU General Public License, Version 2, a copy of which can be
00015 // found in the XORP LICENSE.gpl file.
00016 // 
00017 // XORP Inc, 2953 Bunker Hill Lane, Suite 204, Santa Clara, CA 95054, USA;
00018 // http://xorp.net
00019 
00020 // $XORP: xorp/cli/cli_command.hh,v 1.30 2008/10/02 21:56:29 bms Exp $
00021 
00022 
00023 #ifndef __CLI_CLI_COMMAND_HH__
00024 #define __CLI_CLI_COMMAND_HH__
00025 
00026 
00027 //
00028 // CLI command definition.
00029 //
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 #include "libxorp/callback.hh"
00038 #include "cli/libtecla/libtecla.h"
00039 
00040 
00041 //
00042 // Constants definitions
00043 //
00044 
00045 //
00046 // Structures/classes, typedefs and macros
00047 //
00048 class CliCommand;
00049 class CliClient;
00050 class CliCommandMatch;
00051 
00052 //
00053 // The callback to print-out the return result from a processing function
00054 //
00055 typedef XorpCallback5<int,  /* return_value */
00056     const string&,      /* server_name */
00057     const string&,      /* cli_term_name */
00058     uint32_t,           /* cli_session_id */
00059     const vector<string>&,  /* command_global_name */
00060     const vector<string>&   /* command_args */
00061 >::RefPtr CLI_PROCESS_CALLBACK;
00062 
00063 typedef XorpCallback5<void, /* return_value */
00064     const string&,      /* server_name */
00065     const string&,      /* cli_term_name */
00066     uint32_t,           /* cli_session_id */
00067     const vector<string>&,  /* command_global_name */
00068     const vector<string>&   /* command_args */
00069 >::RefPtr CLI_INTERRUPT_CALLBACK;
00070 
00071 typedef XorpCallback1<map<string, CliCommandMatch>, /* return value */
00072     const vector<string>&   /* global_name */
00073 >::RefPtr DYNAMIC_CHILDREN_CALLBACK;
00074 
00075 //
00076 // The type of a processing function that handles CLI commands
00077 //
00078 typedef int (* CLI_PROCESS_FUNC)(const string& server_name,
00079                  const string& cli_term_name,
00080                  uint32_t cli_session_id,
00081                  const vector<string>& command_global_name,
00082                  const vector<string>& command_args);
00083 typedef void (* CLI_INTERRUPT_FUNC)(const string& server_name,
00084                     const string& cli_term_name,
00085                     uint32_t cli_session_id,
00086                     const vector<string>& command_global_name,
00087                     const vector<string>& command_args);
00088 
00089 //
00090 // The type of a function that handles CLI command completions
00091 //
00092 #define CLI_COMPLETION_FUNC_(func) bool (func)(void *obj,       \
00093                           WordCompletion *cpl,  \
00094                           void *data,       \
00095                           const char *line,     \
00096                           int word_end,     \
00097                           list<CliCommand *>& cli_command_match_list)
00098 typedef CLI_COMPLETION_FUNC_(CLI_COMPLETION_FUNC);
00099 
00103 class CliCommand {
00104 public:
00105     typedef XorpCallback2<bool, const string&, string&>::RefPtr TypeMatchCb;
00106 
00115     CliCommand(CliCommand *init_parent_command,
00116            const string& init_command_name,
00117            const string& init_command_help);
00118 
00122     virtual ~CliCommand();
00123     
00132     void set_allow_cd(bool v, const string& init_cd_prompt);
00133     
00139     int create_default_cli_commands();
00140     
00147     int add_pipes(string& error_msg);
00148     
00165     CliCommand *add_command(const string& init_command_name,
00166                 const string& init_command_help,
00167                 bool is_multilevel_command,
00168                 string& error_msg);
00169     
00187     CliCommand *add_command(const string& init_command_name,
00188                 const string& init_command_help,
00189                 const string& init_cd_prompt,
00190                 bool is_multilevel_command,
00191                 string& error_msg);
00192     
00209     CliCommand *add_command(const string& init_command_name,
00210                 const string& init_command_help,
00211                 bool is_multilevel_command,
00212                 const CLI_PROCESS_CALLBACK& init_cli_process_callback,
00213                 string& error_msg);
00214 
00233     CliCommand *add_command(const string& init_command_name,
00234                 const string& init_command_help,
00235                 bool is_multilevel_command,
00236                 const CLI_PROCESS_CALLBACK& init_cli_process_callback,
00237                 const CLI_INTERRUPT_CALLBACK& init_cli_interrupt_callback,
00238                 string& error_msg);
00239     
00256     CliCommand *add_command(const string& init_command_name,
00257                 const string& init_command_help,
00258                 bool is_multilevel_command,
00259                 CLI_PROCESS_FUNC init_cli_process_func,
00260                 string& error_msg) {
00261     CLI_PROCESS_CALLBACK cb = callback(init_cli_process_func);
00262     return (add_command(init_command_name, init_command_help,
00263                 is_multilevel_command, cb, error_msg));
00264     }
00265 
00285     CliCommand *add_command(const string& init_command_name,
00286                 const string& init_command_help,
00287                 bool is_multilevel_command,
00288                 CLI_PROCESS_FUNC init_cli_process_func,
00289                 CLI_INTERRUPT_FUNC init_cli_interrupt_func,
00290                 string& error_msg) {
00291     CLI_PROCESS_CALLBACK cb1 = callback(init_cli_process_func);
00292     CLI_INTERRUPT_CALLBACK cb2 = callback(init_cli_interrupt_func);
00293     return (add_command(init_command_name, init_command_help,
00294                 is_multilevel_command, cb1, cb2, error_msg));
00295     }
00296     
00304     int add_command(CliCommand *child_command, string& error_msg);
00305     
00312     int delete_command(CliCommand *child_command);
00313     
00321     int delete_command(const string& delete_command_name);
00322     
00326     void delete_all_commands();
00327     
00333     void set_can_pipe(bool v) { _can_pipe = v; }
00334 
00341     bool default_nomore_mode() const { return (_default_nomore_mode); }
00342 
00349     void set_default_nomore_mode(bool v) { _default_nomore_mode = v; }
00350 
00356     bool is_command_argument() const { return (_is_command_argument); }
00357 
00364     void set_is_command_argument(bool v) { _is_command_argument = v; }
00365 
00371     bool is_argument_expected() const { return (_is_argument_expected); }
00372 
00378     void set_is_argument_expected(bool v) { _is_argument_expected = v; }
00379 
00385     const TypeMatchCb& type_match_cb() const { return (_type_match_cb); }
00386 
00392     void set_type_match_cb(const TypeMatchCb& cb) { _type_match_cb = cb; }
00393 
00399     bool has_type_match_cb() const;
00400 
00407     const vector<string>& global_name() const { return (_global_name); }
00408     
00414     void set_global_name(const vector<string>& v) { _global_name = v; }
00415     
00421     const string& server_name() const { return (_server_name); }
00422     
00428     void set_server_name(const string& v) { _server_name = v; }
00429     
00435     void set_dynamic_children_callback(DYNAMIC_CHILDREN_CALLBACK v);
00436     
00443     void set_dynamic_process_callback(const CLI_PROCESS_CALLBACK& v) {
00444     _dynamic_process_callback = v;
00445     }
00446 
00453     void set_dynamic_interrupt_callback(const CLI_INTERRUPT_CALLBACK& v) {
00454     _dynamic_interrupt_callback = v;
00455     }
00456 
00462     void set_cli_process_callback(const CLI_PROCESS_CALLBACK& v) {
00463     _cli_process_callback = v;
00464     }
00465 
00471     void set_cli_interrupt_callback(const CLI_INTERRUPT_CALLBACK& v) {
00472     _cli_interrupt_callback = v;
00473     }
00474 
00475 private:
00476     friend class CliClient;
00477     const string& name() const { return (_name); }
00478     const string& cd_prompt() { return (_cd_prompt); }
00479     
00480     list<CliCommand *>& child_command_list();
00481     
00482     static bool cli_attempt_command_completion_byname(void *obj,
00483                               WordCompletion *cpl,
00484                               void *data,
00485                               const char *line,
00486                               int word_end,
00487                               list<CliCommand *>& cli_command_match_list);
00488     
00489     const string& help() const { return (_help); }
00490     const string& help_completion() const { return (_help_completion); }
00491     
00492     int delete_pipes();
00493     
00494     bool is_same_prefix(const string& token);
00495     bool is_same_command(const string& token);
00496     CliCommand *command_find(const string& token);
00497     bool is_multi_command_prefix(const string& command_line);
00498     
00499     bool find_command_help(const char *line, int word_end,
00500                set<string>& help_strings);
00501     bool allow_cd() { return (_allow_cd); }
00502     
00503     
00504     bool has_cli_process_callback();
00505     bool has_cli_interrupt_callback();
00506     bool has_dynamic_process_callback();
00507     bool has_dynamic_interrupt_callback();
00508     bool has_cli_completion_func() { return (_cli_completion_func != NULL); }
00509     void set_cli_completion_func (CLI_COMPLETION_FUNC *v) {
00510     _cli_completion_func = v;
00511     }
00512     CLI_PROCESS_CALLBACK _cli_process_callback; // The processing callback
00513     CLI_INTERRUPT_CALLBACK _cli_interrupt_callback; // The interrupt callback
00514     CLI_COMPLETION_FUNC *_cli_completion_func;  // The function to call
00515                         // to complete a command
00516 
00517     // Store the callback to generate dynamic children
00518     DYNAMIC_CHILDREN_CALLBACK _dynamic_children_callback;
00519     bool _has_dynamic_children;
00520     // The cli_process_callback to copy to dynamic children
00521     CLI_PROCESS_CALLBACK _dynamic_process_callback;
00522     CLI_INTERRUPT_CALLBACK _dynamic_interrupt_callback;
00523     
00524     bool can_complete();
00525     bool can_pipe() const { return (_can_pipe); }
00526     CliCommand *cli_command_pipe();
00527     void set_cli_command_pipe(CliCommand *v) { _cli_command_pipe = v; }
00528     
00529     CliCommand *root_command() { return (_root_command); }
00530     void set_root_command(CliCommand *v) { _root_command = v; }
00531     
00532     CliCommand      *_root_command;     // The root command
00533     CliCommand      *_parent_command;   // Parent command or NULL if
00534                         // the root
00535     list<CliCommand *>  _child_command_list;    // A list with child commands
00536     const string    _name;          // The command name
00537     const string    _help;          // The command help
00538     vector<string>  _global_name;       // The command global name
00539     string      _server_name;       // The server to process this command
00540     string      _help_completion;   // The command help completion
00541     bool        _allow_cd;      // True if we can "cd" to this
00542     string      _cd_prompt;     // The prompt if we can "cd"
00543     bool        _can_pipe;      // True if accepts "|" after it
00544     bool        _default_nomore_mode;   // True if "no-more" (i.e., unpaged) mode is default
00545     bool        _is_command_argument;   // True if this is a command argument
00546     bool        _is_argument_expected;  // True if an argument is expected
00547     CliCommand      *_cli_command_pipe; // The "|" pipe command
00548     TypeMatchCb     _type_match_cb;     // The type match callback
00549 };
00550 
00551 class CliCommandMatch {
00552 public:
00553     CliCommandMatch(const string& command_name, const string& help_string,
00554             bool is_executable, bool can_pipe)
00555     : _command_name(command_name), _help_string(help_string),
00556       _is_executable(is_executable), _can_pipe(can_pipe),
00557       _default_nomore_mode(false), _is_command_argument(false),
00558       _is_argument_expected(false)
00559     {}
00560 #ifdef XORP_USE_USTL
00561     CliCommandMatch() { }
00562 #endif
00563 
00569     const string& command_name() const { return (_command_name); }
00570 
00576     const string& help_string() const { return (_help_string); }
00577 
00583     bool is_executable() const { return (_is_executable); }
00584 
00590     bool can_pipe() const { return (_can_pipe); }
00591 
00598     bool default_nomore_mode() const { return (_default_nomore_mode); }
00599 
00606     void set_default_nomore_mode(bool v) { _default_nomore_mode = v; }
00607 
00613     bool is_command_argument() const { return (_is_command_argument); }
00614 
00621     void set_is_command_argument(bool v) { _is_command_argument = v; }
00622 
00628     bool is_argument_expected() const { return (_is_argument_expected); }
00629 
00635     void set_is_argument_expected(bool v) { _is_argument_expected = v; }
00636     
00642     const CliCommand::TypeMatchCb& type_match_cb() const {
00643     return (_type_match_cb);
00644     }
00645 
00651     void set_type_match_cb(const CliCommand::TypeMatchCb& cb) {
00652     _type_match_cb = cb;
00653     }
00654 
00655 private:
00656     string  _command_name;      // The command name
00657     string  _help_string;       // The help string for the command
00658     bool    _is_executable;     // True if the command is executable
00659     bool    _can_pipe;      // True if the command supports pipes
00660     bool    _default_nomore_mode;   // True if "no-more" (i.e., unpaged) mode is default
00661     bool    _is_command_argument;   // True if this is a command argument
00662     bool    _is_argument_expected;  // True if an argument is expected
00663     CliCommand::TypeMatchCb _type_match_cb; // The type matching callback
00664 };
00665 
00666 //
00667 // Global variables
00668 //
00669 
00670 
00671 //
00672 // Global functions prototypes
00673 //
00674 
00675 #endif // __CLI_CLI_COMMAND_HH__
 All Classes Namespaces Functions Variables Typedefs Enumerations