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 gchar ** 158 pcmk__cmdline_preproc(char *const *argv, const char *special); 159 160 /*! 161 * \internal 162 * \brief Process extra arguments as if they were provided by the user on the 163 * command line. 164 * 165 * \param[in,out] context The command line option processing context. 166 * \param[out] error A place for errors to be collected. 167 * \param[in] format The command line to be processed, potentially with 168 * format specifiers. 169 * \param[in] ... Arguments to be formatted. 170 * 171 * \note The first item in the list of arguments must be the name of the 172 * program, exactly as if the format string were coming from the 173 * command line. Otherwise, the first argument will be ignored. 174 * 175 * \return TRUE if processing succeeded, or FALSE otherwise. If FALSE, error 176 * should be checked and displayed to the user. 177 */ 178 G_GNUC_PRINTF(3, 4) 179 gboolean 180 pcmk__force_args(GOptionContext *context, GError **error, const char *format, ...); 181 182 #ifdef __cplusplus 183 } 184 #endif 185 186 #endif