2

I have an issue while trying to read a member of a list like \\server\directory The issue comes when I try to get this variable using the lindex command, that proceeds with TCL substitution, so the result is:

\serverdirectory

Then, I think I need to use a regsub command to avoid the backslash substitution, but I did not get the correct proceedure.

An example of what I want should be:

set mistring "\\server\directory"
regsub [appropriate regular expresion here]
puts "mistring: '$mistring'"  ==> "mistring: '\\server\directory'"

I have checked some posts around this, and keep the \\ is ok, but I still have problems when trying to keep always a single \ followed by any other character that could come here.

UPDATE: specific example. What I am actually trying to keep is the initial format of an element in a list. The list is received by an outer application. The original code is something like this:

set mytable $__outer_list_received
puts "Table: '$mytable'"
for { set i 0 } { $i < [llength $mitabla] } { incr i } {
   set row [lindex $mytable $i]
   puts "Row: '$row'"
   set elements [lindex $row 0]
   puts "Elements: '$elements'"
}

The output of this, in this case is:

Table: '{{
   address \\server\directory
   filename foo.bar
}}'
Row: '{
   address \\server\directory
   filename foo.bar
}'
Elements: '
   address \\server\directory
   filename foo.bar
'

So I try to get the value of address (in this specific case, \\server\directory) in order to write it in a configuration file, keeping the original format and data. I hope this clarify the problem.

estradjs
  • 175
  • 2
  • 16

3 Answers3

2

If you don't want substitutions, put the problematic string inside curly braces.

% puts "\\server\directory"
\serverdirectory

and it's not what you want. But

% puts {\\server\directory}
\\server\directory

as you need.

Marco Pallante
  • 3,923
  • 1
  • 21
  • 26
  • Tnaks for the answer, the problem is that I cannot print directly using the curly braces, as I receive this variable directly from a list using lindex. In this case, if I try to use puts with the variable name, the output is the variable name itself. Is there a way then, to print the content of the variable with {} using puts? This would of course be the simplest solution. – estradjs Oct 21 '13 at 13:56
  • Then, the problem is where your list is defined. As another example, if you use `lindex "l1 l2 \\server\directory l3" 2` it won't work; but if you use `lindex {l1 l2 \\server\directory l3} 2` it will. – Marco Pallante Oct 21 '13 at 14:02
  • I mean: somewhere in your program, you will have something like `set mylist [list l1 l2 \\server\directory l2]` and somewhere else, you have `lindex $mylist 3`. Then, if you use `set mylist [list l1 l2 {\\server\directory} l3]`, it will work. – Marco Pallante Oct 21 '13 at 14:04
  • You are totally right about that. Unfortunately, I don´t set the initial list directly on my programm, I don´t have the control of this list but receive it as a parameter from an outer application (and this is actually the issue...). Any ideas about it? Is there a way to read somehow different from lindex or avoid this backslash substitution? – estradjs Oct 21 '13 at 14:15
  • Are you sure the outer application sends the right value? Otherwise, please update your question with some code which explains how you read that value. – Marco Pallante Oct 21 '13 at 14:18
  • I have updated now with the specific code, hope this clarify my question. Thank you for your help! :) – estradjs Oct 21 '13 at 14:34
  • The rows aren't lists, they're strings. Use `split` on them. – potrzebie Oct 21 '13 at 14:37
  • How could I split in this case keeping the original format of this element? – estradjs Oct 21 '13 at 14:52
  • Make a copy, then split the copy :) – Marco Pallante Oct 21 '13 at 14:54
  • 1
    Just to clarify, the workaround was a mixture of your solutions. Of course, treating the list as a string (what it actually was) was the first step. Instead of spliting using the split command, I have used a regexp to solve it and avoid the annoying blank spaces elements and so on, here you have a post related to this issue: http://stackoverflow.com/questions/3020690/how-to-remove-unwanted-charecters-using-split-in-tcl Thank you for your help! :) – estradjs Oct 22 '13 at 06:51
0

Since this is fundamentally a problem on Windows (and Tcl always treats backslashes in double-quotes as instructions to perform escaping substitutions) you should consider a different approach (otherwise you've got the problem that the backslashes are gone by the time you can apply code to “fix” them). Luckily, you've got two alternatives. The first is to put the string in {braces} to disable substitutions, just like a C# verbatim string literal (but that uses @"this" instead). The second is perhaps more suitable:

set mistring [file nativename "//server/directory"]

That ensures that the platform native directory separator is used on Windows (and nowadays does nothing on other platforms; back when old MacOS9 was supported it was much more magical). Normally, you only need this sort of thing if you are displaying full pathnames to users (usually a bad idea, GUI-wise) or if you are passing the name to some API that doesn't like forward slashes (notably when going as an argument to a program via exec but there are other places where the details leak through, such as if you're using the dde, tcom or twapi packages).

Donal Fellows
  • 133,037
  • 18
  • 149
  • 215
0

A third, although ugly, option is to double the slashes. \\ instead of \, and \ instead of \, while using double quotes. When the substitution occurs it should give you what you want. Of course, this will not help much if you do the substitution a second time.