1 /* 2 * Defines for a generic argv and argc processor... 3 * 4 * Copyright 2020 by Gray Watson 5 * 6 * This file is part of the argv library. 7 * 8 * Permission to use, copy, modify, and distribute this software for 9 * any purpose and without fee is hereby granted, provided that the 10 * above copyright notice and this permission notice appear in all 11 * copies, and that the name of Gray Watson not be used in advertising 12 * or publicity pertaining to distribution of the document or software 13 * without specific, written prior permission. 14 * 15 * Gray Watson makes no representations about the suitability of the 16 * software described herein for any purpose. It is provided "as is" 17 * without express or implied warranty. 18 * 19 * The author may be contacted via http://dmalloc.com/ 20 */ 21 22 #ifndef __ARGV_H__ 23 #define __ARGV_H__ 24 25 /* 26 * Version string for the library 27 * 28 * NOTE to gray: whenever this is changed, corresponding Changlog and 29 * NEWS entries *must* be entered and 2 entries in argv.texi must be 30 * updated. 31 * 32 * ARGV LIBRARY VERSION -- 2.5.0 33 */ 34 35 /* produced by configure, inserted into argv.h */ 36 /* used to handle the const operator */ 37 /* const is available */ 38 39 /* NOTE: start of dmalloc_argv.h */ 40 41 /* 42 * Generic and standardized argument processor. You describe the arguments 43 * that you are looking for along with their types and these routines do the 44 * work to convert them into values. 45 * 46 * These routines also provide standardized error and usage messages as well 47 * as good usage documentation and long and short options. 48 */ 49 50 #include <stdio.h> /* have to for FILE * below */ 51 52 /* this defines what type the standard void memory-pointer is */ 53 #if (defined(__STDC__) && __STDC__ == 1) || defined(__cplusplus) 54 #define ARGV_PNT void * 55 #else 56 #define ARGV_PNT char * 57 #endif 58 59 /* 60 * argument information structure. this specifies the allowable options 61 * and some information about each one. 62 * 63 * { 'O', "optimize", ARGV_BOOL, &optimize, NULL, "turn on optimization" } 64 * { 'c', "config", ARGV_CHAR_P, &config, "file", "configuration file" } 65 */ 66 typedef struct { 67 char ar_short_arg; /* short argument, 'd' if '-d' */ 68 char *ar_long_arg; /* long version of arg, '--delete' */ 69 unsigned int ar_type; /* type of option, see values below */ 70 ARGV_PNT ar_variable; /* address of associated variable */ 71 char *ar_var_label; /* label for variable description */ 72 char *ar_comment; /* comment for usage message */ 73 } argv_t; 74 75 /* 76 * Argument array type. when ARGV_FLAG_ARRAY is |'d with the ar_type 77 * in the above structure then multiple instances of the option are 78 * allowed and each instance is stored into the following structure 79 * that MUST be in ar_variable in the above arg_t structure. 80 * 81 * NOTE: after the arguments have been processed, if aa_entryn is > 0 82 * then aa_entries needs to be free'd by user. argv_cleanup() can be 83 * used for this 84 */ 85 typedef struct { 86 int aa_entry_n; /* number of elements in aa_entrees */ 87 ARGV_PNT aa_entries; /* entry list specified */ 88 } argv_array_t; 89 90 /* extract the count of the elements from an argv ARRAY */ 91 #define ARGV_ARRAY_COUNT(array) ((array).aa_entry_n) 92 93 /* extract WHICH entry of TYPE from an argv ARRAY */ 94 #define ARGV_ARRAY_ENTRY(array, type, which) \ 95 (((type *)(array).aa_entries)[which]) 96 97 /* extract a pointer to WHICH entry of TYPE from an argv ARRAY */ 98 #define ARGV_ARRAY_ENTRY_P(array, type, which) \ 99 (((type *)(array).aa_entries) + which) 100 101 /* special ar_short_arg value to mark the last entry in the argument array */ 102 #define ARGV_LAST ((char)255) 103 104 /* 105 * special ar_short_arg value to mark mandatory arguments (i.e. arguments that 106 * *must* be specified. for arguments that are not optional like [-b]. 107 * to have a variable number of mandatory args then make the last MAND 108 * entry be a ARG_ARRAY type. 109 */ 110 #define ARGV_MAND ((char)254) 111 112 /* 113 * special ar_short_arg value to mark that there is the possibility of 114 * a mandatory argument here if one is specified. 115 */ 116 #define ARGV_MAYBE ((char)253) 117 118 /* 119 * special ar_short_arg value to say that the previous and next arguments in 120 * the list should not be used together. 121 * {'a'...}, {ARG_OR}, {'b'...}, {ARG_OR}, {'c'...} means 122 * the user should only specific -a or -b or -c but not 2 or more. 123 */ 124 #define ARGV_OR ((char)252) 125 126 /* 127 * special ar_short_arg value that is the same as ARGV_OR but one of the args 128 * must be used. 129 * {'a'...}, {ARG_ONE_OF}, {'b'...}, {ARG_ONE_OF}, {'c'...} means 130 * the user must specify one of -a or -b or -c but not 2 or more. 131 * ARGV_XOR is there for compatibility with older versions. 132 */ 133 #define ARGV_ONE_OF ((char)251) 134 #define ARGV_XOR ((char)251) 135 136 /* 137 * ar_type values of arg_t 138 * NOTE: if this list is changed, some defines in argv_loc need to be changed 139 */ 140 #define ARGV_BOOL 1 /* boolean type, sets to ARGV_TRUE */ 141 #define ARGV_BOOL_NEG 2 /* like bool but sets to ARGV_FALSE */ 142 #define ARGV_BOOL_ARG 3 /* like bool but takes a yes/no arg */ 143 #define ARGV_CHAR 4 /* single character */ 144 #define ARGV_CHAR_P 5 /* same as STRING */ 145 #define ARGV_SHORT 6 /* short integer number */ 146 #define ARGV_U_SHORT 7 /* unsigned short integer number */ 147 #define ARGV_INT 8 /* integer number */ 148 #define ARGV_U_INT 9 /* unsigned integer number */ 149 #define ARGV_LONG 10 /* long integer number */ 150 #define ARGV_U_LONG 11 /* unsinged long integer number */ 151 #define ARGV_FLOAT 12 /* floating pointer number */ 152 #define ARGV_DOUBLE 13 /* double floating pointer number */ 153 #define ARGV_BIN 14 /* binary number (0s and 1s) */ 154 #define ARGV_OCT 15 /* octal number, (base 8) */ 155 #define ARGV_HEX 16 /* hexadecimal number, (base 16) */ 156 #define ARGV_INCR 17 /* int arg which gets ++ each time */ 157 #define ARGV_SIZE 18 /* long arg which knows mMbBkKgG */ 158 #define ARGV_U_SIZE 19 /* u_long arg which knows mMbBkKgG */ 159 #define ARGV_BOOL_INT 20 /* like bool but takes an integer var*/ 160 #define ARGV_BOOL_INT_NEG 21 /* like bool-neg but with an integer */ 161 #define ARGV_BOOL_INT_ARG 22 /* like bool-arg but with an integer */ 162 163 #define ARGV_TYPE(t) ((t) & 0x3F) /* strip off all but the var type */ 164 #define ARGV_FLAG_ARRAY (1 << 14) /* OR with type to indicate array */ 165 #define ARGV_FLAG_MAND (1 << 13) /* OR with type to mark mandatory */ 166 /* NOTE: other internal flags defined in argv_loc.h */ 167 168 /* argv_usage which argument values */ 169 #define ARGV_USAGE_NONE 0 /* no usage messages -- special */ 170 #define ARGV_USAGE_SHORT 1 /* print short usage messages */ 171 #define ARGV_USAGE_LONG 2 /* print long-format usage messages */ 172 #define ARGV_USAGE_DEFAULT 3 /* default usage messages */ 173 #define ARGV_USAGE_SEE 4 /* say see --usage for more info */ 174 #define ARGV_USAGE_SHORT_REM 5 /* short + reminder how to get long */ 175 #define ARGV_USAGE_ALL 6 /* all usage information */ 176 177 /* boolean type settings */ 178 #define ARGV_FALSE 0 179 #define ARGV_TRUE 1 180 181 /*<<<<<<<<<< The below prototypes are auto-generated by fillproto */ 182 183 /* This is a processed version of argv[0], pre-path removed: /bin/ls -> ls */ 184 extern 185 char argv_program[/* PROGRAM_NAME + 1 */]; 186 187 /* A global value of argv from main after argv_process has been called */ 188 extern 189 char **argv_argv; 190 191 /* A global value of argc from main after argv_process has been called */ 192 extern 193 int argv_argc; 194 195 /* This should be set externally to provide general program help to user */ 196 extern 197 char *argv_help_string; 198 199 /* This should be set externally to provide version information to the user */ 200 extern 201 char *argv_version_string; 202 203 /* 204 * Are we running interactively? This will exit on errors. Set to 205 * false to return error codes instead. 206 */ 207 extern 208 int argv_interactive; 209 210 /* 211 * The FILE stream that argv out_puts all its errors. Set to NULL to 212 * not dump any error messages. Default is stderr. 213 */ 214 extern 215 FILE *argv_error_stream; 216 217 /* 218 * This is the error code to exit with when we have a usage error and 219 * we are in interactive mode. 220 */ 221 extern 222 int argv_error_code; 223 224 /* 225 * Set to 1 (the default) to enable the handling of -l=foo or 226 * --logfile=foo type of arguments. Set to 0 to disable. This allows 227 * you to specifically assign a value to an argument. 228 */ 229 extern 230 int argv_close_enable_b; 231 232 /* 233 * If the library sees a "--" argument, it will turn off further 234 * argument process. Set to 1 to enable the ability of specifying 235 * additional "--" arguments to reenable (basically toggle on then 236 * off) argument processing. Set to 0 (the default) to disable this 237 * behavior. 238 */ 239 extern 240 int argv_last_toggle_b; 241 242 /* 243 * Set to 1 (the default) to have the library accept multiple usage of 244 * the same argument. Set to 0 to have the library generate an error 245 * if you use an argument twice. 246 */ 247 extern 248 int argv_multi_accept_b; 249 250 /* 251 * Set to one of the ARGV_USAGE_ defines in the argv.h file. This 252 * tell the library what usage information to display when --usage is 253 * specified by the user. Default is ARGV_USAGE_LONG. 254 */ 255 extern 256 int argv_usage_type; 257 258 /* 259 * Set to one of the ARGV_USAGE_ defines in the argv.h file. This 260 * tell the library what usage information to display when an error is 261 * encountered. The usage information accompanies the error message. 262 * Default is ARGV_USAGE_SEE. 263 */ 264 extern 265 int argv_error_type; 266 267 /* 268 * Set to 1 (the default) if you want the library look for associated 269 * arguments from the associated program's environmental variable. If 270 * set the 0 then no environmental variable will be used. If you are 271 * running program foo then the library will look for the 272 * environmental variable ARGV_foo and will add those to the argument 273 * list specified on the command line. By default they will be 274 * inserted in front of those on the command line unless the 275 * argv_env_after_b is set to 1. 276 * 277 * NOTE: this is set by argv_process automatically. If you do not 278 * want this behavior, you should use argv_process_no_env. 279 */ 280 extern 281 int argv_process_env_b; 282 283 /* 284 * Set to 1 if you want the library to append the arguments from the 285 * program's environmental variable after those specified on the 286 * command line. If set the 0 (the default) then they will be 287 * inserted before those specified on the command line. See 288 * argv_process_env_b for more information. 289 */ 290 extern 291 int argv_env_after_b; 292 293 /* 294 * int argv_process_no_env 295 * 296 * Process the user arguments with an argv_t structure array. Like 297 * argv_process_args but without the processing of the argv 298 * environmental variables. 299 * 300 * Returns 0 on success and -1 on failure. 301 * 302 * ARGUMENTS: 303 * 304 * args - Array of argv_t structures. 305 * 306 * arg_n - Number of arguments in the argv array. 307 * 308 * argv - Array of character pointers terminated by 0L. 309 */ 310 extern 311 int argv_process_no_env(argv_t *args, const int arg_n, char **argv); 312 313 /* 314 * int argv_process 315 * 316 * Processes a number of arguments depending on the argument array. 317 * This routine will not modify the argv array in any way. 318 * 319 * NOTE: it will modify the args array by setting various flags in the 320 * type field. returns 0 if no error else -1. 321 * 322 * ARGUMENTS: 323 * 324 * args - Array of argv_t structures that we are using to process the 325 * user argument array. If null then an empty array is used. 326 * 327 * argc - Number of arguments in the argv argument array. 328 * 329 * argv - Array of character pointer arguments terminated by a 0L. 330 */ 331 extern 332 int argv_process(argv_t *args, const int argc, char **argv); 333 334 /* 335 * int argv_usage 336 * 337 * Print the standard usage messages for our argument array. You can 338 * specify whether you want to see a short or long usage messages. 339 * 340 * NOTE: if this is called before argv_process then the program name 341 * may be invalid. 342 * 343 * Returns 0 on success and -1 on failure. 344 * 345 * ARGUMENTS: 346 * 347 * args - Our argument array to print the usage messages about. If 348 * null then an empty array is used. 349 * 350 * which - Either ARGV_USAGE_SHORT (for short usage messages), 351 * ARGV_USAGE_LONG (for long usage messages), or ARGV_USAGE_DEFAULT 352 * (the user's default either long or short). 353 */ 354 extern 355 int argv_usage(const argv_t *args, const int which); 356 357 /* 358 * int argv_was_used 359 * 360 * See if an argument was used in a previous call to argv_process. 361 * 362 * Returns 1 if yes it was used, else 0 if not. 363 * 364 * ARGUMENTS: 365 * 366 * args - Argument list to search. 367 * 368 * short_arg - Short argument to see if it was used. 369 */ 370 extern 371 int argv_was_used(const argv_t *args, const char short_arg); 372 373 /* 374 * int argv_long_was_used 375 * 376 * See if a long argument was used in a previous call to argv_process. 377 * 378 * Returns 1 if yes it was used, else 0 if not. 379 * 380 * ARGUMENTS: 381 * 382 * args - Argument list to search. 383 * 384 * long_arg - Long argument to see if it was used. 385 */ 386 extern 387 int argv_long_was_used(const argv_t *args, const char *long_arg); 388 389 /* 390 * int argv_entry_was_used 391 * 392 * See if an entry in the argument array was used in a previous call 393 * to argv_process. 394 * 395 * Returns 1 if yes it was used, else 0 if not. 396 * 397 * ARGUMENTS: 398 * 399 * argv_entry_p - Pointer to an entry in a argv_t list. 400 */ 401 extern 402 int argv_entry_was_used(const argv_t *argv_entry_p); 403 404 /* 405 * void argv_cleanup 406 * 407 * Frees up any allocations associated with the argument array during 408 * argv_process. This should be done at the end of the program or 409 * after all the arguments have been referenced. 410 * 411 * ARGUMENTS: 412 * 413 * args - Argument array we are cleaning up. 414 */ 415 extern 416 void argv_cleanup(const argv_t *args); 417 418 /* 419 * int argv_copy_args 420 * 421 * Copy all the arguements (not including the 0th) one after the other 422 * into the user specified buffer. 423 * 424 * NOTE: you can get the 0th argument from argv_argv[0] or 425 * argv_program. 426 * 427 * Returns 0 on success and -1 on failure. 428 * 429 * ARGUMENTS: 430 * 431 * buf - Buffer to copy all of the user arguments into. 432 * 433 * buf_size - Size of the buffer. 434 */ 435 extern 436 int argv_copy_args(char *buf, const int buf_size); 437 438 /* 439 * int argv_value_string 440 * 441 * Convert the value of a RC entry to its string equivalent in the 442 * buffer provided. 443 * 444 * Returns the length of bytes copied into the buffer. 445 * 446 * ARGUMENTS: 447 * 448 * argv_entry_p - Pointer to an entry in a argv_t list. 449 * 450 * buf - Buffer to convert the value into. 451 * 452 * buf_size - Size of the buffer. 453 */ 454 extern 455 int argv_value_string(const argv_t *argv_entry_p, char *buf, 456 const int buf_size); 457 458 /* 459 * int argv_type_info 460 * 461 * Get internal information about the type of the argument. 462 * 463 * Returns the name of the type. 464 * 465 * ARGUMENTS: 466 * 467 * type - Number of argument type. 468 * 469 * size_p - Pointer to an unsigned integer which, if not NULL, will be 470 * set with the size of the type. 471 * 472 * desc_p - Pointer to a constant character pointer which, if not 473 * NULL, will be pointed to a description of the type. 474 */ 475 extern 476 const char *argv_type_info(const unsigned int type, unsigned int *size_p, 477 const char **desc_p); 478 479 /*<<<<<<<<<< This is end of the auto-generated output from fillproto. */ 480 481 #endif /* ! __ARGV_H__ */ 482