diff options
author | ewt <ewt> | 1998-07-27 15:54:20 +0000 |
---|---|---|
committer | ewt <ewt> | 1998-07-27 15:54:20 +0000 |
commit | 5c2ea6b02044d7d25be8e014c4b9fd08e11df6dd (patch) | |
tree | 72a019ddd6f7a5c85fb0db00e89b2a2ed3df5499 /popt.3 | |
parent | 6e8bfe6864823aecc5a6d361c7501af08b1a7047 (diff) | |
download | libpopt-5c2ea6b02044d7d25be8e014c4b9fd08e11df6dd.tar.gz |
*** empty log message ***
Diffstat (limited to 'popt.3')
-rw-r--r-- | popt.3 | 612 |
1 files changed, 612 insertions, 0 deletions
@@ -0,0 +1,612 @@ +.TH POPT 3 "June 30, 1998" "" "Linux Programmer's Manual" +.SH NAME +popt \- Parse command line options +.SH SYNOPSIS +.nf +.B #include <popt.h> +.sp +.BI "poptContext poptGetContext(char * " name ", int " argc , +.BI " char ** "argv , +.BI " struct poptOption * " options , +.BI " int " flags ); +.sp +.BI "void poptFreeContext(poptContext " con ); +.sp +.BI "void poptResetContext(poptContext " con ); +.sp +.BI "int poptGetNextOpt(poptContext " con ); +.sp +.BI "char * poptGetOptArg(poptContext " con ); +.sp +.BI "char * poptGetArg(poptContext " con ); +.sp +.BI "char * poptPeekArg(poptContext " con ); +.sp +.BI "char ** poptGetArgs(poptContext " con ); +.sp +.BI "const char * poptStrerror(const int " error ); +.sp +.BI "char * poptBadOption(poptContext " con ", int " flags ); +.sp +.BI "int poptReadDefaultConfig(poptContext " con ", int " flags ); +.sp +.BI "int poptReadConfigFile(poptContext " con ", char * " fn ); +.sp +.BI "int poptAddAlias(poptContext " con ", struct poptAlias " alias , +.BI " int " flags ); +.sp +.BI "int poptParseArgvString(char * " s ", int * " argcPtr , +.BI " char *** " argvPtr ); +.sp +.BI "int poptStuffArgs(poptContext " con ", char ** " argv ); +.sp +.fi +.SH DESCRIPTION +The popt library exists essentially for parsing command-line +options. It is found superior in many ways when compared to +parsing the argv array by hand or using the getopt functions +.B getopt() +and +.B getopt_long() +[see +.BR getopt "(3)]." +Some specific advantages of popt are: it does not utilize global +.RI "variables, thus enabling multiple passes in parsing " argv +.RI "; it can parse an arbitrary array of " argv "-style elements, " +allowing parsing of command-line-strings from any source; and +finally, it provides a standard method of option aliasing (to be +discussed at length below.) +.sp +Like +.BR getopt_long() , +the popt library supports short and long style options. Recall +that a +.B short option +consists of a - character followed by a single alphanumeric character. +A +.BR "long option" , +common in GNU utilities, consists of two - characters followed by a +string made up of letters, numbers and hyphens. Either type of option +may be followed by an argument. A space separates a short option from +its arguments; either a space or an = separates a long option from an +argument. +.sp +The popt library is highly portable and should work on any POSIX +platform. The latest version is always available from: +ftp://ftp.redhat.com/pub/redhat/code/popt. +.sp +It may be redistributed under either the GNU General Public License +or the GNU Library General Public License, at the distributor's discretion. +.SH "BASIC POPT USAGE" +.SS "1. THE OPTION TABLE" +Applications provide popt with information on their command-line +options by means of an "option table," i.e., an array of +.B struct poptOption +structures: +.sp +#include <popt.h> +.sp +.nf +struct poptOption { + const char * longName; /* may be NULL */ + char shortName; /* may be '\\0' */ + int argInfo; + void * arg; /* depends on argInfo */ + int val; /* 0 means don't return, just update flag */ +}; +.fi +.sp +Each member of the table defines a single option that may be +passed to the program. Long and short options are considered +a single option that may occur in two different forms. The +first two members, +.IR longName " and " shortName ", define the names of the option;" +the first is a long name, while the latter is a single character. +.sp +The +.IR argInfo " member tell popt what type of argument is expected" +after the argument. If no option is expected, +.BR POPT_ARG_NONE " should be used. (Connoisseurs of " getopt() +.RI "will note that " argInfo " is the only field of " +.BR "struct poptOption" " that is not directly analogous to a field in " +.RB "the " getopt_long() " argument table. The similarity between the " +.RB "two allows for easy transitions from " getopt_long " to popt.) " +The rest of the valid values are shown in the following table: +.sp +.nf +.B " Value Description arg Type" +.BR POPT_ARG_NONE " No argument expected int" +.BR POPT_ARG_STRING " No type checking to be performed char *" +.BR POPT_ARG_INT " An integer argument is expected int" +.BR POPT_ARG_LONG " A long integer is expected long" +.sp +.fi +.RI "The next element, " arg ", allows popt to automatically update " +.RI "program variables when the option is used. If " arg " is " +.BR NULL ", it is ignored and popt takes no special action. " +Otherwise it should point to a variable of the type indicated in the +right-most column of the table above. +.sp +.RI "If the option takes no argument (" argInfo " is " +.BR POPT_ARG_NONE "), the variable pointed to by " +.IR arg " is set to 1 when the option is used. (Incidentally, it " +will perhaps not escape the attention of hunt-and-peck typists that +.RB "the value of " POPT_ARG_NONE " is 0.) If the option does take " +an argument, the variable that +.IR arg " points to is updated to reflect the value of the argument." +.RB "Any string is acceptable for " POPT_ARG_STRING " arguments, but " +.BR POPT_ARG_INT " and " POPT_ARG_LONG " are converted to the +appropriate type, and an error returned if the conversion fails. +.sp +.RI "The final option, " val ", is the value popt's parsing function +should return when the option is encountered. If it is 0, the parsing +function does not return a value, instead parsing the next +command-line argument. +.sp +The final structure in the table should have all the pointer values set +.RB "to " NULL " and all the arithmetic values set to 0, marking the " +end of the table. +.SS "2. CREATING A CONTEXT" +popt can interleave the parsing of multiple command-line sets. It allows +this by keeping all the state information for a particular set of +command-line arguments in a +.BR poptContext " data structure, an opaque type that should not be " +modified outside the popt library. +.sp +.RB "New popt contexts are created by " poptGetContext() ":" +.sp +.nf +.BI "poptContext poptGetContext(char * " name ", int "argc ", +.BI " char ** "argv ", +.BI " struct poptOption * "options ", +.BI " int "flags ");" +.fi +.sp +The first parameter, +.IR name ", is used only for alias handling (discussed later). It " +should be the name of the application whose options are being parsed, +.RB "or should be " NULL " if no option aliasing is desired. The next " +two arguments specify the command-line arguments to parse. These are +.RB "generally passed to " poptGetContext() " exactly as they were " +.RB "passed to the program's " main() " function. The " +.IR options " parameter points to the table of command-line options, " +which was described in the previous section. The final parameter, +.IR flags ",is not currently used but should always be specified as +0 for compatibility with future versions of the popt library. +.sp +.RB "A " poptContext " keeps track of which options have already been " +parsed and which remain, among other things. If a program wishes to +restart option processing of a set of arguments, it can reset the +.BR poptContext " by passing the context as the sole argument to " +.BR poptResetContext() . +.sp +When argument processing is complete, the process should free the +.BR poptContext " as it contains dynamically allocated components. The " +.BR poptFreeContext() " function takes a " +.BR poptContext " as its sole argument and frees the resources the " +context is using. +.sp +.RB "Here are the prototypes of both " poptResetContext() " and " +.BR poptFreeContext() : +.sp +.nf +.B #include <popt.h> +.BI "void poptFreeContext(poptContext " con ");" +.BI "void poptResetContext(poptContext " con ");" +.fi +.sp +.SS "3. PARSING THE COMMAND LINE" +.RB "After an application has created a " poptContext ", it may begin " +.RB "parsing arguments. " poptGetNextOpt() " performs the actual " +argument parsing. +.sp +.nf +.B #include <popt.h> +.BI "int poptGetNextOpt(poptContext " con ");" +.fi +.sp +Taking the context as its sole argument, this function parses the next +command-line argument found. After finding the next argument in the +option table, the function fills in the object pointed to by the option +.RI "table entry's " arg +.RB "pointer if it is not " NULL ". If the val entry for the option is " +non-0, the function then returns that value. Otherwise, +.BR poptGetNextOpt() " continues on to the next argument." +.sp +.BR poptGetNextOpt() " returns -1 when the final argument has been " +parsed, and other negative values when errors occur. This makes it a +good idea to +.RI "keep the " val " elements in the options table greater than 0." +.sp +.RI "If all of the command-line options are handled through " arg +pointers, command-line parsing is reduced to the following line of code: +.sp +.nf +rc = poptGetNextOpt(poptcon); +.fi +.sp +Many applications require more complex command-line parsing than this, +however, and use the following structure: +.sp +.nf +while ((rc = poptGetNextOpt(poptcon)) > 0) { + switch (rc) { + /* specific arguments are handled here */ + } +} +.fi +.sp +When returned options are handled, the application needs to know the +value of any arguments that were specified after the option. There are two +ways to discover them. One is to ask popt to fill in a variable with the +.RI "value of the option through the option table's " arg " elements. The " +.RB "other is to use " poptGetOptArg() ":" +.sp +.nf +.B #include <popt.h> +.BI "char * poptGetOptArg(poptContext " con ");" +.fi +.sp +This function returns the argument given for the final option returned by +.BR poptGetNextOpt() ", or it returns " NULL " if no argument was specified." +.sp +.SS "4. LEFTOVER ARGUMENTS" +Many applications take an arbitrary number of command-line arguments, +such as a list of file names. When popt encounters an argument that does +not begin with a -, it assumes it is such an argument and adds it to a list +of leftover arguments. Three functions allow applications to access such +arguments: +.nf +.HP +.BI "char * poptGetArg(poptContext " con ");" +.fi +This function returns the next leftover argument and marks it as +processed. +.PP +.nf +.HP +.BI "char * poptPeekArg(poptContext " con ");" +.fi +The next leftover argument is returned but not marked as processed. +This allows an application to look ahead into the argument list, +without modifying the list. +.PP +.nf +.HP +.BI "char ** poptGetArgs(poptContext " con ");" +.fi +All the leftover arguments are returned in a manner identical to +.IR argv ". The final element in the returned array points to " +.BR NULL ", indicating the end of the arguments. +.PP +.SH "ERROR HANDLING" +All of the popt functions that can return errors return integers. +When an error occurs, a negative error code is returned. The +following table summarizes the error codes that occur: +.sp +.nf +.B " Error Description" +.BR "POPT_ERROR_NOARG " "Argument missing for an option." +.BR "POPT_ERROR_BADOPT " "Option's argument couldn't be parsed." +.BR "POPT_ERROR_OPTSTOODEEP " "Option aliasing nested too deeply." +.BR "POPT_ERROR_BADQUOTE " "Quotations do not match." +.BR "POPT_ERROR_BADNUMBER " "Option couldn't be converted to number." +.BR "POPT_ERROR_OVERFLOW " "A given number was too big or small." +.fi +.sp +Here is a more detailed discussion of each error: +.sp +.TP +.B POPT_ERROR_NOARG +An option that requires an argument was specified on the command +line, but no argument was given. This can be returned only by +.BR poptGetNextOpt() . +.sp +.TP +.B POPT_ERROR_BADOPT +.RI "An option was specified in " argv " but is not in the option +.RB "table. This error can be returned only from " poptGetNextOpt() . +.sp +.TP +.B POPT_ERROR_OPTSTOODEEP +A set of option aliases is nested too deeply. Currently, popt +follows options only 10 levels to prevent infinite recursion. Only +.BR poptGetNextOpt() " can return this error." +.sp +.TP +.B POPT_ERROR_BADQUOTE +A parsed string has a quotation mismatch (such as a single quotation +.RB "mark). " poptParseArgvString() ", " poptReadConfigFile() ", or " +.BR poptReadDefaultConfig() " can return this error." +.sp +.TP +.B POPT_ERROR_BADNUMBER +A conversion from a string to a number (int or long) failed due +to the string containing nonnumeric characters. This occurs when +.BR poptGetNextOpt() " is processing an argument of type " +.BR POPT_ARG_INT " or " POPT_ARG_LONG . +.sp +.TP +.B POPT_ERROR_OVERFLOW +A string-to-number conversion failed because the number was too +.RB "large or too small. Like " POPT_ERROR_BADNUMBER ", this error +.RB "can occur only when " poptGetNextOpt() " is processing an " +.RB "argument of type " POPT_ARG_INT " or " POPT_ARG_LONG . +.sp +.TP +.B POPT_ERROR_ERRNO +.RI "A system call returned with an error, and " errno " still +contains the error from the system call. Both +.BR poptReadConfigFile() " and " poptReadDefaultConfig() " can " +return this error. +.sp +.PP +Two functions are available to make it easy for applications to provide +good error messages. +.HP +.nf +.BI "const char * poptStrerror(const int " error ");" +.fi +This function takes a popt error code and returns a string describing +.RB "the error, just as with the standard " strerror() " function." +.PP +.HP +.nf +.BI "char * poptBadOption(poptContext " con ", int " flags ");" +.fi +.RB "If an error occurred during " poptGetNextOpt() ", this function " +.RI "returns the option that caused the error. If the " flags " argument" +.RB "is set to " POPT_BADOPTION_NOALIAS ", the outermost option is " +.RI "returned. Otherwise, " flags " should be 0, and the option that is " +returned may have been specified through an alias. +.PP +These two functions make popt error handling trivial for most +applications. When an error is detected from most of the functions, +an error message is printed along with the error string from +.BR poptStrerror() ". When an error occurs during argument parsing, " +code similiar to the following displays a useful error message: +.sp +.nf +fprintf(stderr, "%s: %s\\n", + poptBadOption(optCon, POPT_BADOPTION_NOALIAS), + poptStrerror(rc)); +.fi +.sp +.SH "OPTION ALIASING" +.RB "One of the primary benefits of using popt over " getopt() " is the " +ability to use option aliasing. This lets the user specify options that +popt expands into other options when they are specified. If the standard +.RB "grep program made use of popt, users could add a " --text " option " +.RB "that expanded to " "-i -n -E -2" " to let them more easily find " +information in text files. +.sp +.SS "1. SPECIFYING ALIASES" +.RI "Aliases are normally specified in two places: " /etc/popt +.RB "and the " .popt " file in the user's home directory (found through " +.RB "the " HOME " environment variable). Both files have the same format, " +an arbitrary number of lines formatted like this: +.sp +.IB appname " alias " newoption "" " expansion" +.sp +.RI "The " appname " is the name of the application, which must be the " +.RI "same as the " name " parameter passed to " +.BR poptGetContext() ". This allows each file to specify aliases for " +.RB "multiple programs. The " alias " keyword specifies that an alias is " +being defined; currently popt configuration files support only aliases, but +other abilities may be added in the future. The next option is the option +that should be aliased, and it may be either a short or a long option. The +rest of the line specifies the expansion for the alias. It is parsed +similarly to a shell command, which allows \\, ", and ' to be used for +quoting. If a backslash is the final character on a line, the next line +in the file is assumed to be a logical continuation of the line containing +the backslash, just as in shell. +.sp +.RB "The following entry would add a " --text " option to the grep command, " +as suggested at the beginning of this section. +.sp +.B "grep alias --text -i -n -E -2" +.SS "2. ENABLING ALIASES" +.RB "An application must enable alias expansion for a " poptContext +.RB "before calling " poptGetNextArg() " for the first time. There are " +three functions that define aliases for a context: +.HP +.nf +.BI "int poptReadDefaultConfig(poptContext " con ", int " flags ");" +.fi +.RI "This function reads aliases from " /etc/popt " and the " +.BR .popt " file in the user's home directory. Currently, " +.IR flags " should be " +.BR NULL ", as it is provided only for future expansion." +.PP +.HP +.nf +.BI "int poptReadConfigFile(poptContext " con ", char * " fn ");" +.fi +.RI "The file specified by " fn " is opened and parsed as a popt " +configuration file. This allows programs to use program-specific +configuration files. +.PP +.HP +.nf +.BI "int poptAddAlias(poptContext " con ", struct poptAlias " alias ", +.BI " int " flags ");" +.fi +Occasionally, processes want to specify aliases without having to +read them from a configuration file. This function adds a new alias +.RI "to a context. The " flags " argument should be 0, as it is " +currently reserved for future expansion. The new alias is specified +.RB "as a " "struct poptAlias" ", which is defined as:" +.sp +.nf +struct poptAlias { + char * longName; /* may be NULL */ + char shortName; /* may be '\\0' */ + int argc; + char ** argv; /* must be free()able */ +}; +.fi +.sp +.RI "The first two elements, " longName " and " shortName ", specify " +.RI "the option that is aliased. The final two, " argc " and " argv "," +define the expansion to use when the aliases option is encountered. +.PP +.SH "PARSING ARGUMENT STRINGS" +Although popt is usually used for parsing arguments already divided into +.RI "an " argv "-style array, some programs need to parse strings that " +are formatted identically to command lines. To facilitate this, popt +provides a function that parses a string into an array of strings, +using rules similiar to normal shell parsing. +.sp +.nf +.B "#include <popt.h>" +.BI "int poptParseArgvString(char * " s ", int * "argcPtr ", +.BI " char *** " argvPtr ");" +.fi +.sp +.RI "The string s is parsed into an " argv "-style array. The integer " +.RI "pointed to by the second parameter, " argcPtr ", contains the number " +of elements parsed, and the pointer pointed to by the final parameter is +set to point to the newly created array. The array is dynamically +.RB "allocated and should be " free() "ed when the application is finished " +with it. +.sp +.RI "The " argvPtr +.RB "created by " poptParseArgvString() " is suitable to pass directly " +.RB "to " poptGetContext() . +.SH "HANDLING EXTRA ARGUMENTS" +Some applications implement the equivalent of option aliasing but need +.RB "to do so through special logic. The " poptStuffArgs() " function " +allows an application to insert new arguments into the current +.BR poptContext . +.sp +.nf +.B "#include <popt.h>" +.BI "int poptStuffArgs(poptContext "con ", char ** " argv ");" +.fi +.sp +.RI "The passed " argv +.RB "must have a " NULL " pointer as its final element. When " +.BR poptGetNextOpt() " is next called, the " +"stuffed" arguments are the first to be parsed. popt returns to the +normal arguments once all the stuffed arguments have been exhausted. +.SH "EXAMPLE" +The following example is a simplified version of the program "robin" +which appears in Chapter 15 of the text cited below. Robin has +been stripped of everything but its argument-parsing logic, slightly +reworked, and renamed "parse." It may prove useful in illustrating +at least some of the features of the extremely rich popt library. +.sp +.nf +#include <popt.h> +#include <stdio.h> + +void usage(int exitcode, char *error, char *addl) { + fprintf(stderr, "Usage: parse [options] <port>\\n" + " [options] include:\\n" + " -H,--help for this help\\n" + " -r,--raw for raw mode\\n" + " -c,--crnl to add CR with NL on output\\n" + " -h,--help for hardware flow control\\n" + " -s,--swflow for software flow control\\n" + " -n,--noflow for no flow control\\n" + " -b,--bps <bps> for signalling rate\\n"); + if (error) fprintf(stderr, "%s: %s\\n", error, addl); + exit(exitcode); +} + +int main(int argc, char *argv[]) { + char c; /* used for argument parsing */ + int i = 0; /* used for tracking options */ + char *portname; + int speed = 0; /* used in argument parsing to set speed */ + int raw = 0; /* raw mode? */ + int j; + char buf[BUFSIZ+1]; + poptContext optCon; /* context for parsing command-line options */ + + struct poptOption optionsTable[] = { + { "bps", 'b', POPT_ARG_INT, &speed, 0 }, + { "crnl", 'c', 0, 0, 'c' }, + { "help", 'H', 0, 0, 'H' }, + { "hwflow", 'h', 0, 0, 'h' }, + { "noflow", 'n', 0, 0, 'n' }, + { "raw", 'r', 0, &raw, 0 }, + { "swflow", 's', 0, 0, 's' }, + { NULL, 0, 0, NULL, 0 } + }; + + if (argc < 2) usage(1, "Not enough arguments", ""); + + optCon = poptGetContext(NULL, argc, argv, optionsTable, 0); + + /* Now do options processing, get portname */ + while ((c = poptGetNextOpt(optCon)) >= 0) { + switch (c) { + case 'H': + usage(0, NULL, NULL); + break; + case 'c': + buf[i++] = 'c'; + break; + case 'h': + buf[i++] = 'h'; + break; + case 's': + buf[i++] = 's'; + break; + case 'n': + buf[i++] = 'n'; + break; + } + } + portname = poptGetArg(optCon); + if((portname == NULL) || !(poptPeekArg(optCon) == NULL)) + usage(1, "Specify a single port", ".e.g., /dev/cua0"); + + if (c < -1) { + /* an error occurred during option processing */ + fprintf(stderr, "%s: %s\\n", + poptBadOption(optCon, POPT_BADOPTION_NOALIAS), + poptStrerror(c)); + return 1; + } + + /* Print out options, portname chosen */ + printf("Options chosen: "); + for(j = 0; j < i ; j++) + printf("-%c ", buf[j]); + if(raw) printf("-r "); + if(speed) printf("-b %d ", speed); + printf("\\nPortname chosen: %s\\n", portname); + + poptFreeContext(optCon); + exit(0); +} +.fi +.sp +RPM, a popular Linux package management program, makes heavy use +of popt's features. Many of its command-line arguments are implemented +through popt aliases, which makes RPM an excellent example of how to +take advantage of the popt library. For more information on RPM, see +http://www.rpm.org +.SH BUGS +None presently known. +.SH AUTHOR +Erik W. Troan <ewt@redhat.com> +.PP +This man page is derived in part from +.IR "Linux Application Development" +by Michael K. Johnson and Erik W. Troan, Copyright (c) 1998 by Addison +Wesley Longman, Inc., and included in the popt documentation with the +permission of the Publisher and the appreciation of the Authors. +.PP +Thanks to Robert Lynch for his extensive work on this man page. +.SH "SEE ALSO" +.BR getopt (3) +.sp +.IR "Linux Application Development" ", by Michael K. Johnson and " +Erik W. Troan (Addison-Wesley, 1998; ISBN 0-201-30821-5), Chapter 24. +.sp +.BR popt.ps " is a Postscript version of the above cited book " +chapter. It can be found in the source archive for popt available at: +ftp://ftp.redhat.com/pub/redhat/code/popt |