ASF Bugzilla – Attachment 31227 Details for
Bug 56030
give getopt error codes for localisation
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
apr-getopt-error-code.patch
apr-getopt-error-code.patch (text/plain), 14.33 KB, created by
Mattias EngdegÄrd
on 2014-01-18 14:50:39 UTC
(
hide
)
Description:
apr-getopt-error-code.patch
Filename:
MIME Type:
Creator:
Mattias EngdegÄrd
Created:
2014-01-18 14:50:39 UTC
Size:
14.33 KB
patch
obsolete
>Index: include/apr_getopt.h >=================================================================== >--- include/apr_getopt.h (revision 1552978) >+++ include/apr_getopt.h (arbetskopia) >@@ -92,6 +92,22 @@ > }; > > /** >+ * Error codes returned from apr_getopt_errcode(). >+ * >+ * The associated values returned from apr_getopt_errparam() are given >+ * below for each error code. >+ */ >+typedef enum { >+ APR_GETOPT_INVALID_OPTION, /**< Invalid option; error parameter >+ is the option. */ >+ APR_GETOPT_MISSING_ARGUMENT, /**< Missing argument; error parameter is >+ the option whose argument is >+ missing. */ >+ APR_GETOPT_INVALID_ARGUMENT /**< Invalid or malformed argument; error >+ parameter is the invalid argument. */ >+} apr_getopt_error_e; >+ >+/** > * Initialize the arguments for parsing by apr_getopt(). > * @param os The options structure created for apr_getopt() > * @param cont The pool to operate on >@@ -151,6 +167,30 @@ > const apr_getopt_option_t *opts, > int *option_ch, > const char **option_arg); >+ >+/** >+ * Retrieve a code describing the current getopt error. This function >+ * may only be called from the getopt error function, @c errfn >+ * in @c apr_getopt_t. >+ * @param os The apr_getopt_t structure created by apr_getopt_init(). >+ * @return The error code. >+ * Error codes may have an associated string parameter; >+ * use apr_getopt_errparam() to retrieve it. >+ */ >+APR_DECLARE(apr_getopt_error_e) apr_getopt_errcode(apr_getopt_t *os); >+ >+/** >+ * Retrieve a string parameter pertaining to the current getopt error. >+ * This function may only be called from the getopt error function, @c errfn >+ * in @c apr_getopt_t. >+ * @param os The apr_getopt_t structure created by apr_getopt_init(). >+ * @return The error parameter string. It is only valid during the error >+ * function call. >+ * The meaning of the returned string depends on the current getopt error code; >+ * use apr_getopt_errcode() to retrieve it. >+ */ >+APR_DECLARE(const char *) apr_getopt_errparam(apr_getopt_t *os); >+ > /** @} */ > > #ifdef __cplusplus >Index: misc/unix/getopt.c >=================================================================== >--- misc/unix/getopt.c (revision 1552978) >+++ misc/unix/getopt.c (arbetskopia) >@@ -68,6 +68,43 @@ > return APR_SUCCESS; > } > >+struct error_info_t { >+ apr_getopt_error_e code; >+ const char *param; >+}; >+ >+APR_DECLARE(apr_getopt_error_e) apr_getopt_errcode(apr_getopt_t *os) >+{ >+ struct error_info_t *e = os->errarg; >+ return e->code; >+} >+ >+APR_DECLARE(const char *) apr_getopt_errparam(apr_getopt_t *os) >+{ >+ struct error_info_t *e = os->errarg; >+ return e->param; >+} >+ >+/* Print out an error by calling the user-defined error callback, if any. */ >+static void perr(apr_getopt_t *os, apr_getopt_error_e err, >+ const char *msg, const char *par) >+{ >+ if (os->errfn) { >+ /* Hack: we temporarily re-purpose the errarg member for >+ holding a reference to the error code and string parameter >+ during the call to the error function. */ >+ void *errarg = os->errarg; >+ struct error_info_t e; >+ e.code = err; >+ e.param = par; >+ os->errarg = &e; >+ (os->errfn)(errarg, "%s: %s: %s\n", >+ apr_filepath_name_get(*os->argv), msg, par); >+ if (os->errarg == &e) >+ os->errarg = errarg; >+ } >+} >+ > APR_DECLARE(apr_status_t) apr_getopt(apr_getopt_t *os, const char *opts, > char *optch, const char **optarg) > { >@@ -99,9 +136,11 @@ > } > if (!*os->place) > ++os->ind; >- if (os->errfn && *opts != ':') { >- (os->errfn)(os->errarg, "%s: illegal option -- %c\n", >- apr_filepath_name_get(*os->argv), os->opt); >+ if (*opts != ':') { >+ char par[2] = "x"; >+ par[0] = os->opt; >+ perr(os, APR_GETOPT_INVALID_OPTION, >+ "illegal option", par); > } > *optch = os->opt; > return (APR_BADCH); >@@ -115,16 +154,15 @@ > if (*os->place) /* no white space */ > *optarg = os->place; > else if (os->argc <= ++os->ind) { /* no arg */ >+ char par[2] = "x"; > os->place = EMSG; > if (*opts == ':') { > *optch = os->opt; > return (APR_BADARG); > } >- if (os->errfn) { >- (os->errfn)(os->errarg, >- "%s: option requires an argument -- %c\n", >- apr_filepath_name_get(*os->argv), os->opt); >- } >+ par[0] = os->opt; >+ perr(os, APR_GETOPT_MISSING_ARGUMENT, >+ "option requires an argument", par); > *optch = os->opt; > return (APR_BADCH); > } >@@ -177,26 +215,6 @@ > os->skip_end += len2; > } > >-/* Helper function to print out an error involving a long option */ >-static apr_status_t serr(apr_getopt_t *os, const char *err, const char *str, >- apr_status_t status) >-{ >- if (os->errfn) >- (os->errfn)(os->errarg, "%s: %s: %s\n", >- apr_filepath_name_get(*os->argv), err, str); >- return status; >-} >- >-/* Helper function to print out an error involving a short option */ >-static apr_status_t cerr(apr_getopt_t *os, const char *err, int ch, >- apr_status_t status) >-{ >- if (os->errfn) >- (os->errfn)(os->errarg, "%s: %s: %c\n", >- apr_filepath_name_get(*os->argv), err, ch); >- return status; >-} >- > APR_DECLARE(apr_status_t) apr_getopt_long(apr_getopt_t *os, > const apr_getopt_option_t *opts, > int *optch, const char **optarg) >@@ -236,8 +254,11 @@ > > p++; > for (i = 0; ; i++) { >- if (opts[i].optch == 0) /* No match */ >- return serr(os, "invalid option", p - 2, APR_BADCH); >+ if (opts[i].optch == 0) { /* No match */ >+ perr(os, APR_GETOPT_INVALID_OPTION, >+ "invalid option", p - 2); >+ return APR_BADCH; >+ } > > if (opts[i].name) { > len = strlen(opts[i].name); >@@ -252,15 +273,20 @@ > if (p[len] == '=') /* Argument inline */ > *optarg = p + len + 1; > else { >- if (os->ind >= os->argc) /* Argument missing */ >- return serr(os, "missing argument", p - 2, APR_BADARG); >- else /* Argument in next arg */ >+ if (os->ind >= os->argc) { /* Argument missing */ >+ perr(os, APR_GETOPT_MISSING_ARGUMENT, >+ "missing argument", p - 2); >+ return APR_BADARG; >+ } else /* Argument in next arg */ > *optarg = os->argv[os->ind++]; > } > } else { > *optarg = NULL; >- if (p[len] == '=') >- return serr(os, "erroneous argument", p - 2, APR_BADARG); >+ if (p[len] == '=') { >+ perr(os, APR_GETOPT_INVALID_ARGUMENT, >+ "erroneous argument", p - 2); >+ return APR_BADARG; >+ } > } > permute(os); > return APR_SUCCESS; >@@ -271,8 +297,11 @@ > return APR_EOF; > } > else >- if (*p == '\0') /* Bare "-" is illegal */ >- return serr(os, "invalid option", p, APR_BADCH); >+ if (*p == '\0') { /* Bare "-" is illegal */ >+ perr(os, APR_GETOPT_INVALID_OPTION, >+ "invalid option", p - 1); >+ return APR_BADCH; >+ } > } > } > >@@ -281,8 +310,13 @@ > * Look for it in the caller's table. > */ > for (i = 0; ; i++) { >- if (opts[i].optch == 0) /* No match */ >- return cerr(os, "invalid option character", *p, APR_BADCH); >+ if (opts[i].optch == 0) { /* No match */ >+ char arg[2] = "x"; >+ arg[0] = *p; >+ perr(os, APR_GETOPT_INVALID_OPTION, >+ "invalid option", arg); >+ return APR_BADCH; >+ } > > if (*p == opts[i].optch) > break; >@@ -293,9 +327,13 @@ > if (*p != '\0') /* Argument inline */ > *optarg = p; > else { >- if (os->ind >= os->argc) /* Argument missing */ >- return cerr(os, "missing argument", *optch, APR_BADARG); >- else /* Argument in next arg */ >+ if (os->ind >= os->argc) { /* Argument missing */ >+ char arg[2] = "x"; >+ arg[0] = *optch; >+ perr(os, APR_GETOPT_MISSING_ARGUMENT, >+ "missing argument", arg); >+ return APR_BADARG; >+ } else /* Argument in next arg */ > *optarg = os->argv[os->ind++]; > } > os->place = EMSG; >Index: test/testargs.c >=================================================================== >--- test/testargs.c (revision 1552978) >+++ test/testargs.c (arbetskopia) >@@ -30,13 +30,25 @@ > } > } > >-static void unknown_arg(void *str, const char *err, ...) >+typedef struct { >+ apr_getopt_t *opt; >+ char *formatted; >+ char *param; >+ int errcode; /* Actually an apr_getopt_error_e, but declared >+ int so that it can contain an OOB value. */ >+} error_data_t; >+ >+static void unknown_arg(void *arg, const char *err, ...) > { >+ error_data_t *ed = arg; > va_list va; > > va_start(va, err); >- apr_vsnprintf(str, 8196, err, va); >+ apr_vsnprintf(ed->formatted, 8196, err, va); > va_end(va); >+ >+ ed->errcode = apr_getopt_errcode(ed->opt); >+ strncpy(ed->param, apr_getopt_errparam(ed->opt), 128); > } > > static void no_options_found(abts_case *tc, void *data) >@@ -78,13 +90,21 @@ > char ch; > const char *opt_arg; > char str[8196]; >+ char par[128]; >+ error_data_t ed; > > str[0] = '\0'; >+ par[0] = '\0'; > rv = apr_getopt_init(&opt, p, largc, largv); > ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); > >+ ed.opt = opt; >+ ed.formatted = str; >+ ed.param = par; >+ ed.errcode = -1; >+ > opt->errfn = unknown_arg; >- opt->errarg = str; >+ opt->errarg = &ed; > > while (apr_getopt(opt, "efgh", &ch, &opt_arg) == APR_SUCCESS) { > switch (ch) { >@@ -98,7 +118,9 @@ > break; > } > } >- ABTS_STR_EQUAL(tc, "testprog: illegal option -- a\n", str); >+ ABTS_STR_EQUAL(tc, "testprog: illegal option: a\n", str); >+ ABTS_STR_EQUAL(tc, "a", par); >+ ABTS_INT_EQUAL(tc, APR_GETOPT_INVALID_OPTION, ed.errcode); > } > > static void required_option(abts_case *tc, void *data) >@@ -110,13 +132,19 @@ > char ch; > const char *opt_arg; > char str[8196]; >+ error_data_t ed; > > str[0] = '\0'; > rv = apr_getopt_init(&opt, p, largc, largv); > ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); > >+ ed.opt = opt; >+ ed.formatted = str; >+ ed.param = NULL; >+ ed.errcode = -1; >+ > opt->errfn = unknown_arg; >- opt->errarg = str; >+ opt->errarg = &ed; > > while (apr_getopt(opt, "a:", &ch, &opt_arg) == APR_SUCCESS) { > switch (ch) { >@@ -128,6 +156,7 @@ > } > } > ABTS_STR_EQUAL(tc, "option: a with foo\n", str); >+ ABTS_INT_EQUAL(tc, -1, ed.errcode); > } > > static void required_option_notgiven(abts_case *tc, void *data) >@@ -139,13 +168,21 @@ > char ch; > const char *opt_arg; > char str[8196]; >+ char par[128]; >+ error_data_t ed; > > str[0] = '\0'; >+ par[0] = '\0'; > rv = apr_getopt_init(&opt, p, largc, largv); > ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); > >+ ed.opt = opt; >+ ed.formatted = str; >+ ed.param = par; >+ ed.errcode = -1; >+ > opt->errfn = unknown_arg; >- opt->errarg = str; >+ opt->errarg = &ed; > > while (apr_getopt(opt, "a:", &ch, &opt_arg) == APR_SUCCESS) { > switch (ch) { >@@ -156,7 +193,9 @@ > break; > } > } >- ABTS_STR_EQUAL(tc, "testprog: option requires an argument -- a\n", str); >+ ABTS_STR_EQUAL(tc, "testprog: option requires an argument: a\n", str); >+ ABTS_STR_EQUAL(tc, "a", par); >+ ABTS_INT_EQUAL(tc, APR_GETOPT_MISSING_ARGUMENT, ed.errcode); > } > > static void optional_option(abts_case *tc, void *data) >@@ -168,13 +207,19 @@ > char ch; > const char *opt_arg; > char str[8196]; >+ error_data_t ed; > > str[0] = '\0'; > rv = apr_getopt_init(&opt, p, largc, largv); > ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); > >+ ed.opt = opt; >+ ed.formatted = str; >+ ed.param = NULL; >+ ed.errcode = -1; >+ > opt->errfn = unknown_arg; >- opt->errarg = str; >+ opt->errarg = &ed; > > while (apr_getopt(opt, "a::", &ch, &opt_arg) == APR_SUCCESS) { > switch (ch) { >@@ -186,6 +231,7 @@ > } > } > ABTS_STR_EQUAL(tc, "option: a with foo\n", str); >+ ABTS_INT_EQUAL(tc, -1, ed.errcode); > } > > static void optional_option_notgiven(abts_case *tc, void *data) >@@ -197,13 +243,21 @@ > char ch; > const char *opt_arg; > char str[8196]; >+ char par[128]; >+ error_data_t ed; > > str[0] = '\0'; >+ par[0] = '\0'; > rv = apr_getopt_init(&opt, p, largc, largv); > ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); > >+ ed.opt = opt; >+ ed.formatted = str; >+ ed.param = par; >+ ed.errcode = -1; >+ > opt->errfn = unknown_arg; >- opt->errarg = str; >+ opt->errarg = &ed; > > while (apr_getopt(opt, "a::", &ch, &opt_arg) == APR_SUCCESS) { > switch (ch) { >@@ -218,7 +272,9 @@ > /* Our version of getopt doesn't allow for optional arguments. */ > ABTS_STR_EQUAL(tc, "option: a\n", str); > #endif >- ABTS_STR_EQUAL(tc, "testprog: option requires an argument -- a\n", str); >+ ABTS_STR_EQUAL(tc, "testprog: option requires an argument: a\n", str); >+ ABTS_STR_EQUAL(tc, "a", par); >+ ABTS_INT_EQUAL(tc, APR_GETOPT_MISSING_ARGUMENT, ed.errcode); > } > > abts_suite *testgetopt(abts_suite *suite)
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 56030
: 31227