% glob \{f*
unmatched open-brace in file name
I believe this is a bug.
No. The manpage for glob indicates that {} are metacharacters for glob
(alternation), and that to have them literlly you must backslash them:
glob \\\{f*
should work.
-Alex
Is your program really coding a glob like that in it? Or is the real
situation something more like
puts "Type in a pattern to search for the file: "
read patt
glob $patt
and the user typed in "{f*" ?
If you are dealing with a hard coded string, then here's what I found:
$ touch {foo
$ tclsh8.6
% glob {f*
and tclsh waits for the ending } before passing something along to
glob.
% glob \{f*
unmatched open-brace in file name
% glob \\{f*
\{foo
% glob *
\{foo
So the \\ seems to work for the hard coding situation.
What I don't know how to handle is ensuring that things like this are
properly quoted within a
string. I played around a bit, and the quoting needs vary depending on
what is being done with the string. For instance, I can do
gets stdin str
glob $str
and I type in
abc"xyz
and that quotation mark doesn't cause a problem. But if I type in
abc{xyz
the gets works just fine - but the glob gets what you are seeing.
However, I can say
set a $str
and there isn't a problem with the fact there's a brace.
You can also use {\{f*}.
>
> What I don't know how to handle is ensuring that things like this are
> properly quoted within a
> string.
As Alexandre points out, the problem is not from Tcl, but from [glob] in
which "{" has a special meaning, e.g. you can write e.g. [glob
*.{exe,bat}] to match anything ending in either .exe or .bat. There
isn't really a way of avoiding such quoting issues in user-input, unless
you forbid them from entering those sorts of patterns (and quote all
braces). You could probably quote just un-balanced braces on the
assumption that they meant a literal brace.
-- Neil
[list] seems to quote things correctly:
$ cat 2
gets stdin pat
puts [glob $pat]
$ tclsh 2
{*
unmatched open-brace in file name
while executing
"glob $pat"
invoked from within
"puts [glob $pat]"
(file "2" line 2)
$ cat 3
gets stdin pat
puts [glob [list $pat]]
$ tclsh 3
{*
\{123
--
WL
real mail: wliao at sdf loSnPesAtarM org
(remove the uppercase letters...)
Don't guess when you can actually know ;-)
As it turns out, list and glob syntaxes agree on how to escape braces,
but that's about it. The rest is overgeneralization.
The only safe thing to do is to agree with the end-user on a set of
syntactic rules, and then explicitly handle the delta between these
rules and [glob]'s.
For example, if the user can be assumed to ascribe their usual (shell-
globbing) meaning to ?*[], but _not_ to {} (which is a csh dialect),
the mapping function should be:
regsub -all {[{}]} $in {\\&} out
-Alex
Hmm.. interesting. My problem is exactly that I'm parsing user input
and passing it to glob when hitting this behavior. Currently my
solution is to simply do a blind [catch {glob $arg}] and ignore the
error (and telling users that I don't support weird file names). But
now it looks like pre-filtering the argument to glob is a better idea.
Although, I do prefer:
set out [string map "{ \\{ } \\}" $in]
which to me is more 'obvious' (self documenting) and tend to be
slightly faster.
That should work as long as your software doesn't allow glob meta-use
of the { } combo as mentioned earlier in this thread ( [glob *.
{exe,bat}] ) .