You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@subversion.apache.org by "B. W. Fitzpatrick" <fi...@red-bean.com> on 2000/11/17 06:17:38 UTC

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

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;
+    }
+}
+
+

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

Posted by Karl Fogel <kf...@galois.collab.net>.
Greg Stein <gs...@lyra.org> writes:
> This has been applied to APR.
> 
> Thanks!

Seconded -- much thanks, Fitz!

-K

> On Fri, Nov 17, 2000 at 12:17:38AM -0600, B. W. Fitzpatrick wrote:
> > 
> > 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
> >...
> 
> -- 
> Greg Stein, http://www.lyra.org/

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

Posted by Greg Stein <gs...@lyra.org>.
This has been applied to APR.

Thanks!

Cheers,
-g

On Fri, Nov 17, 2000 at 12:17:38AM -0600, B. W. Fitzpatrick wrote:
> 
> 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
>...

-- 
Greg Stein, http://www.lyra.org/