1/* Copyright (C) 2004 The glibmm Development Team 2 * 3 * This library is free software; you can redistribute it and/or 4 * modify it under the terms of the GNU Lesser General Public 5 * License as published by the Free Software Foundation; either 6 * version 2.1 of the License, or (at your option) any later version. 7 * 8 * This library is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 * Lesser General Public License for more details. 12 * 13 * You should have received a copy of the GNU Lesser General Public 14 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 15 */ 16 17_DEFS(glibmm,glib) 18 19#include <glibmm/optionentry.h> 20#include <glibmm/optiongroup.h> 21#include <glibmm/error.h> 22#include <sigc++/signal.h> 23 24#ifndef DOXYGEN_SHOULD_SKIP_THIS 25extern "C" { typedef struct _GOptionContext GOptionContext; } 26#endif 27 28 29namespace Glib 30{ 31 32/** Exception class for options. 33 */ 34_WRAP_GERROR(OptionError, GOptionError, G_OPTION_ERROR, NO_GTYPE, decl_prefix GLIBMM_API) 35 36/** An OptionContext defines and parses commandline options, using OptionGroup%s and \link OptionEntry option entries \endlink. 37 * 38 * It supports short and long commandline options, as shown in the following example: 39 * 40 * <tt>testtreemodel -r 1 --max-size 20 --rand --display=:1.0 -vb -- file1 file2</tt> 41 * 42 * The example demonstrates a number of features of the GOption 43 * commandline parser: 44 * - Options can be single letters, prefixed by a single dash. 45 * - Multiple short options can be grouped behind a single dash. 46 * - Long options are prefixed by two consecutive dashes. 47 * - Options can have an extra argument, which can be a number, a string or 48 * a filename. For long options, the extra argument can be appended with 49 * an equals sign after the option name, which is useful if the extra 50 * argument starts with a dash, which would otherwise cause it to be 51 * interpreted as another option. 52 * - Non-option arguments are returned to the application as rest arguments. 53 * - An argument consisting solely of two dashes turns off further parsing, 54 * any remaining arguments (even those starting with a dash) are returned 55 * to the application as rest arguments. 56 * 57 * The OptionContext groups options in OptionGroups, which makes it easy to 58 * incorporate options from multiple sources. The intended use for this is 59 * to let applications collect option groups from the libraries it uses, 60 * add them to their OptionContext, and parse all options by a single call 61 * to parse(). See Gtk::Main::add_gtk_option_group(), for an example. 62 * 63 * Add options by creating OptionEntry instances and appropriately-typed variables, 64 * and adding them to an OptionGroup with OptionGroup::add_entry() or 65 * OptionGroup::add_entry_filename(). The option group should then be added to 66 * the OptionContext with set_main_group() or add_group(). 67 * 68 * You might find it convenient to derive your own class from OptionGroup to 69 * contain these OptionEntry instances and member variables. 70 * 71 * If an option is of type string (see OptionGroup::add_entry()) or filename 72 * (see OptionGroup::add_entry_filename()), OptionContext takes 73 * care of converting it to the right encoding. strings are returned in 74 * UTF-8 encoding and filenames are returned in the GLib filename encoding. 75 * Note that this only works if setlocale() has been called before 76 * OptionContext::parse(). 77 * 78 * OptionContext can automatically generate nicely formatted help output. Unless it is 79 * explicitly turned off with set_help_enabled(), this will recognize 80 * the --help, -?, --help-all and --help-groupname options 81 * (where groupname is the name of an OptionGroup) and write suitable text to 82 * stdout. 83 * 84 * 85 */ 86class GLIBMM_API OptionContext 87{ 88 _CLASS_GENERIC(OptionContext, GOptionContext) 89 _IGNORE(g_option_context_free) 90public: 91 92 /** Creates a new option context. 93 * @param parameter_string A string which is displayed in the first line of --help output, after programname [OPTION...] 94 */ 95 explicit OptionContext(const Glib::ustring& parameter_string = Glib::ustring()); 96 97 //Note that, unlike Glib::wrap(), this would create a second C++ instance for the same C instance, 98 //so it should be used carefully. For instance you could not access data in a derived class via this second instance. 99 explicit OptionContext(GOptionContext* castitem, bool take_ownership = false); 100 101 //TODO?: 102 //OptionContext(const OptionContext& other) = delete; 103 //OptionContext& operator=(const OptionContext& other) = delete; 104 105 OptionContext(OptionContext&& other) noexcept; 106 OptionContext& operator=(OptionContext&& other) noexcept; 107 108 virtual ~OptionContext(); 109 110 _WRAP_METHOD(void set_help_enabled(bool help_enabled = true), g_option_context_set_help_enabled) 111 _WRAP_METHOD(bool get_help_enabled() const, g_option_context_get_help_enabled) 112 _WRAP_METHOD(void set_ignore_unknown_options(bool ignore_unknown = true), g_option_context_set_ignore_unknown_options) 113 _WRAP_METHOD(bool get_ignore_unknown_options() const, g_option_context_get_ignore_unknown_options) 114 115 _WRAP_METHOD(void set_strict_posix(bool strict_posix = true), g_option_context_set_strict_posix) 116 _WRAP_METHOD(bool get_strict_posix() const, g_option_context_get_strict_posix) 117 118#m4 _CONVERSION(`char**&',`gchar***',`&($3)') 119 _WRAP_METHOD(bool parse(int& argc, char**& argv), g_option_context_parse, errthrow "Glib::OptionError, Glib::ConvertError", errthrow) 120 121 /** Parses the command line arguments. 122 * 123 * This function is similar to parse(int& argc, char**& argv) except that it 124 * respects the normal memory rules when dealing with a strv instead of 125 * assuming that the passed-in array is the argv of the main function. 126 * In particular, strings that are removed from the arguments list will 127 * be freed using g_free(). 128 * 129 * On Windows, the strings are expected to be in UTF-8. This is in 130 * contrast to parse(int& argc, char**& argv) which expects them to be in the 131 * system codepage, which is how they are passed as @a argv to main(). 132 * See g_win32_get_command_line() or Gio::ApplicationCommandLine::get_arguments() 133 * for a solution. 134 * 135 * This function is useful if you are trying to use OptionContext with 136 * Gio::Application. 137 * 138 * @newin{2,50} 139 * 140 * @param[in,out] argv A pointer to the command line arguments 141 * (which must be in UTF-8 on Windows). 142 * @return <tt>true</tt> if the parsing was successful, 143 * <tt>false</tt> if an error occurred. 144 * @throw Glib::OptionError 145 * @throw Glib::ConvertError 146 */ 147 _WRAP_METHOD(bool parse(char**& argv), g_option_context_parse_strv, errthrow) 148 149 //g_option_context_add_main_entries(), just creates a group internally, adds them to it, and does a set_main_group() 150 //- a group without callbacks seems to do some simple default parsing. 151 _IGNORE(g_option_context_add_main_entries) 152 153 /** Adds an OptionGroup to the context, so that parsing with context will recognize the options in the group. 154 * Note that the group will not be copied, so it should exist for as long as the context exists. 155 * 156 * @param group The group to add. 157 */ 158 void add_group(OptionGroup& group); 159 _IGNORE(g_option_context_add_group) 160 161 /** Sets an OptionGroup as the main group of the context. This has the same effect as calling add_group(), the only 162 * difference is that the options in the main group are treated differently when generating --help output. 163 * Note that the group will not be copied, so it should exist for as long as the context exists. 164 * 165 * @param group The group to add. 166 */ 167 void set_main_group(OptionGroup& group); 168 _IGNORE(g_option_context_set_main_group) 169 170 //We don't need this (hopefully), and the memory management would be really awkward. 171 //OptionGroup& get_main_group(); 172 //const OptionGroup& get_main_group() const; 173 _IGNORE(g_option_context_get_main_group) 174 175 #m4 _CONVERSION(`const OptionGroup&',`GOptionGroup*',`const_cast<GOptionGroup*>(($3).gobj())') 176 _WRAP_METHOD(Glib::ustring get_help(bool main_help, const OptionGroup& group) const, g_option_context_get_help) 177 178 /** Returns a formatted, translated help text for the given context. 179 * 180 * - To obtain the text produced by --help, call get_help(true). 181 * - To obtain the text produced by --help-all, call get_help(false). 182 * - To obtain the help text for an option group, call get_help(false, group). 183 * 184 * @param main_help If true, only include the main group. 185 * @result string containing the help text. 186 */ 187 Glib::ustring get_help(bool main_help = true) const; 188 189 GOptionContext* gobj() { return gobject_; } 190 const GOptionContext* gobj() const { return gobject_; } 191 192 _WRAP_METHOD(void set_summary(const Glib::ustring& summary), g_option_context_set_summary) 193 _WRAP_METHOD(Glib::ustring get_summary() const, g_option_context_get_summary) 194 _WRAP_METHOD(void set_description(const Glib::ustring& description), g_option_context_set_description) 195 _WRAP_METHOD(Glib::ustring get_description() const, g_option_context_get_description) 196 197 _WRAP_METHOD(void set_translation_domain(const Glib::ustring& domain), g_option_context_set_translation_domain) 198 199 /** 200 * This function is used to translate user-visible strings, for --help output. 201 * The function takes an untranslated string and returns a translated string 202 */ 203 using SlotTranslate = sigc::slot<Glib::ustring, const Glib::ustring&>; 204 205 /** 206 * Sets the function which is used to translate user-visible 207 * strings, for --help output. Different groups can use different functions. 208 * 209 * If you are using gettext(), you only need to set the translation domain, 210 * see set_translation_domain(). 211 * 212 * @newin{2,14} 213 */ 214 void set_translate_func (const SlotTranslate& slot); 215 _IGNORE(g_option_context_set_translate_func) 216 217protected: 218 219 GOptionContext* gobject_; 220 bool has_ownership_; 221}; 222 223 224} // namespace Glib 225 226