Tuesday, 13 December 2016

TCL Overview

TCL: 

       “Tcl” is the language used to develop automated test scripts.
       Developed by John Ousterhout at UC Berkeley. 
       It is an interpreted language – provides fundamental operations of all languages such as flow control and variable management.
       Tcl provides a fundamental command set which is to be expanded by adding “extensions” to the language to perform specific operations (e.g. “Tk” –  Tool Kit, the first Tcl Extension for GUI/widget development)

Start and Exit the Tcl Interactive Session
       Tcl is an interactive interpreter – you can start it from UNIX shell and type commands 
       Setting the Environment
       Type tclsh or expect at Unix Shell prompt to start interactive interpreter
       Type exit, exit or ctrl-C to exit the interpreter

% info tclversion
8.4
exit
expect
expect1.1> info tclversion
8.4
expect1.2> exit 1

Language Overview
       Learning Tcl/Expect - Two parts 
         Syntax and Substitution Rules
§   Substitutions simple, may be confusion at first
         Built-in commands
§  Can be learn individually as needed

Data - Strings, Lists
       All Tcl Data are Strings
       All Strings are space separated lists
       i.e. Everything is a “String”, and Every String is a “List”
       This convention was adapted to make the implementation of new Tcl commands in C language much easier, since each C routine only has to deal with one data type i.e. a String 

Define a variable – The “set” commands
       Define a Variable
       set varName
       Return Variable Value
set varName       
       If varName does not exists, set varName will cause an error
expect1.8> set name
can't read "name": no such variable
    while executing
"set name"
expect1.9> set name "gaurav"
gaurav
expect1.10> set name
gaurav
expect1.11> 

Language Basics:
       Tcl script =
          Sequence of commands.
          Commands separated by newlines, semi-colons.
       Tcl command =
          One or more words separated by white space.
          First word is command name, others are arguments.
          Returns string result.
[…] 
       Examples:
set x 22; set y 33
set x 22
set y 33

Language Basics (contd.)
       Commands end in newline or semicolon: “\n” or “;”
       Continuation character is backslash: “\”
       Comment the lines/strings using pound sign: “#”
       Recommendations          
         Don’t put more then one command on a line
         Indent lines that are continued; 4 spaces are recommended
         The backslash must be the last character on a continued line – not even a space is allowed after a backslash
         Line should not exceed 80 characters 
         A comment can be specified after a command
expect1.1> info tclversion
8.3
expect1.2> info \
+> tclversion
8.3
expect1.3> # this is a comment
expect1.4> set v 5 ; info tclversion
8.3
expect1.5> puts $v
5

Variable Substitution:
       Syntax: $varName
       Variable name is letters, digits, underscores.
       May occur anywhere in a word.
                                Sample command            Result
                                set x 23                                 23
                                set y x                                    x
                                set y $x                                 23
                                set y $x+$x                         23+23
                                set y $x.5                               23.5
                                set y $x4                          no such variable
       Parser assigns no meaning to arguments
       Different commands assign different meanings to their arguments

Quoting:
       With Square Brackets […] 
         Used to pass the return value of a command as an argument to other command; also known as command substitution 
       With Double Quotes “…”
         Used to encapsulate the contents of string, with in double or un-quoted string, interpreter will expand:
                Example: set x “one two” ; set y “this is $x”
Return: this is one two
       Quoting with Curly Braces {…}
         When quoting with curly braces, no variable, command or backslash subtitution
         “” and {} can be used interchangeably if substitution is not required
Example: set x 5; set y {x=$x;[info tclversion]};
Return: x=$x;[info tclversion]

