autoconf-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Document, test, and fix AT_ARG_OPTION, AT_ARG_OPTION_ARG.


From: Ralf Wildenhues
Subject: Document, test, and fix AT_ARG_OPTION, AT_ARG_OPTION_ARG.
Date: Wed, 16 Jun 2010 07:09:42 +0200
User-agent: Mutt/1.5.20 (2010-04-22)

Undocumented good features are a waste of goodness!  :-)

I'm not sure in which way this code may overlap, conflict, or profit
from, Gary's option parsing endeavor, but a code search showed me that
the macros are used in third-party code already, so might as well get
these right.  Sorry if there is duplication, this came from 2003.

Aliases to an option have always needed to be space-separated in the
first argument, so that isn't an incompatible change.  The - to _
translation was broken, too.  And the --noOPTION seemed extremely
ugly and inconsistent with the rest of GNU option handling.

Probably, other non-alphanumeric characters should be accepted in option
names, too, and all translated to underscore.  I haven't fixed that.

This is my last Autotest patch for now, besides the pending color one.

Thanks,
Ralf

    Document, test, and fix AT_ARG_OPTION, AT_ARG_OPTION_ARG.
    
    * lib/autotest/general.m4 (_AT_ARG_OPTION): Fix translation of
    hyphens to underscores when turning option names to variables.
    Avoid macro name concatenation garbage with trailing `dnl'.
    (AT_ARG_OPTION, AT_ARG_OPTION_ARG): Overhaul macro description.
    The OPTIONS are space-separated, not comma-separated.  The
    negative form of AT_ARG_OPTION is prefixed with `--no-'.
    * tests/autotest.at (AT@&address@hidden, AT@&address@hidden):
    New tests.
    * NEWS: Update.
    * doc/autoconf.texi (Writing Testsuites): Document AT_ARG_OPTION
    and AT_ARG_OPTION_ARG.
    (testsuite Invocation): Call the thingies passed to the
    testsuite options, not arguments.  Note that the testsuite author
    may add further package-specific options.

diff --git a/NEWS b/NEWS
index 3e1155c..f2290a1 100644
--- a/NEWS
+++ b/NEWS
@@ -31,6 +31,11 @@ GNU Autoconf NEWS - User visible changes.
 ** In configure scripts, loading CONFIG_SITE no longer searches PATH,
    and problems in loading the configuration site files are diagnosed.
 
+** The previously undocumented Autotest macros AT_ARG_OPTION and
+   AT_ARG_OPTION_ARG have seen bug fixes and are documented now.
+   AT_ARG_OPTION has been changed in that the negative of a long option
+   --OPTION is now --no-OPTION rather than --noOPTION.
+
 * Major changes in Autoconf 2.65 (2009-11-21) [stable]
   Released by Eric Blake, based on git versions 2.64.*.
 
diff --git a/doc/autoconf.texi b/doc/autoconf.texi
index 6d6555c..1acf7d0 100644
--- a/doc/autoconf.texi
+++ b/doc/autoconf.texi
@@ -23408,6 +23408,66 @@ Writing Testsuites
 @command{testsuite} and in @samp{testsuite --version}.
 @end defmac
 
