[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: extglobs in case constructs
From: |
Martin von Gagern |
Subject: |
Re: extglobs in case constructs |
Date: |
Thu, 01 Oct 2009 18:28:08 +0200 |
User-agent: |
Thunderbird 2.0.0.23 (X11/20090827) |
Martin von Gagern wrote:
> I've found out that extglobs behave differently in different
> constructs. To avoid syntax errors, the always have to be
> enabled at parse time.
> For comparison constructs like ``[[ $v == a@(a|b|c)c ]]'' this
> is enough. For case constructs like ``case $v in a@(a|b|c)c)''
> the extglob shopt has to be set at runtime as well. This is kind
> of inconsistent.
OK, I guess this is due to the following difference:
execute_cmd.c:3225-3231 in execute_cond_node:
> int oe;
> oe = extended_glob;
> extended_glob = 1;
> result = binary_test (cond->op->word, arg1, arg2,
> TEST_PATMATCH|TEST_ARITHEXP)
> ? EXECUTION_SUCCESS
> : EXECUTION_FAILURE;
> extended_glob = oe;
execute_cmd.c:2931 in execute_case_command:
> match = strmatch (pattern, word, FNMATCH_EXTFLAG|FNMATCH_IGNCASE) !=
> FNM_NOMATCH;
What's interesting is what you don't see here: the case command doesn't
temporarily set extended_glob to 1 as the cond node does. I guess this
is where the different behaviour at runtime comes from.
Is this difference intentionally, or is this a bug? If it is a bug, the
attached patch should fix it, although it might introduce other issues.
At least for my example script, the patch does its job.
I'm a bit surprised that execute_cond_node seems to unconditionally
enable the extended glob mode. I don't see any check whether the thing
has been parsed as an extended glob in the first place.
Is this because things that look like extended globs will always be
invalid syntax if extglob is off? So that if anything got parsed
successfully and still looks like an extended glob, the code can be sure
it was parsed as an extended glob? In that case, is there any point in
not always enabling extended globs, except if you are testing the
portability of your script? If so, I'll second the request to always
enable them, but I have some doubts that's the case.
As an alternative to my patch, one could maybe move all this temporary
extglob stuff to the function definitions. I.e. a function defined with
extglob on will also have extglob on when executed, and vice versa. This
might break some compatibility, though, especially for subshells. And
simply saving and restoring functins by listing their definition would
become a trouble as well. So it's just a thought so far.
Greetings,
Martin
Allow use of extended globs in case constructs at runtime,
even if the extglob shopt is not set.
2009-10-01 Martin von Gagern
References:
http://thread.gmane.org/gmane.comp.shells.bash.bugs/13518
Index: bash-4.0/execute_cmd.c
===================================================================
--- bash-4.0.orig/execute_cmd.c
+++ bash-4.0/execute_cmd.c
@@ -2915,6 +2915,7 @@ execute_case_command (case_command)
QUIT;
for (list = clauses->patterns; list; list = list->next)
{
+ int oe;
es = expand_word_leave_quoted (list->word, 0);
if (es && es->word && es->word->word && *(es->word->word))
@@ -2928,8 +2929,11 @@ execute_case_command (case_command)
/* Since the pattern does not undergo quote removal (as per
Posix.2, section 3.9.4.3), the strmatch () call must be able
to recognize backslashes as escape characters. */
+ oe = extended_glob;
+ extended_glob = 1;
match = strmatch (pattern, word, FNMATCH_EXTFLAG|FNMATCH_IGNCASE) !=
FNM_NOMATCH;
free (pattern);
+ extended_glob = oe;
dispose_words (es);