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