address@hidden AT_ARG_OPTION (@var{options}, @var{help-text}, @
+  @ovar{action-if-given}, @ovar{action-if-not-given})
address@hidden
+Accept options from the space-separated list @var{options}, a list that
+has leading dashes removed from the options.  Long options will be
+prefixed with @samp{--}, single-character options with @samp{-}.  The
+first word in this list is the primary @var{option}, any others are
+assumed to be short-hand aliases.  The variable associated with it
+is @address@hidden, with any dashes in @var{option} replaced
+with underscores.
+
+If the user passes @address@hidden to the @command{testsuite},
+the variable will be set to @samp{:}.  If the user does not pass the
+option, or passes @address@hidden, then the variable will be
+set to @samp{false}.
+
address@hidden is run each time the option is encountered; here,
+the variable @code{at_optarg} will be set to @samp{:} or @samp{false} as
+appropriate.  @code{at_optarg} is actually just a copy of
address@hidden@var{option}}.
+
address@hidden will be run once after option parsing is
+complete and if no option from @var{options} was used.
+
address@hidden is added to the end of the list of options shown in
address@hidden --help} (@pxref{AS_HELP_STRING}).
+
+It it recommended that you use a package-specific prefix to @var{options}
+names in order to avoid clashes with future Autotest built-in options.
address@hidden defmac
+
address@hidden AT_ARG_OPTION_ARG (@var{options}, @var{help-text}, @
+  @ovar{action-if-given}, @ovar{action-if-not-given})
address@hidden
+Accept options with arguments from the space-separated list
address@hidden, a list that has leading dashes removed from the options.
+Long options will be prefixed with @samp{--}, single-character options
+with @samp{-}.  The first word in this list is the primary @var{option},
+any others are assumed to be short-hand aliases.  The variable associated
+with it is @address@hidden, with any dashes in @var{option}
+replaced with underscores.
+
+If the user passes @address@hidden@var{arg}} or
address@hidden@var{option} @var{arg}} to the @command{testsuite}, the
+variable will be set to @address@hidden
+
address@hidden is run each time the option is encountered; here,
+the variable @code{at_optarg} will be set to @address@hidden
address@hidden is actually just a copy of @address@hidden
+
address@hidden will be run once after option parsing is
+complete and if no option from @var{options} was used.
+
address@hidden is added to the end of the list of options shown in
address@hidden --help} (@pxref{AS_HELP_STRING}).
+
+It it recommended that you use a package-specific prefix to @var{options}
+names in order to avoid clashes with future Autotest built-in options.
address@hidden defmac
+
 @defmac AT_TESTED (@var{executables})
 @atindex{TESTED}
 Log the file name and answer to @option{--version} of each program in
@@ -23679,7 +23739,7 @@ testsuite Invocation
 @section Running @command{testsuite} Scripts
 @cindex @command{testsuite}
 
-Autotest test suites support the following arguments:
+Autotest test suites support the following options:
 
 @table @option
 @item --help
@@ -23817,6 +23877,12 @@ testsuite Invocation
 Trigger shell tracing of the test groups.
 @end table
 
+Besides these options accepted by every Autotest testsuite, the
+testsuite author might have added package-specific options
+via the @code{AT_ARG_OPTION} and @code{AT_ARG_OPTION_ARG} macros
+(@pxref{Writing Testsuites}); refer to @command{testsuite --help} and
+the package documentation for details.
+
 
 @node Making testsuite Scripts
 @section Making @command{testsuite} Scripts
diff --git a/lib/autotest/general.m4 b/lib/autotest/general.m4
index 5f965fd..0bc529f 100644
--- a/lib/autotest/general.m4
+++ b/lib/autotest/general.m4
@@ -1637,8 +1637,10 @@ m4_ifdef([AT_case_no],[m4_undefine([AT_case_no])])dnl
 m4_ifdef([AT_case_arg],[m4_undefine([AT_case_arg])])dnl
 m4_foreach([AT_option], m4_split(m4_normalize([$1]),[[ \|]+]),
 [m4_define_default([AT_first_option],AT_option)dnl
+m4_define_default([AT_first_option_tr],
+                 [m4_bpatsubst(m4_defn([AT_first_option]), -, _)])dnl
 m4_append([AT_case],m4_if(m4_len(AT_option),1,[],[-])[-]AT_option, [ | ])dnl
-m4_append([AT_case_no],[--no]AT_option, [ | ])dnl
+m4_append([AT_case_no],[--no-]AT_option, [ | ])dnl
 m4_append([AT_case_arg],
          m4_if(m4_len(AT_option),1,[],[-])[-]AT_option[=*], [ | ])dnl
 ])dnl m4_foreach AT_option
