summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog15
-rw-r--r--lib/long-options.c52
-rw-r--r--lib/long-options.h16
-rw-r--r--modules/long-options2
-rw-r--r--top/maint.mk2
5 files changed, 85 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index 3917f704c4..75dbeb0ff7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2019-02-23 Bernhard Voelker <mail@bernhard-voelker.de>
+
+ long-options: add parse_gnu_standard_options_only
+ Discussed in https://bugs.gnu.org/33468 .
+
+ * lib/long-options.c (parse_long_options): Use EXIT_SUCCESS instead of 0
+ (parse_gnu_standard_options_only): Add function to process
+ the GNU default options --help and --version and fail for
+ any other unknown long or short option. See
+ https://gnu.org/prep/standards/html_node/Command_002dLine-Interfaces.html
+ * lib/long-options.h (parse_gnu_standard_options_only): Declare it.
+ * modules/long-options (depends-on): Add stdbool, exitfail.
+ * top/maint.mk (sc_prohibit_long_options_without_use): Update
+ syntax-check rule, add new function name.
+
2019-02-23 Bruno Haible <bruno@clisp.org>
relocatable-prog: Update documentation.
diff --git a/lib/long-options.c b/lib/long-options.c
index 037f74b3a3..cbdc6a98bc 100644
--- a/lib/long-options.c
+++ b/lib/long-options.c
@@ -29,6 +29,7 @@
#include <getopt.h>
#include "version-etc.h"
+#include "exitfail.h"
static struct option const long_options[] =
{
@@ -71,7 +72,7 @@ parse_long_options (int argc,
va_list authors;
va_start (authors, usage_func);
version_etc_va (stdout, command_name, package, version, authors);
- exit (0);
+ exit (EXIT_SUCCESS);
}
default:
@@ -87,3 +88,52 @@ parse_long_options (int argc,
the probably-new parameters when/if getopt is called later. */
optind = 0;
}
+
+/* Process the GNU default long options --help and --version (see also
+ https://gnu.org/prep/standards/html_node/Command_002dLine-Interfaces.html),
+ and fail for any other unknown long or short option.
+ Use with SCAN_ALL=true to scan until "--", or with SCAN_ALL=false to stop
+ at the first non-option argument (or "--", whichever comes first). */
+void
+parse_gnu_standard_options_only (int argc,
+ char **argv,
+ const char *command_name,
+ const char *package,
+ const char *version,
+ bool scan_all,
+ void (*usage_func) (int),
+ /* const char *author1, ...*/ ...)
+{
+ int c;
+ int saved_opterr = opterr;
+
+ /* Print an error message for unrecognized options. */
+ opterr = 1;
+
+ const char *optstring = scan_all ? "" : "+";
+
+ if ((c = getopt_long (argc, argv, optstring, long_options, NULL)) != -1)
+ {
+ switch (c)
+ {
+ case 'h':
+ (*usage_func) (EXIT_SUCCESS);
+ break;
+
+ case 'v':
+ {
+ va_list authors;
+ va_start (authors, usage_func);
+ version_etc_va (stdout, command_name, package, version, authors);
+ exit (EXIT_SUCCESS);
+ }
+
+ default:
+ (*usage_func) (exit_failure);
+ break;
+ }
+ }
+
+ /* Restore previous value. */
+ opterr = saved_opterr;
+}
diff --git a/lib/long-options.h b/lib/long-options.h
index f4d6a83d57..13f17eccc2 100644
--- a/lib/long-options.h
+++ b/lib/long-options.h
@@ -17,6 +17,11 @@
/* Written by Jim Meyering. */
+#ifndef LONG_OPTIONS_H_
+# define LONG_OPTIONS_H_ 1
+
+# include <stdbool.h>
+
void parse_long_options (int _argc,
char **_argv,
const char *_command_name,
@@ -24,3 +29,14 @@ void parse_long_options (int _argc,
const char *_version,
void (*_usage) (int),
/* const char *author1, ...*/ ...);
+
+void parse_gnu_standard_options_only (int argc,
+ char **argv,
+ const char *command_name,
+ const char *package,
+ const char *version,
+ bool scan_all,
+ void (*usage_func) (int),
+ /* const char *author1, ...*/ ...);
+
+#endif /* LONG_OPTIONS_H_ */
diff --git a/modules/long-options b/modules/long-options
index f1106c3cc7..b845d42936 100644
--- a/modules/long-options
+++ b/modules/long-options
@@ -6,7 +6,9 @@ lib/long-options.h
lib/long-options.c
Depends-on:
+exitfail
getopt-gnu
+stdbool
stdlib
version-etc
diff --git a/top/maint.mk b/top/maint.mk
index 4e37efeb56..e9d5ee7d48 100644
--- a/top/maint.mk
+++ b/top/maint.mk
@@ -537,7 +537,7 @@ sc_prohibit_quote_without_use:
# Don't include this header unless you use one of its functions.
sc_prohibit_long_options_without_use:
- @h='long-options.h' re='\<parse_long_options *\(' \
+ @h='long-options.h' re='\<parse_(long_options|gnu_standard_options_only) *\(' \
$(_sc_header_without_use)
# Don't include this header unless you use one of its functions.