onaclov2000
onaclov2000

Reputation: 5841

How comments work in the context of a regexp switch statement

Ok, So I can't seem to figure out how on earth this works. The Attached code when ran results in an invalid command name " " while executing "\t" ("#" arm line 1) invoked from within "switch -regexp -- $line { "(and the rest of the file basically)

I ran into this problem and finally figured out the # was doing it, I tried escaping it using regsub (shown below). The only way I can get the string to parse is if I remove the # all together from the string (inputString changed to remove the # sign).

Based on the statement that TCL reads all lines as text (including commands) I could only assume that the string being read contained a # and couldn't complete the line and of course returned an error. However escaping (tried 1 \ and 2 \'s) didn't do anything to make it better All it did was add \ to all my other "non word chars" (I had -'s that worked fine, but now have \'s...:S)

If I Delete OR Uncomment out the switch section {^[ \t]TEST.$} the thing works fine.

I am modifying a script and was ignoring a particular couple cases, and decided to comment them out.

Can someone explain what on earth is happening, and what I can do to fix it? It appears that the .tcl file is still parsing the # sections even though they're comments, and getting confused.

Attempt to fix

regsub -all {\W} $line {\\&} line;

Code:

    proc doConversion fname {
    set inputString "* |# Bits\n*  # Bits \n";

    foreach line [split $inputString "\n"] { 
       switch -regexp  -- $line {
                # {^[ \t]*TEST.*$}
                # {
                   # # Do nothing
                # }
               default {

                       }
            }
       }

    }

doConversion "test"

Update: I did find this resource, which explains (to an extent) the confusing nature of comments but I guess I'm still not sure what I can do about it: "Why can I not place unmatched braces in Tcl comments".

Upvotes: 2

Views: 278

Answers (1)

ruakh
ruakh

Reputation: 183446

I'm not 100% clear on what you're trying to do, so I apologize in advance if this doesn't answer your question, but: the upshot is, # doesn't indicate a comment unless it's somewhere that a command is expected. For example, this:

switch -regexp a#b {
    # {
        echo 'a#b' contains '#'
    }
}

prints this:

'a#b' contains '#'

because the string a#b successfully matches the regex #.

Since $line contains #, your code:

       switch -regexp  -- $line {
                # {^[ \t]*TEST.*$}
                ...
            }

will run this command:

^[ \t]*TEST.*$

which (because of the square brackets) runs this command:

\t

so you get an error message telling you that "   " (i.e., the tab character) is an invalid command name.

If you want to disable one branch of a switch, you're better off wrapping it in a condition that will never be satisfied:

    proc doConversion fname {
    set inputString "* |# Bits\n*  # Bits \n";

    foreach line [split $inputString "\n"] { 
       switch -regexp  -- $line {
               this-regexp-will-never-match {
                  {^[ \t]*TEST.*$}
                  {
                   # # Do nothing
                  }
               }
               default {

                       }
            }
       }

    }

doConversion "test"

Upvotes: 4

Related Questions