1 /* -*- related-file-name: "../../liblcdf/clp.c" -*- */ 2 #ifndef LCDF_CLP_H 3 #define LCDF_CLP_H 4 #ifdef __cplusplus 5 extern "C" { 6 #endif 7 8 /* clp.h - Public interface to CLP. 9 * This file is part of CLP, the command line parser package. 10 * 11 * Copyright (c) 1997-2017 Eddie Kohler, ekohler@gmail.com 12 * 13 * CLP is free software. It is distributed under the GNU General Public 14 * License, Version 2, or, alternatively and at your discretion, under the 15 * more permissive (BSD-like) Click LICENSE file as described below. 16 * 17 * Permission is hereby granted, free of charge, to any person obtaining a 18 * copy of this software and associated documentation files (the 19 * "Software"), to deal in the Software without restriction, subject to the 20 * conditions listed in the Click LICENSE file, which is available in full at 21 * http://github.com/kohler/click/blob/master/LICENSE. The conditions 22 * include: you must preserve this copyright notice, and you cannot mention 23 * the copyright holders in advertising related to the Software without 24 * their permission. The Software is provided WITHOUT ANY WARRANTY, EXPRESS 25 * OR IMPLIED. This notice is a summary of the Click LICENSE file; the 26 * license in that file is binding. */ 27 28 #include <stdio.h> 29 #include <stdarg.h> 30 31 typedef struct Clp_Option Clp_Option; 32 typedef struct Clp_Parser Clp_Parser; 33 typedef struct Clp_ParserState Clp_ParserState; 34 35 36 /** @brief Option description. 37 * 38 * CLP users declare arrays of Clp_Option structures to specify what options 39 * should be parsed. 40 * @sa Clp_NewParser, Clp_SetOptions */ 41 struct Clp_Option { 42 const char *long_name; /**< Name of long option, or NULL if the option 43 has no long name. */ 44 int short_name; /**< Character defining short option, or 0 if 45 the option has no short name. */ 46 int option_id; /**< User-specified ID defining option, 47 returned by Clp_Next. */ 48 int val_type; /**< ID of option's value type, or 0 if option 49 takes no value. */ 50 int flags; /**< Option parsing flags. */ 51 }; 52 53 /** @name Value types 54 * These values describe the type of an option's argument and are used in 55 * the Clp_Option val_type field. For example, if an option took integers, its 56 * Clp_Option structure would have val_type set to Clp_ValInt. */ 57 /**@{*/ 58 #define Clp_NoVal 0 /**< @brief Option takes no value. */ 59 #define Clp_ValString 1 /**< @brief Option value is an 60 arbitrary string. */ 61 #define Clp_ValStringNotOption 2 /**< @brief Option value is a 62 non-option string. 63 64 See Clp_DisallowOptions. */ 65 #define Clp_ValBool 3 /**< @brief Option value is a 66 boolean. 67 68 Accepts "true", "false", "yes", "no", "1", and "0", or any 69 prefixes thereof. The match is case-insensitive. */ 70 #define Clp_ValInt 4 /**< @brief Option value is a 71 signed int. 72 73 Accepts an optional "+" or "-" sign, followed by one or more 74 digits. The digits may be include a "0x" or "0X" prefix, for 75 a hexadecimal number, or a "0" prefix, for an octal number; 76 otherwise it is decimal. */ 77 #define Clp_ValUnsigned 5 /**< @brief Option value is an 78 unsigned int. 79 80 Accepts an optional "+" sign, followed by one or more 81 digits. The digits may be include a "0x" or "0X" prefix, for 82 a hexadecimal number, or a "0" prefix, for an octal number; 83 otherwise it is decimal. */ 84 #define Clp_ValLong 6 /**< @brief Option value is a 85 signed long. */ 86 #define Clp_ValUnsignedLong 7 /**< @brief Option value is an 87 unsigned long. */ 88 #define Clp_ValDouble 8 /**< @brief Option value is a 89 double. 90 Accepts a real number as defined by strtod(). */ 91 #define Clp_ValFirstUser 10 /**< @brief Value types >= 92 Clp_ValFirstUser are available 93 for user types. */ 94 /**@}*/ 95 96 /** @name Option flags 97 * These flags are used in the Clp_Option flags field. */ 98 /**@{*/ 99 #define Clp_Mandatory (1<<0) /**< @brief Option flag: value 100 is mandatory. 101 102 It is an error if the option has no value. This is the 103 default if an option has arg_type != 0 and the Clp_Optional 104 flag is not provided. */ 105 #define Clp_Optional (1<<1) /**< @brief Option flag: value 106 is optional. */ 107 #define Clp_Negate (1<<2) /**< @brief Option flag: option 108 may be negated. 109 110 --no-[long_name] will be accepted in argument lists. */ 111 #define Clp_OnlyNegated (1<<3) /**< @brief Option flag: option 112 <em>must</em> be negated. 113 114 --no-[long_name] will be accepted in argument lists, but 115 --[long_name] will not. This is the default if long_name 116 begins with "no-". */ 117 #define Clp_PreferredMatch (1<<4) /**< @brief Option flag: prefer this 118 option when matching. 119 120 Prefixes of --[long_name] should map to this option, even if 121 other options begin with --[long_name]. */ 122 /**@}*/ 123 124 /** @name Option character types 125 * These flags are used in to define character types in Clp_SetOptionChar(). */ 126 /**@{*/ 127 /* Clp_NotOption 0 */ 128 #define Clp_Short (1<<0) /**< @brief Option character begins 129 a set of short options. */ 130 #define Clp_Long (1<<1) /**< @brief Option character begins 131 a long option. */ 132 #define Clp_ShortNegated (1<<2) /**< @brief Option character begins 133 a set of negated short options. */ 134 #define Clp_LongNegated (1<<3) /**< @brief Option character begins 135 a negated long option. */ 136 #define Clp_LongImplicit (1<<4) /**< @brief Option character can begin 137 a long option, and is part of that 138 long option. */ 139 /**@}*/ 140 141 #define Clp_NotOption 0 /**< @brief Clp_Next value: argument 142 was not an option. */ 143 #define Clp_Done -1 /**< @brief Clp_Next value: there are 144 no more arguments. */ 145 #define Clp_BadOption -2 /**< @brief Clp_Next value: argument 146 was an erroneous option. */ 147 #define Clp_Error -3 /**< @brief Clp_Next value: internal 148 CLP error. */ 149 150 #define Clp_ValSize 40 /**< @brief Minimum size of the 151 Clp_Parser val.cs field. */ 152 #define Clp_ValIntSize 10 /**< @brief Minimum size of the 153 Clp_Parser val.is field. */ 154 155 156 /** @brief A value parsing function. 157 * @param clp the parser 158 * @param vstr the value to be parsed 159 * @param complain if nonzero, report error messages via Clp_OptionError 160 * @param user_data user data passed to Clp_AddType() 161 * @return 1 if parsing succeeded, 0 otherwise 162 */ 163 typedef int (*Clp_ValParseFunc)(Clp_Parser *clp, const char *vstr, 164 int complain, void *user_data); 165 166 /** @brief A function for reporting option errors. 167 * @param clp the parser 168 * @param message error message 169 */ 170 typedef void (*Clp_ErrorHandler)(Clp_Parser *clp, const char *message); 171 172 173 /** @brief Command line parser. 174 * 175 * A Clp_Parser object defines an instance of CLP, including allowed options, 176 * value types, and current arguments. 177 * @sa Clp_NewParser, Clp_SetOptions, Clp_SetArguments */ 178 struct Clp_Parser { 179 const Clp_Option *option; /**< The last option. */ 180 181 int negated; /**< Whether the last option was negated. */ 182 183 int have_val; /**< Whether the last option had a value. */ 184 const char *vstr; /**< The string value provided with the last 185 option. */ 186 187 union { 188 int i; 189 unsigned u; 190 long l; 191 unsigned long ul; 192 double d; 193 const char *s; 194 void *pv; 195 #ifdef HAVE_INT64_TYPES 196 int64_t i64; 197 uint64_t u64; 198 #endif 199 char cs[Clp_ValSize]; 200 unsigned char ucs[Clp_ValSize]; 201 int is[Clp_ValIntSize]; 202 unsigned us[Clp_ValIntSize]; 203 } val; /**< The parsed value provided with the last 204 option. */ 205 206 void *user_data; /**< Uninterpreted by CLP; users can set 207 arbitrarily. */ 208 209 struct Clp_Internal *internal; 210 }; 211 212 /** @cond never */ 213 #if __GNUC__ >= 4 214 # define CLP_SENTINEL __attribute__((sentinel)) 215 #else 216 # define CLP_SENTINEL /* nothing */ 217 #endif 218 /** @endcond never */ 219 220 221 /** @brief Create a new Clp_Parser. */ 222 Clp_Parser *Clp_NewParser(int argc, const char * const *argv, 223 int nopt, const Clp_Option *opt); 224 225 /** @brief Destroy a Clp_Parser object. */ 226 void Clp_DeleteParser(Clp_Parser *clp); 227 228 229 /** @brief Return @a clp's program name. */ 230 const char *Clp_ProgramName(Clp_Parser *clp); 231 232 /** @brief Set @a clp's program name. */ 233 const char *Clp_SetProgramName(Clp_Parser *clp, const char *name); 234 235 236 /** @brief Set @a clp's error handler function. */ 237 Clp_ErrorHandler Clp_SetErrorHandler(Clp_Parser *clp, Clp_ErrorHandler errh); 238 239 /** @brief Set @a clp's UTF-8 mode. */ 240 int Clp_SetUTF8(Clp_Parser *clp, int utf8); 241 242 /** @brief Return @a clp's treatment of character @a c. */ 243 int Clp_OptionChar(Clp_Parser *clp, int c); 244 245 /** @brief Set @a clp's treatment of character @a c. */ 246 int Clp_SetOptionChar(Clp_Parser *clp, int c, int type); 247 248 /** @brief Set @a clp's option definitions. */ 249 int Clp_SetOptions(Clp_Parser *clp, int nopt, const Clp_Option *opt); 250 251 /** @brief Set @a clp's arguments. */ 252 void Clp_SetArguments(Clp_Parser *clp, int argc, const char * const *argv); 253 254 /** @brief Set whether @a clp is searching for options. */ 255 int Clp_SetOptionProcessing(Clp_Parser *clp, int on); 256 257 258 #define Clp_DisallowOptions (1<<0) /**< @brief Value type flag: value 259 can't be an option string. 260 261 See Clp_AddType(). */ 262 263 /** @brief Define a new value type for @a clp. */ 264 int Clp_AddType(Clp_Parser *clp, int val_type, int flags, 265 Clp_ValParseFunc parser, void *user_data); 266 267 268 #define Clp_AllowNumbers (1<<0) /**< @brief String list flag: allow 269 explicit numbers. 270 271 See Clp_AddStringListType() and Clp_AddStringListTypeVec(). */ 272 #define Clp_StringListLong (1<<1) /**< @brief String list flag: values 273 have long type. */ 274 275 /** @brief Define a new string list value type for @a clp. */ 276 int Clp_AddStringListTypeVec(Clp_Parser *clp, int val_type, int flags, 277 int nstrs, const char * const *strs, 278 const int *vals); 279 280 /** @brief Define a new string list value type for @a clp. */ 281 int Clp_AddStringListType(Clp_Parser *clp, int val_type, int flags, ...) 282 CLP_SENTINEL; 283 284 285 /** @brief Parse and return the next argument from @a clp. */ 286 int Clp_Next(Clp_Parser *clp); 287 288 /** @brief Return the next argument from @a clp without option parsing. */ 289 const char *Clp_Shift(Clp_Parser *clp, int allow_options); 290 291 292 /** @brief Create a new Clp_ParserState. */ 293 Clp_ParserState *Clp_NewParserState(void); 294 295 /** @brief Destroy a Clp_ParserState object. */ 296 void Clp_DeleteParserState(Clp_ParserState *state); 297 298 /** @brief Save @a clp's current state in @a state. */ 299 void Clp_SaveParser(const Clp_Parser *clp, Clp_ParserState *state); 300 301 /** @brief Restore parser state from @a state into @a clp. */ 302 void Clp_RestoreParser(Clp_Parser *clp, const Clp_ParserState *state); 303 304 305 /** @brief Report a parser error. */ 306 int Clp_OptionError(Clp_Parser *clp, const char *format, ...); 307 308 /** @brief Format a message. */ 309 int Clp_vsnprintf(Clp_Parser* clp, char* str, size_t size, 310 const char* format, va_list val); 311 312 /** @brief Print a message. */ 313 int Clp_fprintf(Clp_Parser* clp, FILE* f, const char* format, ...); 314 315 /** @brief Print a message. */ 316 int Clp_vfprintf(Clp_Parser* clp, FILE* f, const char* format, va_list val); 317 318 /** @brief Extract the current option as a string. */ 319 int Clp_CurOptionNameBuf(Clp_Parser *clp, char *buf, int len); 320 321 /** @brief Extract the current option as a string. */ 322 const char *Clp_CurOptionName(Clp_Parser *clp); 323 324 /** @brief Test if the current option had long name @a name. */ 325 int Clp_IsLong(Clp_Parser *clp, const char *long_name); 326 327 /** @brief Test if the current option had short name @a name. */ 328 int Clp_IsShort(Clp_Parser *clp, int short_name); 329 330 #undef CLP_SENTINEL 331 #ifdef __cplusplus 332 } 333 #endif 334 #endif 335