F.1.6 Dealing with unbalanced parentheses

One of the pitfalls of portable shell programming is that case
statements require unbalanced parentheses (see Limitations of
Shell Builtins). With syntax highlighting
editors, the presence of unbalanced ‘)’ can interfere with editors
that perform syntax highlighting of macro contents based on finding the
matching ‘(’. 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
my_case, which happens to expand to a portable case
statement:

In the above example, the AS_IF call underquotes its arguments.
As a result, the unbalanced ‘)’ generated by the premature
expansion of my_case results in expanding AS_IF with a
truncated parameter, and the expansion is syntactically invalid:

if :; then
case $file_name in
*.c
fi echo "C source code";;
esac)

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 my_case to be more robust, even when used
without proper quoting, each with some benefits and some drawbacks.

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 ‘#(’ is an M4 comment
that masks the normal properties of ‘(’.

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 ‘@%:@’ for ‘#’ reduces readability.

This version quotes the ‘)’, 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 ‘[#(]’ to meet that need, too. However, it
still requires some edits before it can be copied and pasted into a
terminal.

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.

This version avoids the balancing issue altogether, by relying on
AS_CASE (see Common Shell Constructs); it also allows for the
expansion of 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.