summaryrefslogtreecommitdiff
path: root/popt.3
diff options
context:
space:
mode:
authorewt <ewt>1998-07-27 15:54:20 +0000
committerewt <ewt>1998-07-27 15:54:20 +0000
commit5c2ea6b02044d7d25be8e014c4b9fd08e11df6dd (patch)
tree72a019ddd6f7a5c85fb0db00e89b2a2ed3df5499 /popt.3
parent6e8bfe6864823aecc5a6d361c7501af08b1a7047 (diff)
downloadlibpopt-5c2ea6b02044d7d25be8e014c4b9fd08e11df6dd.tar.gz
*** empty log message ***
Diffstat (limited to 'popt.3')
-rw-r--r--popt.3612
1 files changed, 612 insertions, 0 deletions
diff --git a/popt.3 b/popt.3
new file mode 100644
index 0000000..02ad54f
--- /dev/null
+++ b/popt.3
@@ -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