1 /*
2 * Copyright 2019-2022 the Pacemaker project contributors
3 *
4 * The version control history for this file may have further details.
5 *
6 * This source code is licensed under the GNU Lesser General Public License
7 * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
8 */
9
10 #ifndef PCMK__CMDLINE_INTERNAL__H
11 #define PCMK__CMDLINE_INTERNAL__H
12
13 #ifdef __cplusplus
14 extern "C" {
15 #endif
16
17 #include <glib.h>
18
19 typedef struct {
20 char *summary;
21 char *output_as_descr;
22
23 gboolean version;
24 gboolean quiet;
25 unsigned int verbosity;
26
27 char *output_ty;
28 char *output_dest;
29 } pcmk__common_args_t;
30
31 /*!
32 * \internal
33 * \brief Allocate a new common args object
34 *
35 * \param[in] summary Summary description of tool for man page
36 *
37 * \return Newly allocated common args object
38 * \note This function will immediately exit the program if memory allocation
39 * fails, since the intent is to call it at the very beginning of a
40 * program, before logging has been set up.
41 */
42 pcmk__common_args_t *
43 pcmk__new_common_args(const char *summary);
44
45 /*!
46 * \internal
47 * \brief Create and return a GOptionContext containing the command line options
48 * supported by all tools.
49 *
50 * \note Formatted output options will be added unless fmts is NULL. This allows
51 * for using this function in tools that have not yet been converted to
52 * formatted output. It should not be NULL in any tool that calls
53 * pcmk__register_formats() as that function adds its own command line
54 * options.
55 *
56 * \param[in,out] common_args A ::pcmk__common_args_t structure where the
57 * results of handling command options will be written.
58 * \param[in] fmts The help string for which formats are supported.
59 * \param[in,out] output_group A ::GOptionGroup that formatted output related
60 * command line arguments should be added to.
61 * \param[in] param_string A string describing any remaining command line
62 * arguments.
63 */
64 GOptionContext *
65 pcmk__build_arg_context(pcmk__common_args_t *common_args, const char *fmts,
66 GOptionGroup **output_group, const char *param_string);
67
68 /*!
69 * \internal
70 * \brief Clean up after pcmk__build_arg_context(). This should be called
71 * instead of ::g_option_context_free at program termination.
72 *
73 * \param[in,out] context Argument context to free
74 */
75 void
76 pcmk__free_arg_context(GOptionContext *context);
77
78 /*!
79 * \internal
80 * \brief Add options to the main application options
81 *
82 * \param[in,out] context Argument context to add options to
83 * \param[in] entries Option entries to add
84 *
85 * \note This is simply a convenience wrapper to reduce duplication
86 */
87 void pcmk__add_main_args(GOptionContext *context, const GOptionEntry entries[]);
88
89 /*!
90 * \internal
91 * \brief Add an option group to an argument context
92 *
93 * \param[in,out] context Argument context to add group to
94 * \param[in] name Option group name (to be used in --help-NAME)
95 * \param[in] header Header for --help-NAME output
96 * \param[in] desc Short description for --help-NAME option
97 * \param[in] entries Array of options in group
98 *
99 * \note This is simply a convenience wrapper to reduce duplication
100 */
101 void pcmk__add_arg_group(GOptionContext *context, const char *name,
102 const char *header, const char *desc,
103 const GOptionEntry entries[]);
104
105 /*!
106 * \internal
107 * \brief Prepare the command line for being added to a pcmk__output_t as the
108 * request
109 *
110 * This performs various transformations on the command line arguments, such
111 * as surrounding arguments containing spaces with quotes and escaping any
112 * single quotes in the string.
113 *
114 * \param[in,out] argv Command line (typically from pcmk__cmdline_preproc())
115 */
116 gchar *pcmk__quote_cmdline(gchar **argv);
117
118 /*!
119 * \internal
120 * \brief Pre-process command line arguments to preserve compatibility with
121 * getopt behavior.
122 *
123 * getopt and glib have slightly different behavior when it comes to processing
124 * single command line arguments. getopt allows this: -x<val>, while glib will
125 * try to handle <val> like it is additional single letter arguments. glib
126 * prefers -x <val> instead.
127 *
128 * This function scans argv, looking for any single letter command line options
129 * (indicated by the 'special' parameter). When one is found, everything after
130 * that argument to the next whitespace is converted into its own value. Single
131 * letter command line options can come in a group after a single dash, but
132 * this function will expand each group into many arguments.
133 *
134 * Long options and anything after "--" is preserved. The result of this function
135 * can then be passed to ::g_option_context_parse_strv for actual processing.
136 *
137 * In pseudocode, this:
138 *
139 * pcmk__cmdline_preproc(4, ["-XbA", "--blah=foo", "-aF", "-Fval", "--", "--extra", "-args"], "aF")
140 *
141 * Would be turned into this:
142 *
143 * ["-X", "-b", "-A", "--blah=foo", "-a", "F", "-F", "val", "--", "--extra", "-args"]
144 *
145 * This function does not modify argv, and the return value is built of copies
146 * of all the command line arguments. It is up to the caller to free this memory
147 * after use.
148 *
149 * \note This function calls g_set_prgname assuming it wasn't previously set and
150 * assuming argv is not NULL. It is not safe to call g_set_prgname more
151 * than once so clients should not do so after calling this function.
152 *
153 * \param[in] argv The command line arguments.
154 * \param[in] special Single-letter command line arguments that take a value.
155 * These letters will all have pre-processing applied.
156 *
157 * \note @COMPAT We should drop this at a new major or minor release series
158 * after we no longer support building with Booth <1.2, which invokes
159 * Pacemaker CLI tools using the getopt syntax.
160 */
161 gchar **
162 pcmk__cmdline_preproc(char *const *argv, const char *special);
163
164 /*!
165 * \internal
166 * \brief Process extra arguments as if they were provided by the user on the
167 * command line.
168 *
169 * \param[in,out] context The command line option processing context.
170 * \param[out] error A place for errors to be collected.
171 * \param[in] format The command line to be processed, potentially with
172 * format specifiers.
173 * \param[in] ... Arguments to be formatted.
174 *
175 * \note The first item in the list of arguments must be the name of the
176 * program, exactly as if the format string were coming from the
177 * command line. Otherwise, the first argument will be ignored.
178 *
179 * \return TRUE if processing succeeded, or FALSE otherwise. If FALSE, error
180 * should be checked and displayed to the user.
181 */
182 G_GNUC_PRINTF(3, 4)
183 gboolean
184 pcmk__force_args(GOptionContext *context, GError **error, const char *format, ...);
185
186 #ifdef __cplusplus
187 }
188 #endif
189
190 #endif