I want to the same thing in tcl as the following C code:
#define VAL_A 1
#define VAL_B 2
#define VAL_C 4
int x = VAL_A|VAL_C;
switch (x & (VAL_A|VAL_C)) {
case VAL_A: ... break;
case VAL_A|VAL_C: break;
}
the tcl code i tried was:
set VAL_A 1
set VAL_B 2
set VAL_C 4
switch -regexp expr( x & VAL_A|VAL_C) \
$VAL_A { } \
$VAL_C|$VAL_C {} \
but that did not work.
I think the usage on vars as const is wrong at first. But are there
named constants in tcl???
The second is that I could not avaluate expressions as case value...
Any hint?
Bye
Klaus
You probably want something like this:
switch -exact -- [expr {$x & ($VAL_A|$VAL_C)}] \
$VAL_A { ... } \
[expr {$VAL_A|$VAL_C}] { ... }
The next level of thought is to disconnect from representing things as
integers in the first place and instead look at other representations
that take advantage of the fact that strings are *the* fundamental
datatype of Tcl (by contrast, in C it's really the machine-word). That's
quite a change though, and probably requires a lot of reworking of the
rest of your program too.
Donal.
Oh, I don't know. I think:
switch -- $something {
FOO {
}
BAR {
}
}
is fairly close to the C:
#define FOO 1
#define BAR 2
switch (something) {
case FOO:
break;
case BAR:
break;
}
I re-remembered this recently writing some Tcl to parse 802.1D BPDUs:
...
binary scan $bpdu "S c c c a*" \
a(protocol) a(rstpVersion) a(type) a(flags) bpdu
if {$a(protocol) != 0 } {
error "Invalid protocol"
}
switch -- $a(type) {
0 {
set a(type) "CFG"
}
0x80 {
set a(type) "TCN"
}
2 {
set a(type) "RST"
}
default {
error "Unknown BPDU type"
}
}
...
Then the rest of my code and use the fairly natural and expressive
strings.
That'd be fine (even highly recommended), except he's switching on bit
patterns and not simple symbolic constants. That makes things much messier.
Donal.
What should that "$VAL_C|$VAL_C" mean?
Even the original
case VAL_A: ... break;
case VAL_A|VAL_C: break;
does not make much sense in that order (VAL_A will always trigger in
the first clause, the second will never run).
The "|" in C-case is best thought of as the
foo -
bar { }
in TCL-switch, so try
switch -- [expr {$x & ($VAL_A|$VAL_C)}] \
$VAL_A { puts VAL-A } \
SVAL_B - \
$VAL_C { puts "VAL-B (will never trigger) | VAL-C" }
Note: the precedence of & and | in TCl-expr are the same as in C, so
you need the same grouping in TCL-expr as in C-switch.
HTH
R'
Wrong. VAL_A|VAL_C is an expression with constant value 5, whereas VAL_A
on its own is an expression with constant value 1.
Donal.
Schelte.
--
set Reply-To [string map {nospam schelte} $header(From)]
... and by the time you're writing *this*, it's often natural to
consider the alternative of
array set my_lookup_table {0 CFG
0x80 TCN
2 RST}
set a(type) $my_lookup_table($a(type))
along with a bit of exception-handling.
Also, as Donal notes, bit-pattern-ing can make things messier.
That is what I want!
Thanks a lot!
Klaus