@@ -1651,31 +1653,31 @@ m4_divert_once([PARSE_ARGS_BEGIN],
 ])dnl
 m4_divert_text([PARSE_ARGS_BEGIN],
 [dnl Provide a default value for options without arguments.
-m4_ifvaln([$3],,[at_arg_[]m4_bpatsubst([AT_first_option], -, _)=false])dnl
-at_arg_given_[]m4_bpatsubst([AT_first_option], -, _)=false
+m4_ifvaln([$3],,[at_arg_[]AT_first_option_tr=false])dnl
+at_arg_given_[]AT_first_option_tr=false
 ])dnl m4_divert_text DEFAULTS
 m4_divert_text([PARSE_ARGS],
 [dnl Parse the options and args when necessary.
 m4_ifvaln([$3],
 [    AT_case )
-       at_prev=--m4_bpatsubst([AT_first_option], -, _)
+       at_prev=--AT_first_option_tr
        ;;
     AT_case_arg )
-       at_arg_[]m4_bpatsubst([AT_first_option], -, _)=$at_optarg
-       at_arg_given_[]m4_bpatsubst([AT_first_option], -, _)=:
+       at_arg_[]AT_first_option_tr=$at_optarg
+       at_arg_given_[]AT_first_option_tr=:
        $4
        ;;],
 [    AT_case )
        at_optarg=:
-       at_arg_[]m4_bpatsubst([AT_first_option], -, _)=:
-       at_arg_given_[]m4_bpatsubst([AT_first_option], -, _)=:
-       m4_ifval([$4],[$4])dnl
+       at_arg_[]AT_first_option_tr=:
+       at_arg_given_[]AT_first_option_tr=:
+       m4_ifval([$4],[$4])[]dnl
        ;;
     AT_case_no )
        at_optarg=false
-       at_arg_[]m4_bpatsubst([AT_first_option], -, _)=false
-       at_arg_given_[]m4_bpatsubst([AT_first_option], -, _)=:
-       m4_ifval([$4],[$4])dnl
+       at_arg_[]AT_first_option_tr=false
+       at_arg_given_[]AT_first_option_tr=:
+       m4_ifval([$4],[$4])[]dnl
        ;;])dnl m4_ifvaln $3
 ])dnl m4_divert_text PARSE_ARGS
 m4_ifvaln([$5],
@@ -1686,7 +1688,7 @@ m4_ifvaln([$5],
 ##])dnl m4_divert_once PARSE_ARGS_END
 m4_divert_text([PARSE_ARGS_END],
 [
-AS_IF([$at_arg_given_[]m4_bpatsubst([AT_first_option], -, _)],,[$5])dnl
+AS_IF([$at_arg_given_[]AT_first_option_tr],,[$5])dnl
 ])dnl m4_divert_text PARSE_ARGS_END
 ])dnl m4_ifvaln $5
 ])dnl _AT_ARG_OPTION
@@ -1694,41 +1696,42 @@ AS_IF([$at_arg_given_[]m4_bpatsubst([AT_first_option], 
-, _)],,[$5])dnl
 
 # AT_ARG_OPTION(OPTIONS,HELP-TEXT,[ACTION-IF-GIVEN],[ACTION-IF-NOT-GIVEN])
 # ------------------------------------------------------------------------
-# Accept a set of OPTIONS with arguments.  Add HELP-TEXT to the HELP_OTHER
-# diversion.
+# Accept a list of space-separated OPTIONS, all aliases of the first one.
+# Add HELP-TEXT to the HELP_OTHER diversion.
 #
-# Preceding dashes should not be passed into OPTIONS.  Users will be required
+# Leading dashes should not be passed in OPTIONS.  Users will be required
 # to pass `--' before long options and `-' before single character options.
 #
 # $at_arg_OPTION will be set to `:' if this option is received, `false' if
-# if --noOPTION is received, and `false' by default.
+# if --no-OPTION is received, and `false' by default.
 #