Expressions:
       C-like (int and double), extra support for string operations.
       Command, variable substitution occurs within expressions.
       Used in expr, other commands.
                                Sample command                            Result
                                set x 5                                                    5
                                incr x -1                                                4
                                expr ($x*4) - 3                                    13
                                expr $x <= 2                                       0
                                set a cisco                                            cisco
                                expr {$a < “systems"}                         1

Command Substitution:
       Syntax: [script]
       Evaluate script, substitute result.
       May occur anywhere within a word.
                                Sample command                                            Result
                                set b 8                                                                   8
                                set a [expr $b+2]                                               10
                                set a "b-3 is [expr $b-3]"                             b-3 is 5

Controlling Word Structure:
       Words break at white space and semi-colons, except:
         Double-quotes prevent breaks:
                  Set x 3;set y 5; set a "x is $x; y is $y“
                  Result: x is 3; y is 5

                Curly braces prevent breaks and substitutions:
                set a {[expr $b*$c]}
                Result: [expr $b*$c]

                Backslashes quote special characters:
                set a word\ with\ \$\ and\ space
                Result: word with $ and space

       Substitutions don't change word structure:
set a "two words"
set b $a
Result: two words

Tcl Syntax Summary:
       Script = commands separated by newlines or semicolons.
       Command = words separated by white space.
       $ causes variable substitution.
       [] causes command substitution.
       "" quotes white space and semi-colons.
       {} quotes all special characters.
       \ quotes next character, provides C-like substitutions.
       # for comments (must be at beginning of command).

TCL Lists:
       Zero or more elements separated by white space:

              Example: set myList “red green blue”
              Example: set myList {red green blue}
             Result: red green blue

       Braces and backslashes for grouping:
             Example: set myList {a b {c d e} f}
             Result: a b {c d e} f

       Using the “List” command
              Example: set myList [ list red green blue ]
             Result: red green blue

       With variable substitution
              Example:
                set v1 red; set v2 green; set v3 blue
                set myList [ list $v1 $v2 $v3 ]                    Result: red green blue
                set myList [ list [ set v1] $v2 $v3 ]            Result: red green blue
                set myList “$v1 $v2 $v3”                           Result: red green blue
                set myList “[ set v1] $v2 $v3”                   Result: red green blue
                set myList {$v1 $v2 $v3}                          Result: $v1 $v2 $v3

TCL Lists:
       The “list” manipulation commands allow you to manipulate or query individual elements within the list. 
       List Commands:
          list 
          lappend 
          lindex 
          linsert 
          llength 
          lrange |end
          lreplace |end 
          lsearch ?mode? (mode is one of -exact, -glob, -regexp)
          lsort ?switch? 
(switch can be -ascii, -dictionary, -integer, -real, -increasing, -decreasing, -unique etc…)

List Manipulation – Examples
% set list1 { a b c }
 a b c
% set list2 { 1 2 3 }
 1 2 3
% lappend list1 x y z
a b c x y z
% set list1
a b c x y z
% lindex $list1 4
y
% linsert $list1 4 p q
a b c x p q y z
% llength $list1
6
% lrange $list1 3 end
x y z
% lrange $list1 1 4
b c x y
% lrange $list1 1 2
b c
% lreplace $list1 4 end p q r
a b c x p q r
% lsearch $list1 p
-1
% lsearch $list1 x
3
% lsort $list1
a b c x y z
% lsort -dec $list1
z y x c b a
%

TCL Strings:
       String manipulation commands allow you to work with blocks of characters (strings) within the string 
          string compare
          string equal
          string first
          string last 
          string index 
          string length
          string range |end
          string
          string ?chars?

String Manipulation – Examples:
$  tclsh
% set str1 "cisco"
cisco
% set str2 "systems"
systems
% string compare $str1 $str2
-1
% string equal $str1 $str2
0
% string first is $str1
1
% string first co $str1
3
% string first c $str1
0
% string index $str1 2
s
% string length $str1
5
% string range $str1 2 4
sco
% string range $str1 2 end
sco
% string toupper $str1
CISCO
% string tolower [ string toupper $str1 ]
cisco
% string trim $str1 o
Cisc

Split & Join operations:
       join ?joinString?
          Returns a string formed from , optionally joined by ?joinString?
       split ?splitChars?
          Returns a list formed from , split at ?splitChars?, is specified 
Example:
                join { one two three four} .           Result: one.two.three.four
                split /usr/cisco/bin/tclsh /           Result: usr cisco bin tclsh
                split cisco {}                                   Result: c i s c o
                join {c i s c o } {}                            Result: cisco

Tcl Arrays:
       Used to group multiple strings together in a single variable
       Specified by a variable name followed by an index enclosed in parentheses.
          set my_array(1) value
          set my_array(one) another_value
       Multidimensional arrays can be simulated
       array names
 Returns a list of the indexes for all values stored in the array named 

Array Commands         
       array set
          Initialize an array 
       array names
          Returns all array index
       parray
          Print array
       array unset
          Un-initialize the array 
       array exists
          Returns 1 is varName is an array, 0 otherwise
       array size
          Returns number of elements in the array

Tcl Array – Examples
% array set arrayVar \
                { 1 one 2 two 3 three }
% parray arrayVar
arrayVar(1) = one
arrayVar(2) = two
arrayVar(3) = three
% set arrayVar(4) four
four
% parray arrayVar
arrayVar(1) = one
arrayVar(2) = two
arrayVar(3) = three
arrayVar(4) = four

% array names arrayVar
4 1 2 3
% array exists arrayVar
1
% set name gaurav
gaurav
% array exists name
0
% array size arrayVar
4
% array unset arrayVar
% parray arrayVar
"arrayVar" isn't an array
%

Flow Control – if/then/else:
       Basic “if” statement:
             set varName 1
             if {$varName == 1} { # if expression is true
             puts “The expression is true” # execute code
            }

       Relational and Logical Operators:
==           !=            < >          <=           >=           &&          ||            ( )
       Any expression that returns 0 is “false”; any other value is “true”; 1 is the most common value for true; value must be
       numeric!
       { } Mandatory if expression contains spaces after variable/command substitution
       [ ] Use for command substitution
       ! Negates the result of an expression
       Optional else and elseif , e.g. } else {
       There’s an optional then command, but it’s recommended not to use it

Flow Control – While look:
       Repeatedly evaluate a code block ‘while true’
       Basic “while” statement:
             set varName 1
             while {$varName < 11} { # while expr is true
              puts $varName # execute code
              incr varName
             }
       Two arguments:
         an expression
         a code block
       The expression is evaluated first
        Watch out for “while 1” loops!

Flow Control – Foreach loop:
       Useful for processing lists
       Basic “foreach” statement:
               foreach var [lsort [info commands]] { # set var to next value
                puts $var # then, execute code
              }
       Three arguments
          the name of a variable to set
          a list to iterate across
          a code block to execute
       Similar to a “while” loop, but it sets a variable to the next value of a list before each invocation of the code block
       The loop terminates when the list contents have been consumed

Flow Control – For loop:
       Specialized “while” loop that combines the processes of initialization, testing, and incrementing into a structure.
       Basic “for” statement:
             for {set var 1} {$var < 11} {incr var} {
               puts $var # then, execute code
            }
       Four arguments:
          an initialization expression (executed once, before 1st loop)
          an expression (evaluated for truth before each loop)
          an ending expression (executed after each loop)
          a code block (the body of the loop)
Include all sections, even if empty

Loop Control – break and continue:
       Basic “break” statement:
while 1{
                …
                if 1 break;                             # terminate innermost
                …
}
       Basic “continue” statement:
foreach var [info commands] {
                if {![string match {l*} $var]} {
                                continue               # go to top of loop
                }
                puts $var
                …
}

Flow Control – While look
       Repeatedly evaluate a code block ‘while true’
       Basic “while” statement:
set varName 1
while {$varName < 11} { # while expr is true
                puts $varName # execute code
                incr varName
}
       Two arguments:
         an expression
         a code block
       The expression is evaluated first
        Watch out for “while 1” loops!

Keyed List:
       keyed list commands:
       – keyldel
       – keylget
       – keylkeys
       – keylset
       -keylprint
The sample keyed list :
Keylset  int gig0/0/0/1.ipv4_address 2.2.2.2
Keylset int gig0/0/0/1.ipv4_mask 255.255.255.0
Keylset int gig0/0/01.admin_status up
Keylset int gig0/0/0/1.link_status up

Sample Keyed List Output:
       # Sample Output:
       #  {proc.tcl {
       #       {Type User}
       #       {Event timer watchdog}
       #       {Time  Wed Sep 30 05:36:15 2009}
       #       {name mywdogtimer}
       #       {time_sec 60}
       #       {time_nsec 0}
       #       {nice 0}
       #       {priority normal}
       #       {maxrun_sec 20}
       #       {maxrun_nsec 0}
       #       {persist_time 3600}
       #       {username lab}
       #        }
#    }
Sample Keyed List Output
       expect1.18> keylkeys xyz
       proc_tcl
       expect1.19> keylget xyz proc_tcl
              {Type User}
              {Event timer watchdog}
              {Time  Wed Sep 30 05:36:15 2009}
              {name mywdogtimer}
              {time_sec 60}
              {time_nsec 0}
              {nice 0}
              {priority normal}
              {maxrun_sec 20}
              {maxrun_nsec 0}
              {persist_time 3600}
              {username lab}

Regular Expression:
       Metacharacters in the regular expression pattern:
             . matches any single character
             * matches 0 or more of the previous character(s)
             + matches one or more of the previous character(s)
             ? matches 0 or 1 occurrences of the previous character(s)
             [ chars ] matches any one character in chars
                If ] is the first character in chars , it is treated literally
                If - appears first or last in chars , it is treated literally
             [ ^chars ] matches any one character except those in chars
            ( ) forms a sub-pattern
            | is the or operator; when used, one of the patterns must match
           ^chars matches chars if chars is at the beginning of a string
            chars$ matches chars if chars is at the end of a string
           The metacharacters ^ and $ are called anchors when used at the beginning and end of patterns

