1 /*
2  * Copyright 2019-2021 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, 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                          GOptionEntry entries[]);
104 
105 /*!
106  * \internal
107  * \brief Pre-process command line arguments to preserve compatibility with
108  *        getopt behavior.
109  *
110  * getopt and glib have slightly different behavior when it comes to processing
111  * single command line arguments.  getopt allows this:  -x<val>, while glib will
112  * try to handle <val> like it is additional single letter arguments.  glib
113  * prefers -x <val> instead.
114  *
115  * This function scans argv, looking for any single letter command line options
116  * (indicated by the 'special' parameter).  When one is found, everything after
117  * that argument to the next whitespace is converted into its own value.  Single
118  * letter command line options can come in a group after a single dash, but
119  * this function will expand each group into many arguments.
120  *
121  * Long options and anything after "--" is preserved.  The result of this function
122  * can then be passed to ::g_option_context_parse_strv for actual processing.
123  *
124  * In pseudocode, this:
125  *
126  * pcmk__cmdline_preproc(4, ["-XbA", "--blah=foo", "-aF", "-Fval", "--", "--extra", "-args"], "aF")
127  *
128  * Would be turned into this:
129  *
130  * ["-X", "-b", "-A", "--blah=foo", "-a", "F", "-F", "val", "--", "--extra", "-args"]
131  *
132  * This function does not modify argv, and the return value is built of copies
133  * of all the command line arguments.  It is up to the caller to free this memory
134  * after use.
135  *
136  * \note This function calls g_set_prgname assuming it wasn't previously set and
137  *       assuming argv is not NULL.  It is not safe to call g_set_prgname more
138  *       than once so clients should not do so after calling this function.
139  *
140  * \param[in] argv    The command line arguments.
141  * \param[in] special Single-letter command line arguments that take a value.
142  *                    These letters will all have pre-processing applied.
143  */
144 gchar **
145 pcmk__cmdline_preproc(char **argv, const char *special);
146 
147 /*!
148  * \internal
149  * \brief Process extra arguments as if they were provided by the user on the
150  *        command line.
151  *
152  * \param[in,out] context The command line option processing context.
153  * \param[out]    error   A place for errors to be collected.
154  * \param[in]     format  The command line to be processed, potentially with
155  *                        format specifiers.
156  * \param[in]     ...     Arguments to be formatted.
157  *
158  * \note The first item in the list of arguments must be the name of the
159  *       program, exactly as if the format string were coming from the
160  *       command line.  Otherwise, the first argument will be ignored.
161  *
162  * \return TRUE if processing succeeded, or FALSE otherwise.  If FALSE, error
163  *         should be checked and displayed to the user.
164  */
165 G_GNUC_PRINTF(3, 4)
166 gboolean
167 pcmk__force_args(GOptionContext *context, GError **error, const char *format, ...);
168 
169 #ifdef __cplusplus
170 }
171 #endif
172 
173 #endif
174