mirror of
git://git.sv.gnu.org/autoconf
synced 2024-11-27 01:49:56 +08:00
Move case statement style discussion to m4 quoting section.
* doc/autoconf.texi (Limitations of Builtins): Move comparison of quoting styles... (Balancing Parentheses): ...to this new node. Suggested by Ralf Wildenhues. Signed-off-by: Eric Blake <ebb9@byu.net>
This commit is contained in:
parent
abe172f4ba
commit
54dd8a9379
@ -1,3 +1,11 @@
|
||||
2008-11-21 Eric Blake <ebb9@byu.net>
|
||||
|
||||
Move case statement style discussion to m4 quoting section.
|
||||
* doc/autoconf.texi (Limitations of Builtins): Move comparison of
|
||||
quoting styles...
|
||||
(Balancing Parentheses): ...to this new node.
|
||||
Suggested by Ralf Wildenhues.
|
||||
|
||||
2008-11-20 Eric Blake <ebb9@byu.net>
|
||||
|
||||
Factor more common code out of AT_CHECK into shell function.
|
||||
|
@ -445,6 +445,7 @@ M4 Quotation
|
||||
* Quotation and Nested Macros:: Macros calling macros
|
||||
* Changequote is Evil:: Worse than INTERCAL: M4 + changequote
|
||||
* Quadrigraphs:: Another way to escape special characters
|
||||
* Balancing Parentheses:: Dealing with unbalanced parentheses
|
||||
* Quotation Rule Of Thumb:: One parenthesis, one quote
|
||||
|
||||
Using @command{autom4te}
|
||||
@ -9292,6 +9293,7 @@ former helps one to follow the latter.
|
||||
* Quotation and Nested Macros:: Macros calling macros
|
||||
* Changequote is Evil:: Worse than INTERCAL: M4 + changequote
|
||||
* Quadrigraphs:: Another way to escape special characters
|
||||
* Balancing Parentheses:: Dealing with unbalanced parentheses
|
||||
* Quotation Rule Of Thumb:: One parenthesis, one quote
|
||||
@end menu
|
||||
|
||||
@ -9778,6 +9780,126 @@ invention, and I suppose it could have been a common pun around the
|
||||
Cambridge University computer lab at the time.
|
||||
@end quotation
|
||||
|
||||
|
||||
@node Balancing Parentheses
|
||||
@subsection Dealing with unbalanced parentheses
|
||||
@cindex balancing parentheses
|
||||
@cindex parentheses, balancing
|
||||
@cindex unbalanced parentheses, managing
|
||||
|
||||
One of the pitfalls of portable shell programming is that @command{case}
|
||||
statements require unbalanced parentheses (@pxref{Limitations of
|
||||
Builtins, , Limitations of Shell Builtins}). With syntax highlighting
|
||||
editors, the presence of unbalanced @samp{)} can interfere with editors
|
||||
that perform syntax highlighting of macro contents based on finding the
|
||||
matching @samp{(}. Another concern is how much editing must be done
|
||||
when transferring code snippets between shell scripts and macro
|
||||
definitions. But most importantly, the presence of unbalanced
|
||||
parentheses can introduce expansion bugs.
|
||||
|
||||
For an example, here is an underquoted attempt to use the macro
|
||||
@code{my_case}, which happens to expand to a portable @command{case}
|
||||
statement:
|
||||
|
||||
@example
|
||||
AC_DEFUN([my_case],
|
||||
[case $file_name in
|
||||
*.c) echo "C source code";;
|
||||
esac])
|
||||
AS_IF(:, my_case)
|
||||
@end example
|
||||
|
||||
@noindent
|
||||
In the above example, the @code{AS_IF} call underquotes its arguments.
|
||||
As a result, the unbalanced @samp{)} generated by the premature
|
||||
expansion of @code{my_case} results in expanding @code{AS_IF} with a
|
||||
truncated parameter, and the expansion is syntactically invalid:
|
||||
|
||||
@example
|
||||
if :; then
|
||||
case $file_name in
|
||||
*.c
|
||||
fi echo "C source code";;
|
||||
esac)
|
||||
@end example
|
||||
|
||||
If nothing else, this should emphasize the importance of the quoting
|
||||
arguments to macro calls. On the other hand, there are several
|
||||
variations for defining @code{my_case} to be more robust, even when used
|
||||
without proper quoting, each with some benefits and some drawbacks.
|
||||
|
||||
@itemize @asis
|
||||
@item Creative literal shell comment
|
||||
@example
|
||||
AC_DEFUN([my_case],
|
||||
[case $file_name in #(
|
||||
*.c) echo "C source code";;
|
||||
esac])
|
||||
@end example
|
||||
@noindent
|
||||
This version provides balanced parentheses to several editors, and can
|
||||
be copied and pasted into a terminal as is. Unfortunately, it is still
|
||||
unbalanced as an Autoconf argument, since @samp{#(} is an M4 comment
|
||||
that masks the normal properties of @samp{(}.
|
||||
|
||||
@item Quadrigraph shell comment
|
||||
@example
|
||||
AC_DEFUN([my_case],
|
||||
[case $file_name in @@%:@@(
|
||||
*.c) echo "C source code";;
|
||||
esac])
|
||||
@end example
|
||||
@noindent
|
||||
This version provides balanced parentheses to even more editors, and can
|
||||
be used as a balanced Autoconf argument. Unfortunately, it requires
|
||||
some editing before it can be copied and pasted into a terminal, and the
|
||||
use of the quadrigraph @samp{@@%:@@} for @samp{#} reduces readability.
|
||||
|
||||
@item Quoting just the parenthesis
|
||||
@example
|
||||
AC_DEFUN([my_case],
|
||||
[case $file_name in
|
||||
*.c[)] echo "C source code";;
|
||||
esac])
|
||||
@end example
|
||||
@noindent
|
||||
This version quotes the @samp{)}, so that it can be used as a balanced
|
||||
Autoconf argument. As written, this is not balanced to an editor, but
|
||||
it can be coupled with @samp{[#(]} to meet that need, too. However, it
|
||||
still requires some edits before it can be copied and pasted into a
|
||||
terminal.
|
||||
|
||||
@item Double-quoting the entire statement
|
||||
@example
|
||||
AC_DEFUN([my_case],
|
||||
[[case $file_name in #(
|
||||
*.c) echo "C source code";;
|
||||
esac]])
|
||||
@end example
|
||||
@noindent
|
||||
Since the entire macro is double-quoted, there is no problem with using
|
||||
this as an Autoconf argument; and since the double-quoting is over the
|
||||
entire statement, this code can be easily copied and pasted into a
|
||||
terminal. However, the double quoting prevents the expansion of any
|
||||
macros inside the case statement, which may cause its own set of
|
||||
problems.
|
||||
|
||||
@item Using @code{AS_CASE}
|
||||
@example
|
||||
AC_DEFUN([my_case],
|
||||
[AS_CASE([$file_name],
|
||||
[*.c], [echo "C source code"])])
|
||||
@end example
|
||||
@noindent
|
||||
This version avoids the balancing issue altogether, by relying on
|
||||
@code{AS_CASE} (@pxref{Common Shell Constructs}); it also allows for the
|
||||
expansion of @code{AC_REQUIRE} to occur prior to the entire case
|
||||
statement, rather than within a branch of the case statement that might
|
||||
not be taken. However, the abstraction comes with a penalty that it is
|
||||
no longer a quick copy, paste, and edit to get back to shell code.
|
||||
@end itemize
|
||||
|
||||
|
||||
@node Quotation Rule Of Thumb
|
||||
@subsection Quotation Rule Of Thumb
|
||||
|
||||
@ -14901,113 +15023,13 @@ $ @kbd{case foo in (foo) echo foo;; esac}
|
||||
@end example
|
||||
|
||||
@noindent
|
||||
@cindex balancing parentheses
|
||||
@cindex parentheses, balancing
|
||||
The leading @samp{(} can be omitted safely. Unfortunately, there are
|
||||
contexts where unbalanced parentheses cause other problems, such as when
|
||||
using a syntax-highlighting editor that searches for the balancing
|
||||
counterpart, or more importantly, when using a case statement as an
|
||||
underquoted argument to an Autoconf macro:
|
||||
|
||||
@example
|
||||
AC_DEFUN([my_case],
|
||||
[case $file_name in
|
||||
*.c) echo "C source code";;
|
||||
esac])
|
||||
AS_IF(:, my_case)
|
||||
@end example
|
||||
|
||||
@noindent
|
||||
In the above example, the unbalanced @samp{)} in the premature expansion
|
||||
of @code{my_case} results in expanding @code{AS_IF} with a truncated
|
||||
parameter, and the expansion is syntactically invalid:
|
||||
|
||||
@example
|
||||
if :; then
|
||||
case $file_name in
|
||||
*.c
|
||||
fi echo "C source code";;
|
||||
esac)
|
||||
@end example
|
||||
|
||||
@noindent
|
||||
If nothing else, this should emphasize the importance of the quoting
|
||||
rule of thumb (@pxref{Quotation Rule Of Thumb}), that you should single
|
||||
quote all macro arguments that might be re-expanded, and double-quote
|
||||
macro arguments that are literal text. On the other hand, there are
|
||||
several variations for defining @code{my_case} to be more robust, each
|
||||
with some benefits and some drawbacks.
|
||||
|
||||
@table @asis
|
||||
@item Creative literal shell comment
|
||||
@example
|
||||
AC_DEFUN([my_case],
|
||||
[case $file_name in #(
|
||||
*.c) echo "C source code";;
|
||||
esac])
|
||||
@end example
|
||||
@noindent
|
||||
This version provides balanced parentheses to several editors, and can
|
||||
be copied and pasted into a terminal as is. Unfortunately, it is still
|
||||
unbalanced as an Autoconf argument, since @samp{#(} is an M4 comment
|
||||
that masks the normal properties of @samp{(}.
|
||||
|
||||
@item Quadrigraph shell comment
|
||||
@example
|
||||
AC_DEFUN([my_case],
|
||||
[case $file_name in @@%:@@(
|
||||
*.c) echo "C source code";;
|
||||
esac])
|
||||
@end example
|
||||
@noindent
|
||||
This version provides balanced parentheses to even more editors, and can
|
||||
be used as a balanced Autoconf argument. Unfortunately, it requires
|
||||
some editing before it can be copied and pasted into a terminal, and the
|
||||
use of the quadrigraph @samp{@@%:@@} for @samp{#} reduces readability.
|
||||
|
||||
@item Quoting just the parenthesis
|
||||
@example
|
||||
AC_DEFUN([my_case],
|
||||
[case $file_name in
|
||||
*.c[)] echo "C source code";;
|
||||
esac])
|
||||
@end example
|
||||
@noindent
|
||||
This version quotes the @samp{)}, so that it can be used as a balanced
|
||||
Autoconf argument. As written, this is not balanced to an editor, but
|
||||
it can be coupled with @samp{[#(]} to meet that need, too. However, it
|
||||
still requires some edits before it can be copied and pasted into a
|
||||
terminal.
|
||||
|
||||
@item Double-quoting the entire statement
|
||||
@example
|
||||
AC_DEFUN([my_case],
|
||||
[[case $file_name in #(
|
||||
*.c) echo "C source code";;
|
||||
esac]])
|
||||
@end example
|
||||
@noindent
|
||||
Since the entire macro is double-quoted, there is no problem with using
|
||||
this as an Autoconf argument; and since the double-quoting is over the
|
||||
entire statement, this code can be easily copied and pasted into a
|
||||
terminal. However, the double quoting prevents the expansion of any
|
||||
macros inside the case statement, which may cause its own set of
|
||||
problems.
|
||||
|
||||
@item Using @code{AS_CASE}
|
||||
@example
|
||||
AC_DEFUN([my_case],
|
||||
[AS_CASE([$file_name],
|
||||
[*.c], [echo "C source code"])])
|
||||
@end example
|
||||
@noindent
|
||||
This version avoids the balancing issue altogether, by relying on
|
||||
@code{AS_CASE} (@pxref{Common Shell Constructs}); it also allows for the
|
||||
expansion of @code{AC_REQUIRE} to occur prior to the entire case
|
||||
statement, rather than within a branch of the case statement that might
|
||||
not be taken. However, the abstraction comes with a penalty that it is
|
||||
no longer a quick copy, paste, and edit to get back to shell code.
|
||||
@end table
|
||||
underquoted argument to an Autoconf macro. @xref{Balancing
|
||||
Parentheses}, for tradeoffs involved in various styles of dealing with
|
||||
unbalanced @samp{)}.
|
||||
|
||||
Zsh handles pattern fragments derived from parameter expansions or
|
||||
command substitutions as though quoted:
|
||||
|
Loading…
Reference in New Issue
Block a user