Regular Expression Pattern Matching:
       Any character other than . [ ] ? + * ^ $ ( ) | matches a single occurrence of that character.
       Examples:
                [vV]ersion matches either “version” or “Version”
                [0- 9]+ matches a positive integer
                (hardware )?address matches either “hardware address” or “address”
                hdlc|ppp matches either “hdlc” or “ppp”
.               * matches anything, including an empty string
• The backslash character \ escapes the special meaning of the following metacharacter
“regexp” command
“regexp” command:
regexp ??? ? ...?
       The optional variable name will contain the entire substring that matched the expression when regexp returns. The variable names will contain the substrings that match portions of the expression enclosed in parenthesis (()). 
       For example:
expect4.1> set string "One: 1, Two: 2, Three: 3"
One: 1, Two: 2, Three: 3
expect4.2> regexp {[Tt]wo: ([0-9]+)} $string match submatch
1
expect4.3> puts $match
Two: 2
expect4.4> puts $submatch
2
expect4.5>regexp {[Tt]wo:.*([0-9]+)} $string match submatch
1
expect4.6>puts $match
Two: 2, Three: 3
expect4.8> puts $submatch
3

Regular Expression Example:
%set string "%invalid Interface E0.\nRouter#"
# Match a string that begins with '%invalid'
%if {[regexp {^%invalid} $string]} {
                puts "Validation failed"
}
# Match a string that specifies an ethernet interface
# Expression == The word 'interface' beginning with an upper or lower
# case 'i', followed by a space, and a word beginning with an upper
# or lowercase 'e', an optional , and ending with at least 1 digit
%if {[regexp {[Ii]nterface [Ee][A-Za-z]* ?[0-9]+} $string]} {
                puts "Yep, it is an ethernet"
}
%
Regular Expression Example
proc printurl {url} {
set urlmatch {([^:]+)://([^:/]+)(:([0-9]+))?(/.*)}
regexp $urlmatch $url match protocol server x port path
puts "url      = $match"
puts "protocol = $protocol"
puts "server   = $server"
puts "port     = $port"
puts "path     = $path"
}
% printurl  http://www.cisco.com:80/index.html
url      = http://www.cisco.com:80/index.html
protocol = http
server   = www.cisco.com
port     = 80
path     = /index.html

Debugging Regular Expression
       Always check return code!
         If the match fails, regexp will not change the values of the extraction variables. If you don't check the return value, you could be working with data extracted from a previous call to regexp.
       Debug regular expressions interactively, piece by piece
         Cut and paste the pattern into the interpreter
       Use ‘+’ to make sure you have at least one instance of an entire pattern

“regsub” command
       Regular expressions can be used to replace portions of a string with the regsub command:
         regsub ? 
Switched supported here are all , nocase
* Example:
       set string “Fred Joe bob Steve”
       regsub {bob} $string {Bob} new_string

       STRING MAP :
         string map can be used as a alternative to regsub.
expect1.11> set ip 1.1.1.1
expect1.13> string map {. _} $ip
1_1_1_1
expect1.14> set ip ABCDED
expect1.18> string map -nocase {D d} $ip
ABCdEd
expect1.19>

Tcl Procedures
       New commands can be added through Tcl procedure
       “proc” command defines a procedure:
proc 
Example:
proc sub1 { x }{ set result [ expr $x-1]; return $result}

Tcl Procedures
       Procedures behave just like built-in commands:
sub1 3                   2
       Default return value of the procedure is the value of last expression in the procedure
       Arguments can have defaults:
proc decr {x {y 1}} {
    expr $x-$y
}
decr 5 4 1
decr 7                    6
       Scoping: local and global variables.

       Tcl Procedures
Variable-length argument lists “args” argument:
                proc sum {args} {
   set s 0
                                foreach i $args {
        incr s $i
   }
                return $s
                }
%sum 1 2 3 4 5
15
%sum
0
       Procedure provides following benefits
         Easy maintenance – changes needs to be made only at one place
         Saves space, time and effort as a function is implemented only once
         Procedures can be shared when placed in “libraries”

Tcl Procedures:
       Displaying procedure information
         info procs ??              Returns a list of currently defined procedure names
         info args     Returns the argument list for procedure
         info body Returns the body of 
       proc sub { x { y 1 } } {
             return [ expr $x - $y ]
       }
       % sub 7 3
       4
       % sub 5
       4
       % info procs
       auto_load_index unknown auto_import auto_execok auto_qualify auto_load sub history tclLog
       % info args sub
       x y
       % info body sub
             return [ expr $x - $y ]
       %

Global variables
       global varname ?varname ...?
       This command has no effect unless executed in the context of a proc body. If the global command is executed in the context of a proc body, it creates local variables linked to the corresponding global variables 
proc accum {string} { 
global accumulator 
append accumulator $string \n 

EVAL Command
       eval - Evaluate a Tcl script 
       eval arg ?arg ...
       Eval takes one or more arguments, which together comprise a Tcl script containing one or more commands. Eval concatenates all its arguments in the same fashion as the concat command, passes the concatenated string to the Tcl interpreter recursively, and returns the result of that evaluation (or any error generated by it). Note that the list command quotes sequences of words in such a way that they are not further expanded by the eval command. 
EVAL Command (Contd)
       Example:
       set script { 
       puts "logging now" 
       lappend $myCurrentLogVar } 
       set myCurrentLogVar log1 
       # Set up a switch of logging variable part way through!
        after 20000 
       set myCurrentLogVar log2
        for {set i 0} {$i<10} {incr i} { 
       # Introduce a random delay 
       after [expr {int(5000 * rand())}] update ;
       # Check for the asynch log switch 
       eval $script $i [clock clicks] } 

Packages:
       Tcl provides a more powerful mechanism for handling reusable units of code called packages
       A package is simply a bundle of files implementing some functionality, along with a name that identifies the package, and a version number that allows multiple versions of the same package to be present 
       A package can be a collection of Tcl scripts, or a binary library, or a combination of both 

How to Create Package:
       Adding a package provide statement to your script 
       Creating a pkgIndex.tcl file. 
       Installing the package where it can be found by Tcl. 
       Commands
       package require ?-exact? name ?version?
       package provide name ?version?

Sample Packages:
Example:
package require TclUtils

Tcl Namespaces:
       Tcl namespaces allow you to apply a prefix to a procedure name to avoid overriding procedures in the global namespace with the same name
       Namespaces also allow you to define variables accessible only to procedures within the namespace
       In both cases, namespaces result in reduced namespace collision and remove clutter from the global namespace

The Global Namespace:
       By default, procedures and variables are defined in the global namespace
       Procedures defined in the global namespace are accessible to all other procedures

                proc foo {} {puts “hello world”}
                proc bar {} {puts [foo]}

       Variables in the global namespace are accessible to procedures via the global command
                proc foo {} {
    global my_variable
    …
}
       Procedures and variables in the global namespace with the same name overwrite each other (namespace collision)

Defining a Namespace:
       To avoid namespace collision, Tcl library should define all procedures and variables in a private namespace
       Use the Tcl namespace eval command to define a private namespace
                namespace eval ::random {
    …
}
       Note: By convension, namespaces have the same name as the package with a lower case first character

Defining Procedures in a Namespace:
       To add a procedure to a namespace, simply precede the name of the procedure with a fully qualified namespace name
                proc ::random::get {} {
    # Return a random number
}
       Separate the namespace name from the procedure name with double colons
Precede the name with double colons to anchor it in the global namespace (optional

Defining Variables in a Namespace:
       Private variables can be added to a namespace so that they’re accessible to all procedures within the namespace
       This is done by defining the namespace in the namespace eval body and referencing the variable from a procedure using the variable command
                namespace eval ::atsdbg {
    variable isEnabled 0
}

proc ::atsdbg::enable {} {
    variable isEnabled

    set result $isEnabled
    set isEnabled 1

    return $result
}

Procedure and Variable Access:
       To call a procedure defined in a namespace, simply precede the procedure name with the name of it’s namespace
                ::atsdbg::enable
       To access a variable within a namespace, precede the variable name with the name of the namespace
                puts $::atsdbg::isEnabled
       To explicitly access a procedure or variable in the global namespace, precede the name with a double colon
                puts $::auto_path
::info tclversion


No comments:

Post a Comment

Note: only a member of this blog may post a comment.