1.\" Copyright (c) 1999 - 2002 Kungliga Tekniska Högskolan 2.\" (Royal Institute of Technology, Stockholm, Sweden). 3.\" All rights reserved. 4.\" 5.\" Redistribution and use in source and binary forms, with or without 6.\" modification, are permitted provided that the following conditions 7.\" are met: 8.\" 9.\" 1. Redistributions of source code must retain the above copyright 10.\" notice, this list of conditions and the following disclaimer. 11.\" 12.\" 2. Redistributions in binary form must reproduce the above copyright 13.\" notice, this list of conditions and the following disclaimer in the 14.\" documentation and/or other materials provided with the distribution. 15.\" 16.\" 3. Neither the name of the Institute nor the names of its contributors 17.\" may be used to endorse or promote products derived from this software 18.\" without specific prior written permission. 19.\" 20.\" THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 21.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23.\" ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 24.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30.\" SUCH DAMAGE. 31.\" 32.\" $Id$ 33.Dd September 24, 1999 34.Dt GETARG 3 35.Os ROKEN 36.Sh NAME 37.Nm getarg , 38.Nm arg_printusage 39.Nd collect command line options 40.Sh SYNOPSIS 41.In getarg.h 42.Ft int 43.Fn getarg "struct getargs *args" "size_t num_args" "int argc" "char **argv" "int *optind" 44.Ft void 45.Fn arg_printusage "struct getargs *args" "size_t num_args" "const char *progname" "const char *extra_string" 46.Sh DESCRIPTION 47.Fn getarg 48collects any command line options given to a program in an easily used way. 49.Fn arg_printusage 50pretty-prints the available options, with a short help text. 51.Pp 52.Fa args 53is the option specification to use, and it's an array of 54.Fa struct getargs 55elements. 56.Fa num_args 57is the size of 58.Fa args 59(in elements). 60.Fa argc 61and 62.Fa argv 63are the argument count and argument vector to extract option from. 64.Fa optind 65is a pointer to an integer where the index to the last processed 66argument is stored, it must be initialised to the first index (minus 67one) to process (normally 0) before the first call. 68.Pp 69.Fa arg_printusage 70take the same 71.Fa args 72and 73.Fa num_args 74as getarg; 75.Fa progname 76is the name of the program (to be used in the help text), and 77.Fa extra_string 78is a string to print after the actual options to indicate more 79arguments. The usefulness of this function is realised only be people 80who has used programs that has help strings that doesn't match what 81the code does. 82.Pp 83The 84.Fa getargs 85struct has the following elements. 86.Bd -literal 87struct getargs{ 88 const char *long_name; 89 char short_name; 90 enum { arg_integer, 91 arg_string, 92 arg_flag, 93 arg_negative_flag, 94 arg_strings, 95 arg_double, 96 arg_collect 97 } type; 98 void *value; 99 const char *help; 100 const char *arg_help; 101}; 102.Ed 103.Pp 104.Fa long_name 105is the long name of the option, it can be 106.Dv NULL , 107if you don't want a long name. 108.Fa short_name 109is the character to use as short option, it can be zero. If the option 110has a value the 111.Fa value 112field gets filled in with that value interpreted as specified by the 113.Fa type 114field. 115.Fa help 116is a longer help string for the option as a whole, if it's 117.Dv NULL 118the help text for the option is omitted (but it's still displayed in 119the synopsis). 120.Fa arg_help 121is a description of the argument, if 122.Dv NULL 123a default value will be used, depending on the type of the option: 124.Pp 125.Bl -hang -width arg_negative_flag 126.It arg_integer 127the argument is a signed integer, and 128.Fa value 129should point to an 130.Fa int . 131.It Fa arg_string 132the argument is a string, and 133.Fa value 134should point to a 135.Fa char* . 136.It Fa arg_flag 137the argument is a flag, and 138.Fa value 139should point to a 140.Fa int . 141It gets filled in with either zero or one, depending on how the option 142is given, the normal case being one. Note that if the option isn't 143given, the value isn't altered, so it should be initialised to some 144useful default. 145.It Fa arg_negative_flag 146this is the same as 147.Fa arg_flag 148but it reverses the meaning of the flag (a given short option clears 149the flag), and the synopsis of a long option is negated. 150.It Fa arg_strings 151the argument can be given multiple times, and the values are collected 152in an array; 153.Fa value 154should be a pointer to a 155.Fa struct getarg_strings 156structure, which holds a length and a string pointer. 157.It Fa arg_double 158argument is a double precision floating point value, and 159.Fa value 160should point to a 161.Fa double . 162.It Fa arg_collect 163allows more fine-grained control of the option parsing process. 164.Fa value 165should be a pointer to a 166.Fa getarg_collect_info 167structure: 168.Bd -literal 169typedef int (*getarg_collect_func)(int short_opt, 170 int argc, 171 char **argv, 172 int *optind, 173 int *optarg, 174 void *data); 175 176typedef struct getarg_collect_info { 177 getarg_collect_func func; 178 void *data; 179} getarg_collect_info; 180.Ed 181.Pp 182With the 183.Fa func 184member set to a function to call, and 185.Fa data 186to some application specific data. The parameters to the collect function are: 187.Bl -inset 188.It Fa short_flag 189non-zero if this call is via a short option flag, zero otherwise 190.It Fa argc , argv 191the whole argument list 192.It Fa optind 193pointer to the index in argv where the flag is 194.It Fa optarg 195pointer to the index in argv[*optind] where the flag name starts 196.It Fa data 197application specific data 198.El 199.Pp 200You can modify 201.Fa *optind , 202and 203.Fa *optarg , 204but to do this correct you (more or less) have to know about the inner 205workings of getarg. 206.Pp 207You can skip parts of arguments by increasing 208.Fa *optarg 209(you could 210implement the 211.Fl z Ns Ar 3 212set of flags from 213.Nm gzip 214with this), or whole argument strings by increasing 215.Fa *optind 216(let's say you want a flag 217.Fl c Ar x y z 218to specify a coordinate); if you also have to set 219.Fa *optarg 220to a sane value. 221.Pp 222The collect function should return one of 223.Dv ARG_ERR_NO_MATCH , ARG_ERR_BAD_ARG , ARG_ERR_NO_ARG, ENOMEM 224on error, zero otherwise. 225.Pp 226For your convenience there is a function, 227.Fn getarg_optarg , 228that returns the traditional argument string, and you pass it all 229arguments, sans data, that where given to the collection function. 230.Pp 231Don't use this more this unless you absolutely have to. 232.El 233.Pp 234Option parsing is similar to what 235.Xr getopt 236uses. Short options without arguments can be compressed 237.Pf ( Fl xyz 238is the same as 239.Fl x y z ) , 240and short 241options with arguments take these as either the rest of the 242argv-string or as the next option 243.Pf ( Fl o Ns Ar foo , 244or 245.Fl o Ar foo ) . 246.Pp 247Long option names are prefixed with -- (double dash), and the value 248with a = (equal), 249.Fl Fl foo= Ns Ar bar . 250Long option flags can either be specified as they are 251.Pf ( Fl Fl help ) , 252or with an (boolean parsable) option 253.Pf ( Fl Fl help= Ns Ar yes , 254.Fl Fl help= Ns Ar true , 255or similar), or they can also be negated 256.Pf ( Fl Fl no-help 257is the same as 258.Fl Fl help= Ns no ) , 259and if you're really confused you can do it multiple times 260.Pf ( Fl Fl no-no-help= Ns Ar false , 261or even 262.Fl Fl no-no-help= Ns Ar maybe ) . 263.Sh EXAMPLE 264.Bd -literal 265#include <stdio.h> 266#include <string.h> 267#include <getarg.h> 268 269char *source = "Ouagadougou"; 270char *destination; 271int weight; 272int include_catalog = 1; 273int help_flag; 274 275struct getargs args[] = { 276 { "source", 's', arg_string, &source, 277 "source of shippment", "city" }, 278 { "destination", 'd', arg_string, &destination, 279 "destination of shippment", "city" }, 280 { "weight", 'w', arg_integer, &weight, 281 "weight of shippment", "tons" }, 282 { "catalog", 'c', arg_negative_flag, &include_catalog, 283 "include product catalog" }, 284 { "help", 'h', arg_flag, &help_flag } 285}; 286 287int num_args = sizeof(args) / sizeof(args[0]); /* number of elements in args */ 288 289const char *progname = "ship++"; 290 291int 292main(int argc, char **argv) 293{ 294 int optind = 0; 295 if (getarg(args, num_args, argc, argv, &optind)) { 296 arg_printusage(args, num_args, progname, "stuff..."); 297 exit (1); 298 } 299 if (help_flag) { 300 arg_printusage(args, num_args, progname, "stuff..."); 301 exit (0); 302 } 303 if (destination == NULL) { 304 fprintf(stderr, "%s: must specify destination\en", progname); 305 exit(1); 306 } 307 if (strcmp(source, destination) == 0) { 308 fprintf(stderr, "%s: destination must be different from source\en"); 309 exit(1); 310 } 311 /* include more stuff here ... */ 312 exit(2); 313} 314.Ed 315.Pp 316The output help output from this program looks like this: 317.Bd -literal 318$ ship++ --help 319Usage: ship++ [--source=city] [-s city] [--destination=city] [-d city] 320 [--weight=tons] [-w tons] [--no-catalog] [-c] [--help] [-h] stuff... 321-s city, --source=city source of shippment 322-d city, --destination=city destination of shippment 323-w tons, --weight=tons weight of shippment 324-c, --no-catalog include product catalog 325.Ed 326.Sh BUGS 327It should be more flexible, so it would be possible to use other more 328complicated option syntaxes, such as what 329.Xr ps 1 , 330and 331.Xr tar 1 , 332uses, or the AFS model where you can skip the flag names as long as 333the options come in the correct order. 334.Pp 335Options with multiple arguments should be handled better. 336.Pp 337Should be integrated with SL. 338.Pp 339It's very confusing that the struct you pass in is called getargS. 340.Sh SEE ALSO 341.Xr getopt 3 342