foreach - tcl data formats confusion -
the motivation behind question learning...
i have done tcl programming , have working code, not understand why syntax working , not.
problem description: i'm writing code needs set voltages power , ground nets. after enter vdd nets string,
set power_nets "vdd=1.1 vdda=1.2 vref=1.1"
then simple tcl code should construct , execute following commands:
set_vdd vdd 1.1 set_vdd vdda 1.2 set_vdd vref 1.1
that all. seems trivial, have had difficulty implementing it. still not understand why code not work, although seems correct me.
working solution: working solution came following:
foreach item [split $power_nets] { set net [lindex [split $item =] 0] set voltage [lindex [split $item =] 1] set_vdd $net $voltage }
that's lot of code such simple operation. when written in more condensed form still works:
foreach item [split $power_nets] { set_vdd [lindex [split $item =] 0] [lindex [split $item =] 1] }
but still have feeling there room improvement here.
learning objective: settle solution optimal code (it both short , comprehensive)
foreach item [split $power_nets] { set_vdd [split $item =] }
unfortunately not work. tool interprets set_vdd command complains that
no value given parameter "voltage" (use -help full usage) :
i not understand why not work. difference?
when replace set_vdd
puts
, print values. information there. isn't it?
nlv12345@acc3081 char_out_logs $ tclsh % set power_nets "vdd=1.1 vdda=1.2 vref=1.1" vdd=1.1 vdda=1.2 vref=1.1 % foreach item [split $power_nets] { puts [split $item =] } vdd 1.1 vdda 1.2 vref 1.1 %
the error message less optimal, problem you're passing 2 words out of split
single argument set_vdd
.
if tcl interpreter currently-supported version, can instead this:
foreach item [split $power_nets] { set_vdd {*}[split $item =] }
the {*}
marker “take list — rest of word — , split separate arguments”. while it's formally not operator rather syntactic part of tcl language, calling “expansion operator” won't confuse lot.
older, unsupported versions of tcl (8.4 , before) require use of eval
this. you're ok with:
foreach item [split $power_nets] { eval set_vdd [split $item =] }
but safer this:
foreach item [split $power_nets] { eval [linsert [split $item =] 0 set_vdd] }
as can see, {*}
simplifies things quite bit.
however, i'd this:
foreach {item key value} [regexp -all -inline {(\w+)=([\d.]+)} $power_nets] { set_vdd $key $value }
like that, unexpected things in power_nets
value won't cause trouble. otoh, if you're not used regular expressions perhaps not time start regexp
…
Comments
Post a Comment