1 /*
2    Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
3 
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License, version 2.0,
6    as published by the Free Software Foundation.
7 
8    This program is also distributed with certain software (including
9    but not limited to OpenSSL) that is licensed under separate terms,
10    as designated in a particular file or component or in included license
11    documentation.  The authors of MySQL hereby grant you an additional
12    permission to link the program and your derivative works with the
13    separately licensed software that they have included with MySQL.
14 
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License, version 2.0, for more details.
19 
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
23 */
24 
25 #ifndef ABSTRACT_OPTIONS_PROVIDER_INCLUDED
26 #define ABSTRACT_OPTIONS_PROVIDER_INCLUDED
27 
28 #include <map>
29 #include <string>
30 
31 #include "client/base/bool_option.h"
32 #include "client/base/char_array_option.h"
33 #include "client/base/disabled_option.h"
34 #include "client/base/enum_option.h"
35 #include "client/base/i_option.h"
36 #include "client/base/i_option_changed_listener.h"
37 #include "client/base/i_options_provider.h"
38 #include "client/base/number_option.h"
39 #include "client/base/password_option.h"
40 #include "client/base/simple_option.h"
41 #include "client/base/string_option.h"
42 #include "my_inttypes.h"
43 
44 namespace Mysql {
45 namespace Tools {
46 namespace Base {
47 namespace Options {
48 
49 /**
50   Common abstract class for options providers.
51   Provides common functionalities.
52  */
53 class Abstract_options_provider : public I_options_provider {
54  public:
55   /**
56     Creates and attach new simple option.
57     @param name Name of option. It is used in command-line option name as
58       --name.
59     @param description Description of option to be printed in --help.
60    */
61   Simple_option *create_new_option(std::string name, std::string description);
62   /**
63     Creates and attach new disabled option. This option is to mark existance
64     of options inavailable due to distribution configuration.
65     @param name Name of option. It is used in command-line option name as
66       --name.
67     @param description Description of option to be printed in --help.
68    */
69   Disabled_option *create_new_disabled_option(std::string name,
70                                               std::string description);
71   /**
72     Creates and attach new string option stored in char* type object.
73     @param value Pointer to char* object to receive option value.
74     @param name Name of option. It is used in command line option name as
75       --name.
76     @param description Description of option to be printed in --help.
77    */
78   Char_array_option *create_new_option(char **value, std::string name,
79                                        std::string description);
80   /**
81     Creates and attach new password option. It removes password from
82     command-line on UNIX systems to prevent password to be seen when listing
83     processes.
84     @param value Pointer to Nullable<string> object to receive option value.
85     @param name Name of option. It is used in command line option name as
86       --name.
87     @param description Description of option to be printed in --help.
88    */
89   Password_option *create_new_password_option(Nullable<std::string> *value,
90                                               std::string name,
91                                               std::string description);
92   /**
93     Creates and attach new string option.
94     @param value Pointer to Nullable<string> object to receive option value.
95     @param name Name of option. It is used in command line option name as
96       --name.
97     @param description Description of option to be printed in --help.
98    */
99   String_option *create_new_option(Nullable<std::string> *value,
100                                    std::string name, std::string description);
101   /**
102     Creates and attach new 32-bit signed number option.
103     @param value Pointer to int32 object to receive option value.
104     @param name Name of option. It is used in command line option name as
105       --name.
106     @param description Description of option to be printed in --help.
107    */
108   Number_option<int32> *create_new_option(int32 *value, std::string name,
109                                           std::string description);
110   /**
111     Creates and attach new 32-bit unsigned number option.
112     @param value Pointer to uint32 object to receive option value.
113     @param name Name of option. It is used in command line option name as
114       --name.
115     @param description Description of option to be printed in --help.
116    */
117   Number_option<uint32> *create_new_option(uint32 *value, std::string name,
118                                            std::string description);
119   /**
120     Creates and attach new 64-bit signed number option.
121     @param value Pointer to int64 object to receive option value.
122     @param name Name of option. It is used in command line option name as
123       --name.
124     @param description Description of option to be printed in --help.
125    */
126   Number_option<int64> *create_new_option(int64 *value, std::string name,
127                                           std::string description);
128   /**
129     Creates and attach new 64-bit unsigned number option.
130     @param value Pointer to uint64 object to receive option value.
131     @param name Name of option. It is used in command line option name as
132       --name.
133     @param description Description of option to be printed in --help.
134    */
135   Number_option<uint64> *create_new_option(uint64 *value, std::string name,
136                                            std::string description);
137   /**
138     Creates and attach new floating-point number option.
139     @param value Pointer to double object to receive option value.
140     @param name Name of option. It is used in command line option name as
141       --name.
142     @param description Description of option to be printed in --help.
143    */
144   Number_option<double> *create_new_option(double *value, std::string name,
145                                            std::string description);
146   /**
147     Creates and attach new boolean option with value received from argument.
148     @param value Pointer to double object to receive option value.
149     @param name Name of option. It is used in command line option name as
150       --name.
151     @param description Description of option to be printed in --help.
152    */
153   Bool_option *create_new_option(bool *value, std::string name,
154                                  std::string description);
155 
156   template <typename T_type, typename T_typelib>
create_new_enum_option(T_type * value,const T_typelib * type,std::string name,std::string description)157   Enum_option<T_type, T_typelib> *create_new_enum_option(
158       T_type *value, const T_typelib *type, std::string name,
159       std::string description) {
160     return this->attach_new_option<Enum_option<T_type, T_typelib>>(
161         new Enum_option<T_type, T_typelib>(value, type, name, description));
162   }
163 
164   /**
165     Creates all options that will be provided.
166    */
167   virtual void create_options() = 0;
168 
169   /**
170     Creates list of options provided by this provider.
171     Part of I_options_provider interface implementation.
172     @returns list of my_getopt internal option data structures.
173    */
174   virtual std::vector<my_option> generate_options();
175   /**
176     Callback to be called when command-line options parsing have finished.
177     Part of I_options_provider interface implementation.
178    */
179   virtual void options_parsed();
180 
181  protected:
182   Abstract_options_provider();
183   virtual ~Abstract_options_provider();
184 
185   /**
186     Sets optional option changes listener to which all changes in all options
187     contained in this provider should be reported. This is used when this
188     provider is attached to another.
189     Part of I_options_provider interface implementation.
190    */
191   virtual void set_option_changed_listener(I_option_changed_listener *listener);
192 
193  private:
194   /**
195     Makes sure this provider will be able to watch name and optid usage.
196    */
197   template <typename T_type>
attach_new_option(T_type * option)198   T_type *attach_new_option(T_type *option) {
199     // Make this option reporting all name and optid changes to us.
200     option->set_option_changed_listener(this);
201 
202     // Add to list of our own options.
203     this->m_options_created.push_back(option);
204 
205     // Check for name and optid collision.
206     this->notify_option_name_changed(option, "");
207     this->notify_option_optid_changed(option, 0);
208 
209     return option;
210   }
211 
212   /**
213     Called after specified option has name changed.
214     It is also called when new option is added, old_name is empty string in
215     that case.
216     Part of I_option_changed_listener interface implementation.
217    */
218   virtual void notify_option_name_changed(I_option *source,
219                                           std::string old_name);
220   /**
221     Called after specified option has option ID changed.
222     It is also called when new option is added, old_optid is 0 in that case.
223     Part of I_option_changed_listener interface implementation.
224    */
225   virtual void notify_option_optid_changed(I_option *source, uint32 old_optid);
226 
227   bool m_are_options_created;
228   std::map<std::string, I_option *> m_name_usage;
229   std::map<uint32, I_option *> m_optid_usage;
230   I_option_changed_listener *m_option_changed_listener;
231   std::vector<I_option *> m_options_created;
232 };
233 
234 }  // namespace Options
235 }  // namespace Base
236 }  // namespace Tools
237 }  // namespace Mysql
238 
239 #endif
240