Quickest way to evaluate a variable in TCL - reference

I have a variable myref set to:
set myref {$expect_out(buffer)}
What is the quickest way to get the $expect_out(buffer) into myval?
set myval [HOWTOEVAL $myref]

If you have a string containing just the name of a variable, you are best off using set with only a single argument:
set myref {expect_out(buffer)}
puts "The value is [set $myref]"
But if you've got that $ as well, the right thing to do is to use subst (which means “pretend this was something in double quotes”):
set myref {$expect_out(buffer)}
puts "The value is [subst $myref]"
Pick the right one for what you've got.

I think this will do the trick
set myval [subst $$myref]
The $myref gets substituted first, and then we substitute that value with the second $
This is an example of the above doing what I think it is you want:
set a 12
12
set b a
a
set c [subst $$b]
12

You can't use $$ to double de-reference. However you can use the set command with only a single parameter to read a value from a variable. So:
set myval [set $myref]
The evaluation of the set statement first expands the $myref to get the $expect_out(buffer) string, this is then the argument to the set command itself and is evaluated to return the value of that variable name.
% set a(test) hello
hello
% set name "a(test)"
a(test)
% set b [set $name]
hello

Related

adding commas as thousands to numerical string in batch

I was wondering if there was a simplistic code to add commas as thousands separators in variables that takes into account the length of the digit. For example, if The variable equals 123576 I would want it to become 123,456, but if the variable were equal to 1234567 then I would want it to turn into 1,234,567.
ECHO Processing %num%
SET "withcommas="
:subl
IF DEFINED num SET "withcommas=%num:~-3%,%withcommas%"&SET "num=%num:~0,-3%"&GOTO subl
SET "withcommas=%withcommas:~0,-1%"
ECHO result=%withcommas%
Processes num to required format. Note : num will be undefined by code.

How to replace particular character in string with tcl script?

set some_string "Name/is/ComplexSTRUCTUre"
convert this string to,
some_string = "Name/is/ComplexSTR.CTUre"
i.e replacing first "U" to "."
Try This,
set replaced_string [regsub "U" $some_string "."]
puts $replaced_string
Another Option,
set pos [string first "U" $some_string]
set replaced_string [string replace $some_string $pos $pos "."]
puts $replaced_string
Here your "Name/is" portion should not contain any "U"
More information can be found here tcl string replacement
Use of regsub is overkill for plain strings. If you simply wish to replace one set of substrings with another, string map is your friend:
set s "Name/is/ComplexSTRUCTUre"
set s [string map {U .} $s]
This, however, will replace all Us with dots -- as your question's title suggests.
If, however, you want only the first U replaced -- as the text of your question implies, then AxT_8041's second option is the most suitable.
you can use:
string replace <num1> <num2> <To_be_replaced>
example:
set a [get_attr [get_cells -filter <cell_name> ] ref_name]
<cell_name>
string replace 5 8 NAME
<cell_NAME>

Why string compare returns -1 even though both strings are same?

I am getting -1 instead of 0 in string comparison
I have used following code
set s1 "sekhar"
set s2 "sekhar"
puts [string compare s1 s2]
When you do:
string compare s1 s2
You are comparing the string literals s1 and s2. Since s1 is lesser according to the rules (which are basically the same as for the C strcmp() function with enhancements) you get -1 as result.
To compare the strings with those names, you need to read the variables before feeding them into string compare. You do this by prefixing the names with $ (which in Tcl means “read this variable right now”):
string compare $s1 $s2
Internally, Tcl passes values around by reference and reduces variable accesses to indexes into a local variable table where it can (i.e., in procedures). This operation is actually pretty fast in practice.

GNUplot use GN variable in a label

GN produces the variable STATS_max_y when plotting data.
I'd like to use it in a label, such as:
set label 4 "The highest value is: STATS_max_y"
but I can't see how to concatenate the GN variable and the label text.
I tried:
"The highest value is: . STATS_max_y"
and I get internal error : STRING operator applied to non-STRING type
Something like:
set label 4 sprintf("The highest value is: %f", a)
should do it. For more information, check out www.gnuplotting.org/manpage-gnuplot-4-6/#Q1-1-464
[edited]
"The highest value is: " . STATS_max_y - my suggestion
"The highest value is: . STATS_max_y" - OPs code
So the closing quote is at a different position. The first line is a constant string ("...") concatenated (via the .-operator) with the variable <STATS_max_y>, the second line ist only a constant string (everything between the two quotes).

