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