-# Run ACTION-IF-GIVEN each time an option in OPTIONS is encountered with
-# $at_optarg set to `:' or `false' as appropriate.  $at_optarg is actually
-# just a copy of $at_arg_OPTION.
+# Run ACTION-IF-GIVEN each time an option in OPTIONS is encountered; here,
+# $at_optarg will be set to `:' or `false' as appropriate.  $at_optarg is
+# actually just a copy of $at_arg_OPTION.
 #
-# ACTION-IF-NOT-GIVEN will be run once after option parsing is complete
-# if no option from OPTIONS was found.
+# ACTION-IF-NOT-GIVEN will be run once after option parsing is complete and
+# if no option from OPTIONS was used.
 m4_defun([AT_ARG_OPTION],[_AT_ARG_OPTION([$1],[$2],,[$3],[$4])])
 
 
 # AT_ARG_OPTION_ARG(OPTIONS,HELP-TEXT,[ACTION-IF-GIVEN],[ACTION-IF-NOT-GIVEN])
 # ----------------------------------------------------------------------------
-# Accept a set of OPTIONS with arguments, seperated by commas.  Add HELP-TEXT
-# to the HELP_OTHER diversion.
+# Accept a set of space-separated OPTIONS with arguments, all aliases of the
+# first one.  Add HELP-TEXT to the HELP_OTHER diversion.
 #
-# Preceding dashes should not be passed into OPTIONS.  Users will be required
+# Leading dashes should not be passed in OPTIONS.  Users will be required
 # to pass `--' before long options and `-' before single character options.
 #
 # By default, any argument to these options will be assigned to the shell
 # variable $at_arg_OPTION, where OPTION is the first option in OPTIONS with
 # any `-' characters replaced with `_'.
 #
-# Run ACTION-IF-GIVEN each time an option in OPTIONS is encountered with
-# $at_optarg set.  $at_optarg is actually just a copy of $at_arg_OPTION.
+# Run ACTION-IF-GIVEN each time an option in OPTIONS is encountered; here,
+# $at_optarg will be set to the option argument.  $at_optarg is actually just
+# a copy of $at_arg_OPTION.
 #
 # ACTION-IF-NOT-GIVEN will be run once after option parsing is complete
-# if no option from OPTIONS was found.
+# and if no option from OPTIONS was used.
 m4_defun([AT_ARG_OPTION_ARG],[_AT_ARG_OPTION([$1],[$2],1,[$3],[$4])])
 
 
diff --git a/tests/autotest.at b/tests/autotest.at
index ad38b7a..e09e189 100644
--- a/tests/autotest.at
+++ b/tests/autotest.at
@@ -1127,6 +1127,109 @@ AT_CHECK_KEYS([-l], [.{80}], [1], [.{87}], [0])
 
 AT_CLEANUP
 
