Pages

Wednesday, June 5, 2013

TCL Questions

#reverse a string in tcl
set a 12345
set b [string length $a]
puts $b
for {set i $b} {$i >= 0} {incr i -1} {
puts -nonewline [string index $a [expr $i -1]]
}

Another method:
set string "nawrajlekhak"
set rev [string reverse $string]
puts $rev

#reverse a list in tcl
set list "5 7 66 2 1"
set len [llength $list]
#puts $len
for {set i $len} {$i > 0} {incr i -1} {
set b [lindex $list [expr $i - 1]]
puts -nonewline "$b "
}

or

set lst {1 2 3 30 -1 a b}
puts [lreverse $lst]

#Remove duplicate entries from the list
set list "1 2 3 4 5 6 7 8 11 17 33 3 4 8"
set b [lsort -unique $list]
puts $b

#Find the number of elements in the list without using llength
set list "1 2 3 4 5 6 7 8 11 17 33 3 4 8"
set i 0
foreach ele $list {
set b "$ele = $i"
incr i
}
puts $i

#Print all elements in the list using flow controls
set list "1 2 3 4 5 6 7 8 11 17 33 3 4 8"
set len [llength $list]
puts $len
for {set i 0} {$i < $len} {incr i} {
puts -nonewline "[lindex $list $i] "
}

#Create array and print all elements in array
array set arrayvar {1 one 2 two 3 three}
puts [parray arrayvar]
puts [array names arrayvar]
puts [array size arrayvar]
puts [array get arrayvar]
puts [array exists arrayvar]

#Reverse a string
set string "nawrajlekhak"
set rev [string reverse $string]
puts $rev

#Write a program to find given string is palindrome or not
set a madam
set len [string length $a]
set n [expr ($len-1)/2]
for {set i 0} {$i < $n} {incr i} {
set b [string index $a $i]
set c [expr $len - 1 - $i]
set d [string index $a $c]
if {$b != $d} {
puts "not palindrome"
exit
}
}
puts "palindrome"


#Write a regsub command to replace all “.” in ip address to “_”
set ip "192.168.10.1"
set b [string map {. _} $ip]
puts $b

#Create a package
package require TclUtils

#fabonacci series.
set fib1 0
set fib2 1
set s ""
for {set i 0} {$i < 8} {incr i} {
    set fib3 [expr {$fib1 + $fib2}]
    set fib1 $fib2
    set fib2 $fib3
    append s "$fib1, "
}
puts "$s"


#Factorial:
set fact 1
for {set i 0} {$i <= 16} {incr i} {
    puts "$i! = $fact"
    set fact [expr {$fact * ($i + 1)}]
}

#switch
set x 1
switch $x {
  "1" {puts "hello"}
    "2"  {puts "hi"}
    "default" {puts "wrong value"}
}

