How to insert ASCII control characters into a TCL string? - tcl

I need to create a TCL script that contains ASCII control characters. This is the full list of these characters from the ASCII table but I am only interested in putting in the "start of text" value 2 and "end of text" value 3.

You can enter a hex code in a string by writing \xnn where nn is the code, e.g.
set start_of_text "\x02"
set end_of_text "\x03"
See the documentation at https://www.tcl-lang.org/man/tcl8.6/TclCmd/Tcl.htm#M27

You can also use format with the %c code (which might be more useful if you don't know the relevant number until run-time because it's in a variable or whatever):
set ascii(STX) [format %c 2]
set ascii(ETX) [format %c 3]

If I'm going to be wrapping text in a control sequence (often for things like applying a colouring) then I'll make a procedure to do the job:
proc wrapped {string} {
# These use Unicode escapes
return "\u0002$string\u0003"
}
puts [wrapped "this is some test text"]

Related

tcl puts if format strings

I want to print a information in a table.
some of the information contain a color code as \033\[1;31m${info}\033\[0m
The method I use to print the content is as below:
set name "arb bul"
set qname black
set phone 123-456789
set print_users az
set name "arbi yu"
set info dod
set string "%-15s%-22s%-15s%-11s%-1s"
puts [format $string $name $qname ${info} ${phone} $print_users]
The problem came out when I try to color one of the strings, the table shift doesn't kept since the next string take into account the spaces from the last characters.
set qname "\033\[1;31mblack\033\[0m"
puts [format $string $name $qname ${info} ${phone} $print_users]
Is there any way to set the string spaces from the beginning of the line?
The format command does not have any knowledge of what the different escape codes may mean to the terminal. Different terminals use different escape codes. If you want to be able to use escape codes in your values, it may be best to also use escape codes to position the strings:
set string "%s\033\[16G%s\033\[38G%s\033\[53G%s\033\[64G%s"

Function which removes html color from a string with sscanf

I've a big dilemma how can I do a condition to remove this type of color from my string (ex: {dd2e22}) using sscanf, which is only func I want to use. So the string provided will be some random text:
Te{dd2e22}xt is {3f53ec}here
The condition what I tried
sscanf(buf,"%[^\{[0-9a-fA-F]{6,8}\}]s",output);
This isn't working, the result are only first character "T".
Try using the format specifier:
"%*6X"
Analysis:
% -- starts a format specifier.
* -- tells scanf not to assign field to variable.
6x -- says that field is 6 hex digits.
See scanf format specifier
result are only first character "T".
Well, the next character is 'e', which matches the set \{[0-9a-fA-F]{6,8}\ and thus doesn't match the inverted set specified by '^'.
This task can be achieved with a regular expression. The standard library provides you with appropriate tools in the <regex> header.

spark csv writer - escape string without using quotes

I am trying to escape delimiter character that appears inside data. Is there a way to do it by passing option parameters? I can do it from udf, but I am hoping it is possible using options.
val df = Seq((8, "test,me\nand your", "other")).toDF("number", "test", "t")
df.coalesce(1).write.mode("overwrite").format("csv").option("quote", "\u0000").option("delimiter", ",").option("escape", "\\").save("testcsv1")
But the escape is not working. The output file is written as
8,test,me
and your,other
I want the output file to be written as.
8,test\,me\\nand your,other
I'm not certain, but I think if you had your sequence as
Seq((8, "test\\,me\\\\nand your", "other"))
and did not specify a custom escape character, it would behave as you are expecting and give you 8,test\,me\\nand your,other as the output. This is because \\ acts simply as the character '\' rather than an escape, so they are printed where you want and the n immediately after is not interpreted as part of a newline character.

Can we give array name with hyphen in TCL

I am declaring a array in TCL say
set JDSU-12-1(key) element
parray JDSU-12-1
I am getting error saying JDSU is not a array
Even simple puts statement is not working
% puts $JDSU-12-1(key)
can't read "JDSU": no such variable
Is there any way i can declare array name with hyphen. I know _ works in array but not sure about hyphen
You can use special characters in Tcl variable names. You need the braces for those though:
% puts ${JDSU-12-1(key)}
element
You can even use $:
% set \$word "Hello world" ;# Or set {$word} "Hello world"
% puts ${$word}
Hello world
EDIT: Some reference:
beedub.com (Emphasis mine)
The set command is used to assign a value to a variable. It takes two arguments: the first is the name of the variable and the second is the value. Variable names can be any length, and case is significant. In fact, you can use any character in a variable name.
You can use almost any character for the name of a variable in Tcl — the only restrictions relate to :: as that is a namespace separator, and ( as that is used for arrays — but the $ syntax is more restrictive; the name it accepts (without using the ${…} form) has to consist of just ASCII letters, ASCII digits, underscores or namespace separators. Dashes aren't on that list.
The standard (and simplest) way of reading from a variable with a “weird” name is to use set with only one argument, as that happily accepts any legal variable name at all:
puts "the element is '[set JDSU-12-1(key)]'"
However, if you're doing this a lot it is actually easier to make an alias to the (array) variable name:
upvar 0 JDSU-12-1 theArray
puts "the element is $theArray(key)"
That's exactly how parray does it, though it uses upvar 1 because it is aliasing to a variable in the calling scope and not in the current scope.
Although you can use such special characters, you can only use a few when you try to access variables with $varname.
To quote the relevant section from the manual:
$name
Name is the name of a scalar variable; the name is a sequence of one or more characters that are a letter, digit, underscore, or namespace separators (two or more colons). Letters and digits are only the standard ASCII ones (0-9, A-Z and a-z).
$name(index)
Name gives the name of an array variable and index gives the name of an element within that array. Name must contain only letters, digits, underscores, and namespace separators, and may be an empty string. Letters and digits are only the standard ASCII ones (0-9, A-Z and a-z). Command substitutions, variable substitutions, and backslash substitutions are performed on the characters of index.
${name}
Name is the name of a scalar variable or array element. It may contain any characters whatsoever except for close braces. It indicates an array element if name is in the form “arrayName(index)” where arrayName does not contain any open parenthesis characters, “(”, or close brace characters, “}”, and index can be any sequence of characters except for close brace characters. No further substitutions are performed during the parsing of name.
There may be any number of variable substitutions in a single word. Variable substitution is not performed on words enclosed in braces.
Note that variables may contain character sequences other than those listed above, but in that case other mechanisms must be used to access them (e.g., via the set command's single-argument form).
I want to empathis the last paragraph a bit:
You are always able to read any variable with set varname:
set JDSU-12-1(key) element
puts [set JDSU-12-1(key)]
Unlike the ${varname} access, you can substitute a part of the variable name (in your case the array key), the entire variable, while set k "key"; puts ${JDSU-12-1($k)} does not work.
You can easily do that:
set set-var "test"
while accessing so ${set-var}
Like in most other programming languages, TCL variable must be alphanumeric starting with letter (A to Z, or _). Hyphen or dash (-) is not permitted as part of variable name, otherwise it would be confused with arithmetic minus or subtraction: there would be no difference between $x-1 as variable with name "x-1" or $x-1 as variable x minus 1.
Try this :)
subst $\{[subst ${conn}](phan)\}
Which version are you working ??
my tcl works.
% set JDSU-12-1(key) element
element
% parray JDSU-12-1
JDSU-12-1(key) = element

Use comment symbol in variable value TCL

I am looking to use the # symbol which is the symbol to indicate that everything following is going to be a comment in a variable value. So, I would like to write the following:
set Dev1_Number 1#
set Dev2_Number 2#
But the program only recognizes 1 and 2 as values that can be placed the memory location of the variable. Is there anyway to get around that?
Tcl comments only occur when the comment character is the first character of a command word
(http://www.tcl.tk/man/tcl8.5/TclCmd/Tcl.htm#M29). You'll see code with end-of-line comments preceded by a semicolon
set foo bar ;# this is a comment
set foo bar # this is an error!
That's not the case in your example. In your example, the hash is merely data.
Your comments indicate your editor is making an incorrect assumptions about Tcl syntax. What editor are you using?
If you are concerned, you can "force" the hash to be part of the value by using quotes
set Dev1_Number "1#"
set Dev1_Number {1#}
Use backslash character, It escapes the original meaning of that character.
set a 3\#
puts "a=$a"
output: a=3