+
+## ------------- ##
+## AT_ARG_OPTION ##
+## ------------- ##
+
+AT_CHECK_AT([AT@&address@hidden,
+[[
+AT_INIT([artificial test suite])
+AT_ARG_OPTION([frob fro fr f],
+              [AS_HELP_STRING([-f, --frob], [frobnicate the test run])],
+             [frob=$at_optarg], [frob=default])
+AT_ARG_OPTION([opt-with-hyphen],
+              [AS_HELP_STRING([--opt-with-hyphen], [option name with hypen])])
+AT_ARG_OPTION([ping],
+             [AS_HELP_STRING([--ping], [ping on every encounter])],
+             [echo ping])
+AT_SETUP([test argument handling])
+AT_CHECK([test "$frob" = "$FROB"])
+AT_CHECK([test "$at_arg_frob" = "$FROB_ARG"])
+AT_CLEANUP
+AT_SETUP([test hyphen normalization])
+AT_CHECK([test "$at_arg_opt_with_hyphen" = "$expected"])
+AT_CLEANUP
+]],
+[], [], [stdout], [], [],
+[# We already invoked --help.
+AT_CHECK([grep '  -f, --frob.*frobnicate' stdout], [], [ignore])
+for args in \
+  '1 FROB=default FROB_ARG=false' \
+  '1 -f FROB=: FROB_ARG=:' \
+  '1 --fr FROB=: FROB_ARG=:' \
+  '1 --fro FROB=: FROB_ARG=:' \
+  '1 --frob FROB=: FROB_ARG=:' \
+  '1 --no-f FROB=false FROB_ARG=false' \
+  '1 --no-fr FROB=false FROB_ARG=false' \
+  '1 --no-fro FROB=false FROB_ARG=false' \
+  '1 --no-frob FROB=false FROB_ARG=false' \
+  '2 expected=false' \
+  '2 --opt-with-hyphen expected=:' \
+  '2 --no-opt-with-hyphen expected=false'
+do
+  AT_CHECK([$CONFIG_SHELL ./micro-suite -x $args], [], [ignore])
+done
+AT_CHECK([$CONFIG_SHELL ./micro-suite 2 --ping --no-ping --ping 
expected=false],
+        [], [stdout])
+AT_CHECK([grep -c ping stdout], [], [[3
+]])
+], [--help])
+
+
+## ----------------- ##
+## AT_ARG_OPTION_ARG ##
+## ----------------- ##
+
+AT_CHECK_AT([AT@&address@hidden,
+[[
+AT_INIT([artificial test suite])
+AT_ARG_OPTION_ARG([frob fro fr f],
+                 [AS_HELP_STRING([-f, --frob=FOO], [frobnicate FOO])],
+                 [frob=$at_optarg], [frob=default])
+AT_ARG_OPTION_ARG([opt-with-hyphen],
+                 [AS_HELP_STRING([--opt-with-hyphen=ARG],
+                                 [option name with hypen])])
+AT_ARG_OPTION_ARG([ping],
+                 [AS_HELP_STRING([--ping], [ping on every encounter])],
+                 [echo ping])
+AT_SETUP([test argument handling])
+AT_CHECK([test "$frob" = "$FROB"])
+AT_CHECK([test "$at_arg_frob" = "$FROB_ARG"])
+AT_CLEANUP
+AT_SETUP([test hyphen normalization])
+AT_CHECK([test "$at_arg_opt_with_hyphen" = "$expected"])
+AT_CLEANUP
+]],
+[], [], [stdout], [], [],
+[# We already invoked --help.
+AT_CHECK([grep '  -f, --frob.*frobnicate' stdout], [], [ignore])
+AT_CHECK([$CONFIG_SHELL ./micro-suite -x --frob], [1], [ignore], [stderr])
+AT_CHECK([grep 'requires an argument' stderr], [], [ignore])
+AT_CHECK([$CONFIG_SHELL ./micro-suite -x --no-frob], [1], [ignore], [stderr])
+AT_CHECK([grep 'invalid option' stderr], [], [ignore])
+for args in \
+  '1 FROB=default FROB_ARG=' \
+  '1 -f bar FROB=bar FROB_ARG=bar' \
+  '1 --fr bar FROB=bar FROB_ARG=bar' \
+  '1 --fro bar FROB=bar FROB_ARG=bar' \
+  '1 --frob bar FROB=bar FROB_ARG=bar' \
+  '1 -f=bar FROB=bar FROB_ARG=bar' \
+  '1 --fr=bar FROB=bar FROB_ARG=bar' \
+  '1 --fro=bar FROB=bar FROB_ARG=bar' \
+  '1 --frob=bar FROB=bar FROB_ARG=bar' \
+  '2 expected=' \
+  '2 --opt-with-hyphen=baz expected=baz'
+do
+  AT_CHECK([$CONFIG_SHELL ./micro-suite -x $args], [], [ignore])
+done
+AT_CHECK([$CONFIG_SHELL ./micro-suite 2 --ping=1 --ping=2 expected=],
+        [], [stdout])
+AT_CHECK([grep -c ping stdout], [], [[2
+]])
+], [--help])
+
+
 m4_define([AT_SKIP_PARALLEL_TESTS],
 [# Per BUGS, we have not yet figured out how to run parallel tests cleanly
 # under dash and some ksh variants.  For now, only run this test under



reply via email to

[Prev in Thread] Current Thread [Next in Thread]