Reputation: 33
I am a newbie to TCL and I am trying to learn scripting on my own.
I am trying to parse a file and trying to separate each line first and then break down each line to each word. However, my execution ends giving me the following message:
DISPLAY: output = "TDO";
list element in quotes followed by ";" instead of space
while executing
"foreach word $line {
puts $word
}"
invoked from within
"if {[file exists default_xl.vif]} {
puts "\ndefault_xl.vif exists"
set fp [open "default_xl.vif" r]
#set file_data [read $fp]
#set lines [split ..."
(file "second.tcl" line 96)
Here is the piece of code which is causing the trouble:
while {[gets $fp line] > -1} {
set word_len [split $line "\n"]
puts -nonewline "DISPLAY: "
puts $line
foreach word $line {
puts $word
}
}
Here are the lines from the file which I am trying to parse:
input = "TMS" sync="fine_delay_clk";
output = "TDO";
output = "veloce_outclk";
The line which says "output = "TDO"" is the line which is causing the trouble.
I am not able to figure out what is wrong here since the lines previous to that line would work just fine but the ones which start with output doesn't work.
Can anyone please help here.
Upvotes: 3
Views: 8606
Reputation: 13252
Your problem is exactly what the error message says: a list element in quotes ("TDO"
) is followed by a semicolon. That's illegal list syntax. The line before that is fine because the word that ends in a semicolon (sync="fine_delay_clk";
) doesn't begin with a double quote. If you add whitespace around the equal sign, you will have trouble with that line too, if you try to use it as a list.
Split the line first, and it will work (assuming line
contains output = "TDO";
):
foreach word [split $line] {
puts $word
}
# output:
output
=
"TDO";
Note 1: this assumes that neither the name to the left of the equal sign, nor the string within the double quotes contain whitespace characters. If they do, you'll have to use another method, such as splitting on the equal sign.
Note 2: traversing the line as a list of words isn't really a good way to parse what seems to be attribute assignments. Code like this might be better (assuming every value is quoted, and that double quotes don't show up in values even as escaped quotes (\"
)):
foreach {- name value} [regexp -inline -all {(\w+)\s*=\s*"([^"]*)"} $line] {
puts "$name -- $value"
}
Or like this (assuming equal signs and semicolons never occur in names or values):
foreach {name value} [string map {= { } ; {}} $line] {
puts "$name -- $value"
}
But what the best method really is depends on your needs and requirements. In most cases, preprocessing of data must be customized to fit the actual data; in most cases it's easy to do so.
Note 3: Tcl isn't designed to hinder you. If you tell Tcl to apply list operations to data that isn't in pure list form, it will do its best and report back when it has to give up (you can of course ask first as well: string is list $line
will tell you if the string can be processed as a list). It's your responsibility to ensure that every piece of data you use is well-formed and semantically appropriate for the operations you want to perform on it. Luckily, that's a lot easier in Tcl than in some other languages.
Documentation: foreach, puts, regexp, split, string
Upvotes: 3