[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

[PATCH] (apr) new function apr_getopt_long + apr_getopt mods

From: B. W. Fitzpatrick <fitz_at_red-bean.com>
Date: 2000-11-17 07:17:38 CET

Greg, here's a patch to add long option processing to apr. I also
added in the "--foo=bar" functionality this evening, so barring any
logic bugs, here's the patch.

Thanks to you and Karl for review, and Greg Hudson for the header
file, inline docs, and review.

-Fitz

Log messages:

include/apr_getopt.h

*) Added new struct and typedef for apr_getopt_long_t.
*) Added prototype and inline documentation for new apr_getopt_long
   function.

misc/unix/getopt.c

*) Added new apr_getopt_long function to handle long option
   processing.
*) Added static method `pretty_path' to avoid duplicating code
*) modified apr_getopt to use pretty_path. Removed cut-and-paste code
   as well as char *p.

pantheon: /home/bwf/software/subversion/apr>cvs diff
Index: include/apr_getopt.h
===================================================================
RCS file: /home/cvspublic/apache-2.0/src/lib/apr/include/apr_getopt.h,v
retrieving revision 1.21
diff -u -r1.21 apr_getopt.h
--- include/apr_getopt.h 2000/10/16 06:04:42 1.21
+++ include/apr_getopt.h 2000/11/17 05:58:47
@@ -82,6 +82,20 @@
     char const* place;
 };
 
+typedef struct apr_getopt_long_t apr_getopt_long_t;
+
+/* structure representing a single longopt */
+struct apr_getopt_long_t {
+ /* the name of the long argument (sans "--") */
+ const char *name;
+ /* 0 for no arg, 1 for arg */
+ int has_arg;
+ /* Either the short option char that this option corresponds to
+ * or a unique integer > 255
+ */
+ int val;
+};
+
 /**
  * Initialize the arguments for parsing by apr_getopt().
  * @param cont The pool to operate on
@@ -111,8 +125,46 @@
  * </PRE>
  * @deffunc apr_status_t apr_getopt(apr_getopt_t *os, const char *opts, char *optch, const char **optarg)
  */
+
 APR_DECLARE(apr_status_t) apr_getopt(apr_getopt_t *os, const char *opts,
                                     char *optch, const char **optarg);
+
+/**
+ * Parse the options initialized by apr_initopt(), accepting long
+ * options beginning with "--" in addition to single-character
+ * options beginning with "-" (which are passed along to apr_getopt).
+ *
+ * Long options are accepted in both "--foo bar" and well as
+ * "--foo=bar" format
+ *
+ * End of argument processing if we encounter "--" or any option that
+ * doesn't start with "-" or "--".
+ *
+ * @param os The apr_opt_t structure returned by apr_initopt()
+ * @param opts A string of acceptable single-character options to the
+ * program. Characters followed by ":" are required to have
+ * an argument associated
+ * @param longopts A pointer to an array of apr_long_option_t structures, which
+ * can be initialized with { "name", has_args, val }. has_args
+ * is nonzero if the option requires an argument. A structure
+ * with a NULL name terminates the list
+ * @param optval The next option character parsed, or the value of "optval"
+ * from the appropriate apr_long_option_t structure if
+ * the next option is a long option.
+ * @param optarg The argument following the option, if any
+ * @tip There are four potential status values on exit. They are:
+ * <PRE>
+ * APR_EOF -- No more options to parse
+ * APR_BADCH -- Found a bad option character
+ * APR_BADARG -- No argument followed @parameter:
+ * APR_SUCCESS -- The next option was found.
+ * </PRE>
+ * @deffunc apr_status_t apr_getopt_long(apr_getopt_t *os, const char *opts, const apr_getopt_long_t *longopts, int *optval, const char **optarg) */
+APR_DECLARE(apr_status_t) apr_getopt_long(apr_getopt_t *os,
+ const char *opts,
+ const apr_getopt_long_t *long_opts,
+ int *optval,
+ const char **optarg);
 
 #endif /* ! APR_GETOPT_H */
 
Index: misc/unix/getopt.c
===================================================================
RCS file: /home/cvspublic/apache-2.0/src/lib/apr/misc/unix/getopt.c,v
retrieving revision 1.23
diff -u -r1.23 getopt.c
--- misc/unix/getopt.c 2000/10/16 06:04:47 1.23
+++ misc/unix/getopt.c 2000/11/17 05:58:48
@@ -32,9 +32,21 @@
  */
 
 #include "misc.h"
+#include "apr_strings.h"
 
 #define EMSG ""
 
+/* Regardless of what we're invoked as, just print out the last part
+ * of the path */
+static char *pretty_path (char* name)
+{
+ char *p;
+ if (!(p = strrchr(name, '/')))
+ return p;
+ else
+ return ++p;
+}
+
 APR_DECLARE(apr_status_t) apr_initopt(apr_getopt_t **os, apr_pool_t *cont,
                                      int argc, char *const *argv)
 {
@@ -51,7 +63,6 @@
 APR_DECLARE(apr_status_t) apr_getopt(apr_getopt_t *os, const char *opts,
                                     char *optch, const char **optarg)
 {
- const char *p;
     const char *oli; /* option letter list index */
 
     if (os->reset || !*os->place) { /* update scanning pointer */
@@ -81,12 +92,8 @@
         if (!*os->place)
             ++os->ind;
         if (os->err && *opts != ':') {
- if (!(p = strrchr(*os->argv, '/')))
- p = *os->argv;
- else
- ++p;
             (void) fprintf(stderr,
- "%s: illegal option -- %c\n", p, os->opt);
+ "%s: illegal option -- %c\n", pretty_path(*os->argv), os->opt);
         }
         *optch = os->opt;
         return (APR_BADCH);
@@ -106,13 +113,9 @@
                 return (APR_BADARG);
             }
             if (os->err) {
- if (!(p = strrchr(*os->argv, '/')))
- p = *os->argv;
- else
- ++p;
                 (void) fprintf(stderr,
                                "%s: option requires an argument -- %c\n",
- p, os->opt);
+ pretty_path(*os->argv), os->opt);
             }
             *optch = os->opt;
             return (APR_BADCH);
@@ -125,5 +128,91 @@
     *optch = os->opt;
     return APR_SUCCESS;
 }
+
+APR_DECLARE(apr_status_t) apr_getopt_long(apr_getopt_t *os,
+ const char *opts,
+ const apr_getopt_long_t *long_opts,
+ int *optval,
+ const char **optarg)
+
+{
+ const apr_getopt_long_t *ptr;
+ char *opt = os->argv[os->ind];
+ char *arg = os->argv[os->ind +1];
+ int arg_index_incr = 1;
+
+ /* Finished processing opts */
+ if (os->ind >= os->argc)
+ return APR_EOF;
+
+ /* End of options processing if we encounter "--" */
+ if (strcmp(opt, "--") == 0)
+ return APR_EOF;
+
+ /*
+ * End of options processing if we encounter something that
+ * doesn't start with "-" or "--" (it's not an option if we hit it
+ * here, it's an argument)
+ */
+ if (*opt != '-')
+ return APR_EOF;
+
+ if ((os->ind + 1) >= os->argc)
+ arg = NULL;
+
+ /* Handle --foo=bar style opts */
+ if (strchr(opt, '=')) {
+ char *index = strchr(opt, '=') + 1;
+ opt = apr_pstrndup(os->cont, opt, ((index - opt) - 1));
+ if (*index != '\0') /* account for "--foo=" */
+ arg = apr_pstrdup(os->cont, index);
+ arg_index_incr = 0;
+ }
+
+ /* If it's a longopt */
+ if (opt[1] == '-') {
+ /* see if it's in our array of long opts */
+ for (ptr = long_opts; ptr->name; ptr++) {
+ if (strcmp((opt + 2), ptr->name) == 0) { /* it's in the array */
+ if (ptr->has_arg) {
+ if (((os->ind + 1) >= os->argc)
+ && (arg == NULL)) {
+ fprintf(stderr,
+ "%s: option requires an argument: %s\n",
+ pretty_path(*os->argv), opt);
+ return APR_BADARG;
+ }
+
+ /* If we make it here, then we should be ok. */
+ *optarg = arg;
+ os->ind += arg_index_incr;
+ }
+ else { /* has no arg */
+ *optarg = NULL;
+ }
+ *optval = ptr->val;
+ ++os->ind;
+ return APR_SUCCESS;
+ }
+ }
+
+ /* If we get here, then we don't have the longopt in our
+ * longopts array
+ */
+ fprintf(stderr, "%s: illegal option: %s\n",
+ pretty_path(*os->argv), opt);
+ return APR_BADCH;
+ }
+
+ { /* otherwise, apr_getopt gets it. */
+ char optch;
+ apr_status_t status;
+ status = apr_getopt (os, opts, &optch, optarg);
+ *optval = optch;
+ return status;
+ }
+}
+
+
Received on Sat Oct 21 14:36:15 2006

This is an archived mail posted to the Subversion Dev mailing list.