Conditionals for data type in gnuplot functions

I would like to define a function which returns the string "NaN" or sprintf("%g",val) depending on whether val is a string or a numeric value. Initially I was trying to test if val was defined (using the gnuplot "exists" function) but it seems that I cannot pass any undefined variable to a function (an error is issued before the function is evaluated). Therefore: is there a way to test inside a function whether the argument is a string or numeric?
I search for a function isstring which I can use somehow like
myfunc(val)=(isstring(val)?"NaN":sprintf("%g",val))
The goal is to output the values of variables without risking errors in case they are undefined. However I need it as a function if I want a compact code for many variables.
Gnuplot doesn't really have the introspection abilities that many other languages have. In fact, it treats strings and numbers (at least integers) very similarly:
print "1"+2 #prints 3
a=1
print "foo".a #prints foo1
I'm not exactly sure how this is implemented internally. However, what you're asking is very tricky to get to work.
Actually, I think your first attempt (checking if a variable exists) is more sensible as type-checking in gnuplot is impossible*. You can pass the variable name to the function as a string, but the problem is that you don't seem to have a handle on the value. All seems lost -- But wait, gnuplot has an eval statement which when given a string will evaluate it. This seems great! Unfortunately, it's a statement, not a function (so it can't be used in a function -- argv!). The best solution I can come up with is to write a function which returns an expression that can be evaluated using eval. Here goes:
def exists_func(result,var)=sprintf("%s=exists('%s')?sprintf('%g',var):'NaN'",result,var,var)
Now when you want to use it, you just prefix it with eval
a=3
eval exists_func("my_true_result","a")
print my_true_result #3
eval exists_func("my_false_result","b")
print my_false_result #NaN
This goes against the grain a little bit. In most programming languages, you'd probably want to do something like this:
my_true_result=exists_func(a)
But alas, I can't figure out how to make that form work.
Of course, the same thing goes here that always goes with eval. Don't use this function with untrusted strings.
*I don't actually know that it's impossible, but I've never been able to get it to work
EDIT
In response to your comment above on the question, I think a function like this would be a little more intuitive:
def fmt(x)=(x==x)?sprintf("%g",x):"NaN"
With this function, your "sentinal/default" value should be NaN instead of "undefined", but it doesn't seem like this should make too much of a difference...(Really, if you're willing to live with "nan" instead of "NaN" you don't need this function at all -- sprintf will do just fine. (Note that this works because according to IEEE, NaN doesn't equal anything (even itself)).
You helped me a lot these days with gnuplot. I want to give you something back because I have found a solution to check if a variable is numeric or not. This helps to decide which operators can be used on it (e.g. == for numbers, eq for strings).
The solution is not very simple, but it works. It redirects gnuplot's print command to a temp file, writes the variable to the file with print myvar and evaluates the file's first line with system("perl -e '<isnumeric(line#1 in temp file)?>' ") (<> is pseudo-code). Let me know if there's room for imrpovements and let me hear your suggestions!
Example: myvar is a float. Any integer (1 or "1") or string value ("*") works too!
myvar = -2.555
# create temporary file for checking if variables are numeric
Int_tmpfle = "tmp_isnumeric_check"
# redirect print output into temp file (existing file is overwritten)
set print Int_tmpfle
# save variable's value to file
print myvar
# check if file is numeric with Perl's 'looks_like_number' function
isnumeric = system("perl -e 'use Scalar::Util qw(looks_like_number); \
open(FLE,".Int_tmpfle."); $line = < FLE >; \
if (looks_like_number($line) > 0) {print qq(y)} ' ")
# reset print output to < STDOUT> (terminal)
set print "-"
# make sure to use "," when printing string and numeric values
if (isnumeric eq "y") {print myvar," is numeric."} else {print myvar," is not numeric."}

Resources