*** empty log message ***
authorewt <devnull@localhost>
Mon, 27 Jul 1998 15:54:20 +0000 (15:54 +0000)
committerewt <devnull@localhost>
Mon, 27 Jul 1998 15:54:20 +0000 (15:54 +0000)
CVS patchset: 2187
CVS date: 1998/07/27 15:54:20

popt/popt.3 [new file with mode: 0644]
popt/test-poptrc [new file with mode: 0644]
popt/test1.c [new file with mode: 0644]
popt/testit.sh [new file with mode: 0755]

diff --git a/popt/popt.3 b/popt/popt.3
new file mode 100644 (file)
index 0000000..02ad54f
--- /dev/null
@@ -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
diff --git a/popt/test-poptrc b/popt/test-poptrc
new file mode 100644 (file)
index 0000000..8a6d86c
--- /dev/null
@@ -0,0 +1,9 @@
+test1 alias --simple --arg2
+test1 alias --two --arg1 --arg2 alias
+test1 alias --takerest --
+test1 alias -T --arg2
+test1 alias -O --arg1
+
+test1 exec --echo-args echo
+test1 alias -e --echo-args
+test1 exec -a /bin/echo
diff --git a/popt/test1.c b/popt/test1.c
new file mode 100644 (file)
index 0000000..dc6be87
--- /dev/null
@@ -0,0 +1,47 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "popt.h"
+
+int main(int argc, char ** argv) {
+    int rc;
+    int arg1 = 0;
+    char * arg2 = "(none)";
+    poptContext optCon;
+    char ** rest;
+    int arg3 = 0;
+    struct poptOption options[] = {
+       { "arg1", '\0', 0, &arg1, 0 },
+       { "arg2", '2', POPT_ARG_STRING, &arg2, 0 },
+       { "arg3", '3', POPT_ARG_INT, &arg3, 0 },
+       { NULL, '\0', 0, NULL, 0 } 
+    };
+
+    optCon = poptGetContext("test1", argc, argv, options, 0);
+    poptReadConfigFile(optCon, "./test-poptrc");
+
+    if ((rc = poptGetNextOpt(optCon)) < -1) {
+       fprintf(stderr, "test1: bad argument %s: %s\n", 
+               poptBadOption(optCon, POPT_BADOPTION_NOALIAS), 
+               poptStrerror(rc));
+       return 2;
+    }
+
+    printf("arg1: %d arg2: %s", arg1, arg2);
+
+    if (arg3)
+       printf(" arg3: %d", arg3);
+
+    rest = poptGetArgs(optCon);
+    if (rest) {
+       printf(" rest:");
+       while (*rest) {
+           printf(" %s", *rest);
+           rest++;
+       }
+    }
+
+    printf("\n");
+
+    return 0;
+}
diff --git a/popt/testit.sh b/popt/testit.sh
new file mode 100755 (executable)
index 0000000..ea8dff0
--- /dev/null
@@ -0,0 +1,36 @@
+#!/bin/sh
+
+run() {
+    prog=$1; shift
+    name=$1; shift
+    answer=$1; shift
+
+    echo Running test $name.
+
+    result=`./$prog $*`
+    if [ "$answer" != "$result" ]; then
+       echo "Test \"$*\" failed with: $result"
+       exit 2
+    fi
+}
+
+make -q testcases
+
+run test1 "test1 - 1" "arg1: 1 arg2: (none)" --arg1
+run test1 "test1 - 2" "arg1: 0 arg2: foo" --arg2 foo
+run test1 "test1 - 3" "arg1: 1 arg2: something" --arg1 --arg2 something
+run test1 "test1 - 4" "arg1: 0 arg2: another" --simple another
+run test1 "test1 - 5" "arg1: 1 arg2: alias" --two
+run test1 "test1 - 6" "arg1: 1 arg2: (none) rest: --arg2" --arg1 -- --arg2 
+run test1 "test1 - 7" "arg1: 0 arg2: abcd rest: --arg1" --simple abcd -- --arg1 
+run test1 "test1 - 8" "arg1: 1 arg2: (none) rest: --arg2" --arg1 --takerest --arg2 
+run test1 "test1 - 9" "arg1: 0 arg2: foo" -2 foo
+run test1 "test1 - 10" "arg1: 0 arg2: (none) arg3: 50" -3 50
+run test1 "test1 - 11" "arg1: 0 arg2: bar" -T bar
+run test1 "test1 - 12" "arg1: 1 arg2: (none)" -O 
+run test1 "test1 - 13" "arg1: 1 arg2: foo" -OT foo
+run test1 "test1 - 14" "" --echo-args
+run test1 "test1 - 15" "--arg1" --echo-args --arg1
+run test1 "test1 - 16" "--arg2 something" -T something -e
+run test1 "test1 - 17" "--arg2 something -- more args" -T something -a more args
+run test1 "test1 - 18" "--echo-args -a" --echo-args -e -a