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