Reputation: 1008
I am writing code to generate Tcl script, it generates script that includes "puts {blah}".
But the script will fail if I try to puts {
or }
. I thought the escape is '\' but it didn't work:
% puts {}}
extra characters after close-brace
% puts {\}}
\}
% puts {\{}
\{
puts{{}
also does not work but puts{{}}
works.
Similarly, if \
is the last character of the string, the command will not complete.
I have checked the 12 rules of Tcl (http://www.tcl.tk/man/tcl8.5/TclCmd/Tcl.htm) but I don't see a solution to my problem.
Upvotes: 0
Views: 3866
Reputation: 129
% puts \{\}\}
{}}
% puts \{\{\}
{{}
% puts this\ is\ it\ {\}\}
this is it {}}
This may help you I just used the concept of the @Peter Lewerin
Upvotes: 0
Reputation: 137787
Braces can quote most things, but cannot quote unbalanced braces. That's when you have to stop using braces for quoting and do it all with backslashes (which can quote anything, but which are annoying and ugly). Indeed, that's what Tcl's own list-quoting engine does.
# Double quotes can quote things in some cases.
set a "This is{ an example"
set b "and so }is this"
puts [list $a $b]
This\ is\{\ an\ example and\ so\ \}is\ this
If you're generating commands, you're strongly advised to use list
to do it, or the equivalent code at the C level, which is hooked in behind Tcl_NewListObj()
and friends. It gets this sort of thing right so you don't have to. (It also has some performance optimisations when it comes to execution as a bonus.)
Upvotes: 2
Reputation: 13282
If you are going to read an input stream that might contain unbalanced braces and use the text on that stream for scripted output you are going to have to either a) count braces and balance them somehow, or b) use double quotes. If the input stream contains double quote characters it's quite easy to string map
them to escaped double quotes.
You might also get some mileage out of the list
command, which is quite clever with escaping. If your input is foo }bar [baz]
, stored in the variable foo
, you can use the command puts [list puts $foo]
to output the script
puts foo\ \}bar\ \[baz\]
which reproduces the input.
Another solution, if noone needs to read the generated scripts, is to convert every character into a character code, so that foo} bar
becomes e.g. \x66\x6f\x6f\x7d\x20\x62\x61\x72
(which can be output directly). One can of course exclude alphanumerics from this conversion to preserve some readability. The main point of this exercise is that you don't need any quoting at all.
There are probably more elegant methods as well, but without knowing your data it's hard to make good suggestions.
Upvotes: 0
Reputation: 16436
As per rule, braces should be balanced and anything placed in between braces will be treated literally. These are the ones causing this behaviour for you.
% puts "{"
{
% puts "}"
}
% puts "{{}"
{{}
%
Use double quotes for enclosing the string.
Upvotes: 0