Line data Source code
1 : // Copyright (c) 2006-2022 Made to Order Software Corp. All Rights Reserved
2 : //
3 : // https://snapwebsites.org/project/advgetopt
4 : // contact@m2osw.com
5 : //
6 : // This program is free software; you can redistribute it and/or modify
7 : // it under the terms of the GNU General Public License as published by
8 : // the Free Software Foundation; either version 2 of the License, or
9 : // (at your option) any later version.
10 : //
11 : // This program is distributed in the hope that it will be useful,
12 : // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : // GNU General Public License for more details.
15 : //
16 : // You should have received a copy of the GNU General Public License along
17 : // with this program; if not, write to the Free Software Foundation, Inc.,
18 : // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 :
20 : /** \file
21 : * \brief Advanced getopt data access implementation.
22 : *
23 : * The advgetopt class has many function used to access the data in the
24 : * class. These functions are gathered here.
25 : */
26 :
27 : // self
28 : //
29 : #include "advgetopt/advgetopt.h"
30 :
31 :
32 : // advgetopt lib
33 : //
34 : #include "advgetopt/exception.h"
35 :
36 :
37 : // last include
38 : //
39 : #include <snapdev/poison.h>
40 :
41 :
42 :
43 : namespace advgetopt
44 : {
45 :
46 :
47 : /** \brief Transform the argv[0] parameter in the program name.
48 : *
49 : * This function is transforms the first command line argument in a program
50 : * name. It will define two versions, the basename and the fullname which
51 : * you can access with the get_program_name() and get_program_fullname()
52 : * functions.
53 : *
54 : * \note
55 : * The %p and %*p options of the process_help_string() function make use
56 : * of this parameter. If you never call this function, they both use an
57 : * empty string as the program name.
58 : *
59 : * \exception getopt_exception_logic
60 : * If you call this function with a null pointer, then it raises this
61 : * exception.
62 : *
63 : * \param[in] argv The arguments vector.
64 : *
65 : * \sa get_program_name()
66 : * \sa get_program_fullname()
67 : * \sa process_help_string()
68 : */
69 276 : void getopt::parse_program_name(char * argv[])
70 : {
71 276 : if(argv == nullptr)
72 : {
73 1 : throw getopt_logic_error("argv pointer cannot be nullptr");
74 : }
75 275 : if(argv[0] != nullptr)
76 : {
77 274 : f_program_fullname = argv[0];
78 : }
79 :
80 275 : std::string::size_type p(f_program_fullname.find_last_of('/'));
81 275 : if(p == std::string::npos)
82 : {
83 : // MS-Windows path uses \ instead of /
84 : //
85 7 : p = f_program_fullname.find_last_of('\\');
86 : }
87 275 : if(p != std::string::npos)
88 : {
89 : // remove the path
90 : //
91 270 : f_program_name = f_program_fullname.substr(p + 1);
92 : }
93 : else
94 : {
95 5 : f_program_name = f_program_fullname;
96 : }
97 275 : }
98 :
99 :
100 : /** \brief Get the full name of the program.
101 : *
102 : * This function return the name of the program exactly as it was passed to
103 : * the program via argv[0].
104 : *
105 : * The reset() function will reset this parameter. If you are creating
106 : * internal lists of parameters that you want to parse with the same
107 : * getopt object and your main getopt object, then you may want to
108 : * consider using this function to define argv[0] of your new list:
109 : *
110 : * \code
111 : * std::vector<std::string> args;
112 : * args.push_back(my_opts.get_program_fullname());
113 : * args.push_back("--test");
114 : * [...]
115 : * // the following probably require some const_cast<>(), but that's the idea
116 : * my_opts.reset(args.size(), &args[0], ...);
117 : * \endcode
118 : *
119 : * \return The contents of the argv[0] parameter as defined on construction.
120 : *
121 : * \sa parse_program_name()
122 : */
123 171 : std::string getopt::get_program_fullname() const
124 : {
125 171 : return f_program_fullname;
126 : }
127 :
128 :
129 : /** \brief Get the basename of the program.
130 : *
131 : * This function retrieves the basename, the name of the program with its
132 : * path trimmed, from this getopt object.
133 : *
134 : * This is defined from the argv[0] parameter passed to the constructor or
135 : * the last reset() call.
136 : *
137 : * \return The basename of the program.
138 : *
139 : * \sa parse_program_name()
140 : */
141 171 : std::string getopt::get_program_name() const
142 : {
143 171 : return f_program_name;
144 : }
145 :
146 :
147 : /** \brief Retrieve the project name if one is defined.
148 : *
149 : * This function returns the name of the project as defined in the
150 : * options_environment structure passed to the constructor.
151 : *
152 : * For example, the snapwebsites project makes use of "snapwebsites"
153 : * name as its common project name. Many of the configuration files are
154 : * found under that sub-folder. This ensures that the configuration files
155 : * are searched for under the indicated folders and again under:
156 : *
157 : * \code
158 : * <existing path>/<project name>.d/<basename>
159 : * \endcode
160 : *
161 : * So if you have a configuration file named "snapserver.conf" with
162 : * a path such as "/etc/snapwebsites", you end up with:
163 : *
164 : * \code
165 : * "/etc/snapwebsites/snapserver.conf"
166 : * "/etc/snapwebsites/snapwebsites.d/snapserver.conf"
167 : * \endcode
168 : *
169 : * Notice that the loader adds a ".d" at the end of the project name.
170 : * Also, if the user were to specify a different filename with the
171 : * --config command line option, it could end up like this:
172 : *
173 : * \code
174 : * ... --config /home/alexis/.config/iplock/iplock.conf ...
175 : *
176 : * # First we read this file:
177 : * "/home/alexis/.config/iplock/iplock.conf"
178 : *
179 : * # Second we read this file (assuming the same project name
180 : * # of "snapwebsites"):
181 : * "/home/alexis/.config/iplock/snapwebsites.d/iplock.conf"
182 : * \endcode
183 : *
184 : * The order is important as well. We first load the direct path, then
185 : * the path with the sub-folder. Finally, we move forward to the next
186 : * configuration file. We ignore errors when a file can't be loaded or
187 : * is missing.
188 : *
189 : * \return The name of the project, maybe empty if undefined.
190 : */
191 2 : std::string getopt::get_project_name() const
192 : {
193 2 : if(f_options_environment.f_project_name == nullptr)
194 : {
195 1 : return std::string();
196 : }
197 1 : return f_options_environment.f_project_name;
198 : }
199 :
200 :
201 :
202 :
203 : /** \brief Retrieve the group name if one is defined.
204 : *
205 : * This function returns the name of the group as defined in the
206 : * options_environment structure passed to the constructor. This is
207 : * the main group name (TODO: fix the name).
208 : *
209 : * The group name is used for the sub-folder because at times many projects
210 : * are going to use the same sub-folder.
211 : *
212 : * \return The name of the group, maybe empty if undefined.
213 : */
214 2 : std::string getopt::get_group_name() const
215 : {
216 2 : if(f_options_environment.f_group_name == nullptr)
217 : {
218 1 : return std::string();
219 : }
220 1 : return f_options_environment.f_group_name;
221 : }
222 :
223 :
224 :
225 :
226 : } // namespace advgetopt
227 : // vim: ts=4 sw=4 et
|