#matching any ip address
set str 192.168.3.110
regexp {(^[0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$} $str all first second third fourth
puts "$all \n $first \n $second \n $third \n $fourth \n"
if {$first <= 255 && $second <= 255 && $third <= 255 && $fourth <= 255} {
puts "valid ip address"
} else {
puts "invlaid ip address"
}

#How to swap two numbers without using swap command
set a 100
set b 12
set a [expr $a + $b]
set b [expr $a - $b]
puts "b = $b"
set a [expr $a - $b]
puts "a = $a"

#How to multiply two numbers without using multiplication operator.
set a 0
set b 5
set s 0
for {set i 1} {$i <= $b} {incr i} {
set s [expr $a + $s]
}
puts $s

#convert ascii to char
proc tochar ascii {
set b [format %c $ascii]
puts $b
}
tochar 65

#convert char to ascii
proc toascii char {
scan $char %c ascii
puts $ascii
}
toascii A

#Read
 set fp [open "somefile" r]
 set file_data [read $fp]
 close $fp

set fp [open "somefile" r+]
 set file_data [read $fp]
 set data "hello how r u"
 puts -no newline $fp $data
 close $fp

#Write
set data "This is some test data.\n"
set filename "test.txt"
set fileId [open $filename "w"]
puts -nonewline $fileId $data
close $fileId

#append
#Open the file called "jokes.txt" for writing
set out [open "jokes.txt" w]
puts $out "Computers make very fast, very accurate mistakes."
close $out
#Now append more jokes at the end of the file
set out [open "jokes.txt" a]
puts $out "Computers are not intelligent. They only think they are."
puts $out "My software never has bugs. It just develops random features."
puts $out {All computers wait at the same speed.
Best file compression around:  "DEL *.*" = 100% compression
DEFINITION: Computer - A device designed to speed and automate errors.
DEFINITION: Upgrade - Take old bugs out, put new ones in.}
close $out

#what does these variable means.
set a [info vars]
puts $a
puts $argv0
puts $tcl_version
puts $tcl_interactive
puts $errorCode
puts $auto_path
puts ***$errorInfo**
puts $argc
puts $tcl_libPath
puts $tcl_library
#Output
argv argv0 tcl_version tcl_interactive errorCode auto_path errorInfo env tcl_patchLevel argc tcl_libPath tcl_platform tcl_library
C:/Users/Nawraj/Desktop/tcltutor30b6.exe/main.tcl
8.6
0
TCL LOOKUP VARNAME ::tcl_pkgPath
C:/Users/Nawraj/Desktop/tcltutor30b6.exe/lib/tcl8.6 C:/Users/Nawraj/Desktop/tcltutor30b6.exe/lib
***can't read "::tcl_pkgPath": no such variable
    while executing
"foreach Dir $::tcl_pkgPath {
   if {$Dir ni $::auto_path} {
lappend ::auto_path $Dir
   }
}"**
0
C:/Users/Nawraj/Desktop/tcltutor30b6.exe/lib/tcl8.6 C:/Users/Nawraj/Desktop/tcltutor30b6.exe/lib
C:/Users/Nawraj/Desktop/tcltutor30b6.exe/lib/tcl8.6

#How to verify whether system installed with 32 bit or 64 bit TCL library
% parray tcl_platform
tcl_platform(byteOrder) = littleEndian
tcl_platform(machine)   = i686
tcl_platform(os)        = Linux
tcl_platform(osVersion) = 2.6.18-164.el5
tcl_platform(platform) = unix
tcl_platform(threaded) = 1
tcl_platform(user)      = vijaym
tcl_platform(wordSize) = 4

tcl_platform(wordSize) = 4  - Express that this is 32 bit TCL, if this is 8 then 64 bit TCL.

#Check where the tcl package has installed the shared library:
rpm -ql tcl | grep lib

#What do you mean by wrapper.
It bundles a base application such as protclsh or prowish, Tcl scripts, system library files, and any other files needed by your application into a single "wrapped" file that is completely self-contained. You can distribute this file to your customers and they can execute it directly without needing any installation or any preexisting facilities.
All-in-one output. TclPro Wrapper creates a single wrapped file that contains everything needed to run a single application.
Flexible sharing. Normally, TclPro Wrapper incorporates everything needed by the application into the wrapped file. However, you can choose to leave out shared library facilities if you know that the application will only be used in environments where the libraries are available. This reduces the size of the wrapped applications while still providing the convenience of bundling several source files into a single wrapped file.

#Simplest call from C to Tcl - just a wrapper
/* Well House Consultant - building TCL into a C application */
/* This example is just a wrapper around a TCL interpreter */
#include
#include
main (int argc, char *argv[]) {
        Tcl_Interp *myinterp;
        int status;
        printf ("Your Tcl Program will run ... \n");
        myinterp = Tcl_CreateInterp();
        status = Tcl_EvalFile(myinterp,argv[1]);
        printf ("Your Tcl Program has completed\n");
}

#What steps should be followed if your script fails during execution.
debug [[-now] 0|1] controls a Tcl debugger allowing you to step through statements, set breakpoints, etc.
With no arguments, a 1 is returned if the debugger is not running, otherwise, a 0 is returned. With a 1 argument, the debugger is started. With a 0 argument, the debugger is stopped. If a 1 argument is preceded by the -now flag, the debugger is started immediately (i.e., in the middle of the debug command itself). Otherwise, the debugger is started with the next Tcl statement.The debug command does not change any traps. Compare this to starting Expect with the -D flag.

#to match any email address
set a "[email protected]"
if {[regexp -- {^[A-Za-z0-9._-][email protected][[A-Za-z0-9.-]+$} $a b]} {
puts $b
} else {
puts fail
}
#puts $a

#To match any url
set url https://groups.google.com
regexp -all {^[a-z]+\:\/\/[0-9.a-z_/]+} $url new
puts $new

#Generate random no in TCL
set random_number [expr int(rand()*10)]

#How do I convert a list into string in Tcl?
set list {a b c d e f}
for {set i 0} {$i<[llength $list]} {incr i} {
    append string [lindex $list $i]
}
puts $string

#Write a Procedure to sum two numbers with one variable has a default value.
proc sum {a {b 5}} {
set c [expr $a+$b]
puts $c
}
sum 1

#call by value
proc print_hello {count} {
for {} {$count>0} {incr count -1} {
puts "hello world"
}
}
set var 2
print_hello $var
#Output
hello world
hello world

#call by reference
proc print_hello {count} {
upvar $count v
set v 2
for {} {$v > 0} {incr v -1} {
puts "hello world"
}
}
print_hello var
#Output
hello world
hello world

#factorial
proc fact {n} {
if {$n==0||$n==1} {
return 1
} else {
return [expr {$n*[fact [expr {$n-1}]]}]
}
}
set a [fact 4]
puts $a

#To display powers of integers
set message "";
set p 2
foreach k {1 2 3 4} {
append message "\$k to the power \$p is [expr pow(\$k,\$p)]\n"
}
set message
=> 1 to the power 2 is 1.0
2 to the power 2 is 4.0
3 to the power 2 is 9.0
4 to the power 2 is 16.0

#Loop Control: break and continue 
The break command causes the innermost enclosing looping command to terminate immediately.
The continue command causes only the current iteration of the innermost loop to be terminated. The loop continues with next iteration.
#continue
for {set x 0} {$x < 10} {incr x} {
if {$x == 5} {
   continue
   }
   puts "x is $x"
 }
#output
x is 0
x is 1
x is 2
x is 3
x is 4
x is 6
x is 7
x is 8
x is 9

#break
for {set x 0} {$x < 10} {incr x} {
if {$x == 5} {
   break
   }
   puts "x is $x"
 }
#output
x is 0
x is 1
x is 2
x is 3
x is 4

#What is difference between lappend and concat
set list1 {1 2 3}
puts $list1
set list2 {a b c}
puts $list2
set new [lappend list1 $list2]
puts $new
set lengthlist [llength $new]
puts $lengthlist

#output
1 2 3
a b c
1 2 3 {a b c}
4

set list1 {1 2 3}
puts $list1
set list2 {a b c}
puts $list2
set b [concat $list1 $list2]
puts $b
set concatlength [llength $b]
puts $concatlength

#output
1 2 3
a b c
1 2 3 a b c
6

Note: length of output of lappend is 4 whereas for output of concat is 6

#Package
Tcl supports grouping multiple procedures or compiled "C" code modules into a single entity referred to as a package. A package may consist of a single file, multiple files or a mix of compiled and Tcl script files.
 Some packages (like http and Tk) are provided in the base Tcl distribution, and much more are included in the tcllib collection. (See tcllib.sourceforge.net

 To access a package from a script:
1. Make certain that the auto_path global variable includes the path to the package you wish to include. The standard Tcl distributions include the proper paths by default.
2. Include a line like this in the application that uses a package:
 package require nameOfPackage 
 Your script will need a separate package require command for each package you wish to include.

 To create a package, you'll need
1. to include a package provide command like
 package provide nameOfPackage revisionNumber 
 in each file that's included in the package
2. create a pkgIndex.tcl file to describe the files in the package.
 This can be done with the pkg_mkIndex command.

package require name? revision?
Tells the interpreter to find a package with the given name and optional revision number. If the revision number is absent, the largest revision available is used.
package provide  name revision 
Declares that this file provides an implementation of a specific revision of a package. A file may include only one package provide command.
pkg_mkIndex libdir file1 ... filen
Creates an index file (pkgIndex.tcl) in libdir from the source code modules listed as file1 - filen. Each proc in the files will be listed in the index file, with a reference to the source code module that contains it.
The file descriptors may be any number of strings using the same format as arguments to the glob command.  Two other commands are related to finding packages and processing them. Your code will not need to use these, but you may find them useful in understanding how the system behaves.

info library
Returns the name of the library directory in which the standard Tcl scripts are stored.

Tcl procs that are in files in the Tcl library directory are loaded automatically when they are executed.
Tcl expects to find init.tcl in the default library location, defined when the Tcl interpreter is built. This path can be changed by setting the environment variable TCL_LIBRARY.
unknown args
This proc is called by the interpreter when it encounters a command that can be parsed, but the command name is not in the tables. Unknown attempts the following steps to execute the command
*Checks the index in the directories listed in auto_path to see if the proc exists in a file. If the proc is found, the script is loaded with the auto_load proc, and the proc is executed.
*If the interpreter is running interactively, Tcl attempts to exec the command with the auto_exec proc.
*If the command is a unique prefix to a Tcl command, unknown completes the command name and executes that command

#tclvars - Variables used by Tcl
http://tmml.sourceforge.net/doc/tcl/tclvars.html

#tclsh - Simple shell containing Tcl interpreter
http://tmml.sourceforge.net/doc/tcl/tclsh.html

#Difference between TCL and Perl
Tcl is a pure interpreter; Perl uses a bytecode engine
Tcl is a scripting language used for extending and controlling applications.
TCL is embeddable
Its interpreter is library of C procedures that can be incorporated in the applications.
TCL gives the benefit of rapid development(functions are already present we just need to use them).

Perl(Practical extraction and report language) is an interpreted language.
Usually used for text and data manipulation.
Majorly used by system administrators and web programmers.
Perl is a composition of sed, awk, C, Shell and English programmers.


#Generally how many LOC a coder can code in a day.
"Applying our TAO-Extreme-XP-Pattern-Pair-Agile-Y2K-Guru development methodologies allows our programmers to produce 1000 LOC per a day, while the industry average is only 250 LOC per day"

"TAO-Extreme-XP-Pattern-Pair-Agile-Y2K-Guru development methodologies allow our programmers to produce code with only 3.2 defects per 100 LOC, while the industry standard is 3.7 defects per 100 LOC."

#Namespce
namespace bascially will be written inside packages
say u want to have telent session for two different routers say r1 and r2 then u will write one function say
telnet
but while calling telnet session for r1 ..u will use namespace r1::telent
for telent session of r2 ..use namespace r2::telnet

#Perl: Compiler or Interpreter?
A compiler is a program that reads a source program and converts it into object code. This object code is then used
by the Linker to produce an executable file. Both the object code and executable files are in binary form. This
means that if you try to read them all you can see are garbage and some of the literals used in the program. The
compile-link process ensures that the program is free from any syntax errors. It cannot determine logic errors in
the program.
An interpreter is a program that reads a source program and executes the source program in real time. This cuts
down the time to prepare the program as you do not need to compile and link the program. The interpreter executes the instructions as it reads the file. This, however, means that syntax errors can cause the program to abort in the middle of execution. This can be very frustrating and dangerous especially if your program has been running for quite a while.
Perl is a hybrid of the two. When a program is executed, perl reads the program and builds a binary file at the
same time, checking for syntax errors. If there are no errors, it then uses the binary file to execute the
instructions. Syntax errors will cause Perl to terminate BEFORE it goes on to execute the program. In a sense, Perl gives you the best of both worlds.

#Difference in tcsh and tclsh
tcsh (the Enhanced/Tenex C Shell) or tclsh (TCL shell)

#Diff in braces
{ } used to defer the expansion of variables,
commands, and backslash characters until the code
executes
set i 0
while {$i < 10} {code to execute}
is not the same as
set i 0
while ”$i < 10” ”code to execute”
which will always evaluate as true.

# Convert a single hex digit to decimal
set hex a
set decimal [string first [string toupper $hex] "0123456789ABCDEF"]
puts $decimal
if {$decimal == -1} {
puts "Hey, $hex isn't a hex digit"
}

# Convert a decimal number in the range of 0 to 15 to a hex character
set decimal 13
set hex [string index "0123456789ABCDEF" $decimal]
puts $hex
if {$hex == {}} {
puts "Hey, $decimal isn't in the range 0 to 15"
}

# Check for runt (<64 and="" bytes="" giant=""> mtu) packets
set mtu 1500
set packet "This is a simulated packetAAAA08..."
set packetlen [string length $packet]
if {$packetlen < 64} {
puts "Hey, this packet is a runt"
}
if {$packetlen > $mtu} {
puts "Hey, this packet is a giant"
}
  
#:? Command Usage
Usage:
?: is used in sub patterns in a regexp
Whenever you don’t want a particular subpattern to be included as a sub-pattern use “?:” in front of the sub-pattern
Example:
set string "Names: Nawraj Raj Lekhak"
regexp "Names: (Nawraj|Raj) (?:Lekhak|Dinesh|Raj) (Lekhak|Dinesh)" $string match sub1 sub2 sub3
puts "$match\n$sub1\n$sub2\n$sub3\n"
In the above example, the output will be
Names: Nawraj Raj Lekhak
Nawraj
Lekhak

#TCL Program – Check given number is odd or even in tcl
proc oddeven {n} {
if {$n%2==0} {
puts “the given $n is even” } else {
puts “the given number $n is odd” }
}
oddeven 24
oddeven 67
o/p:
the given 24 is even
the given number 67 is odd

# How to increment each elements in a list
set list "1 2 3"
foreach ele $list {
puts [incr ele]
}

#How to increment a char
set no a
set new [expr [scan $no %c] + 1]
puts $new
set value [format %c $new]
puts $value
Output:
98
b

#Loop
Next small script will run for a specified times specified command and wait specified time. Variable repeat is used to specify number of loops. Variable command is a IOS command you want to run and variable wait says, how long to wait before executing the same command in a loop.
# Loop
# Run specified command in a loop for X times and wait Y ms after every execution.
set repeat 10
set command "show ip interface brief"
set wait 1000
for { set i 1 } { $i <= $repeat } { incr i } {
puts "\n===========================\nShowing: $i/$repeat\n==========================="
puts $command
after $wait
}

Aliaser
Just a small TCL script that demonstrates, how is switch command used. You will run this command in an infinite loop, until “q” is typed. You can use number 1, 2 and 3. You can add any character you want. After typing character, press enter.
# Aliaser
#
while {1}  {
switch [read stdin 1] {
"1" {show ip route}
"2" {show ip protocols}
"3" {show ip int brie \| i up}
"q" {break}
"\n" {puts ""}
default {puts "Unknown command, type \"q\" for quit"}
}

}

Find duplicate files from different directories.

set searcrhResults {dir1/dir2/dir3/file1.tcl   dir1/dir3/file1.tcl   dir1/dir2/file1.tcl   dir1/dir2/dir3/file2.tcl   dir1/dir2/dir3/file3.tcl   dir1/dir3/file2.tcl   dir1/file3.tcl   dir1/file4.tcl }

foreach file $searcrhResults {
  if {[catch {incr filenames([file tail $file],cnt)}]} {
      set filenames([file tail $file],cnt) 1
  }
      lappend filenames([file tail $file],paths) [file dirname $file]
}






11 comments:

  1. Thanks for the detailed QA

    ReplyDelete
  2. Its my pleasure !! Happy reading !!

    ReplyDelete
  3. Hi,
    Thank you very much for long list of programs, It's a great help.

    -Chandra

    ReplyDelete
  4. Very nice. thanks for the good programs and your time

    ReplyDelete
  5. Welcome Sumanthi ..Glad you liked it .Happy Reading :)

    ReplyDelete
  6. Nawraj, Thank you so much for these.
    Please can you confirm if you have run all these programs?

    ReplyDelete
  7. Hi Sou,

    Yes i have tested all of the programs some time back.

    Regards,
    -Nawraj

    ReplyDelete
  8. Hi Nawraj, thanks for confirming.
    I have also recollected that I have worked with you for a brief period of time when you were in Spirent. Good to hear from you. :)

    ReplyDelete
  9. Hi Narwaraj,

    i searched many sites.nobody can give the clarity information about tcl.
    Thanks for sharing your valuable information with us.
    I expect little bit more questions and answers from you apart from this.

    once again thanks a lot!!!!

    Regards,
    Suresh Reddy

    ReplyDelete
  10. Thanks Guys .. I am glad you liked it :)

    ReplyDelete