Introduction à Tcl 8.4
par ulis
© ulis, 2006
Licence NOL
INDEX
Les règles de base 5
Avant-goût 5
13. Constante chaîne protégée 10
16. Procédures et environnements 12
17. Environnement d'exécution 12
18. Namespaces (programmation avancée) 13
Les commandes de base 16
Les commandes de chaînes 24
3. Accès à un caractère dans une chaîne 24
5. Recherche du premier index d’une sous-chaîne dans une chaîne 25
6. Recherche du dernier index d’une sous-chaîne dans une chaîne 25
7. Ajout d’une sous-chaîne en fin de chaîne 25
8. Remplacement d’une sous-chaîne dans une chaîne 25
9. Remplacement de sous-chaînes dans une chaîne 26
10. Changement de casse dans une chaîne 26
11. Autres commandes de chaîne 26
Les commandes de listes 27
5. Modification d’un élément 28
6. Recherche de l’index d’un élément 28
7. Ajout d’éléments en fin de liste 28
8. Insertion d’éléments dans une liste 28
9. Remplacement d’éléments dans une liste 29
11. Concaténation de listes 29
12. Création d'un chaîne à partir d'une liste 30
13. Création d'un liste à partir d'une chaîne 30
Les commandes de tableaux 31
2. Création d’un tableau, ajout dans un tableau 31
4. Nombre d’éléments d’un tableau 31
5. Référencement d’un tableau 32
6. Suppression dans un tableau 32
7. Noms des éléments d’un tableau 32
Les commandes d'entrée-sortie 34
2. Ouverture d'un canal non socket 34
3. Ouverture d'un canal socket 34
4. Lecture d'un fichier ou d'un buffer sur un canal 35
5. Lecture d'une ligne sur un canal 35
Lien utiles 37
Ce document est diffusé suivant la licence NOL (pas d’obligation pour vous ni pour moi).
Tcl est un langage de script inventé par John Ousterhout qui inventa aussi Tk, le Tool Kit graphique associé à Tcl.
Histoire de Tcl/Tk : http://www.tcl.tk/about/history.html
Voici un premier exemple commenté pour avoir un avant-goût de ce qu'est Tcl :
Ce petit programme (script) lit un fichier et remplace toutes les tabulations par des blancs.
# ===========================
# transform tabs into spaces
# ===========================
# -----------------
# defining the proc
# parm1: input file name or – (stdin)
# parm2: output file name or – (stdout)
# parm3: tabs size (defaults to 8)
# -----------------
# returns the count of lines
# -----------------
Commentaires. Ils sont introduits par le caractère #.
proc tab2space {ifn ofn {tabs 8}} \
Définition d'une procédure.
Les paramètres sont entre accolades ({}).
{tabs 8} indique que le paramètre tabs a 8 pour valeur par défaut.
L'anti-slash (\) de fin de ligne indique que la ligne logique continue sur la prochaine ligne physique.
La définition d'une procédure a pour structure : proc nom args body.
args et body sont entre accolades pour grouper leurs éléments.
{
# open input file
if {$ifn == "-"} { set ifp stdin } \
else { set ifp [open $ifn r] }
Commande if. Elle a pour structure (simplifiée) : if cond then-body else else-body.
La condition et les deux bodies sont entre accolades pour grouper leurs éléments.
Le dollar ($) devant ifn indique qu'il s'agit d'une variable (et non d'une constante chaîne) et qu'on veut utiliser la valeur de la variable.
Les guillemets (" ") autour de – sont obligatoire pour indiquer que le signe == compare des chaînes (et non des nombres).
La commande set permet de donner une valeur à une variable. Ainsi set ifp stdin donne la valeur stdin à la variable ifp.
Dans [open $ifn r] les crochets ([ ]) indiquent qu'il faut évaluer le script immédiat qu'ils contiennent et remplacer l'ensemble de l'expression par la valeur retournée par le script. Ici, le résultat de la commande open.
# open output file
if {$ofn == "-"} { set ofp stdout } \
else { set ofp [open $ofn w] }
# read each line
set count 0
while {![eof $ifp]} \
Commande while. Elle a pour structure while cond body. La condition et le body sont entre accolades pour grouper leurs éléments.
{
set line [gets $ifp]
while {[set p [string first \t $line]] != -1} \
Commande string. Multiforme, elle est très complète. Ici l'opération first permet de retourner l'indice du premier caractère tabulation (\t) dans la chaîne contenue dans line.
{
set n [expr {$p % $tabs}]
Commande expr. Elle permet de faire des calculs. Comme elle analyse elle-même ses arguments, les accolades autour de l'expression empêchent Tcl de le faire de façon anticipée.
if {$n == 0} { set n $tabs }
set beg [string range $line 0 [incr n -1]]
Opération range de la commande string. Elle permet de sélectionner une sous-chaîne.
Commande incr. Elle incrémente la variable d'une certaine valeur et retourne la valeur de la variable.
set end [string range $line 0 [incr n 2] end]
set line "$beg[string repeat " " $n]$end"
}
puts $ofp $line
Commande puts. Elle envoie sur un canal ouvert en sortie une chaîne suivie d'un saut de ligne.
incr count
}
# return count
Commande return. Elle permet de sortir de la procédure en renvoyant un résultat. Ici le nombre de lignes traitées.
return $count
}
# -----------------
# using the proc
# -----------------
package require Tk
Commande package. Elle gère les packages. Ici l'opération require demande le chargement de l'extension Tk qui contient l'interface graphique portable de Tcl.
# get input file name
set ifn [tk_getOpenFile -title "tab2space: input file"]
Commande tk_getOpenFile. Elle fait partie de Tk. Elle ouvre une boîte de dialogue qui permet de choisir un fichier.
Elle peut avoir plusieurs arguments nommés. Ici c'est le titre (option -title) qui est donné.
# exit if no name
if {$ifn == ""} { exit }
Commande exit. Elle permet de terminer l’application.
# show console for result
catch { console show }
Commande console (avec son option show). Elle permet d'afficher une console sur les systèmes non Unixiens.
Commande catch. Elle récupère les erreurs (pour les systèmes Unixiens la commande console n'existe pas).
# call proc
tab2space $ifn - 2
Appel de la procédure avec ses arguments. L'argument - indique que le fichier de sortie est la sortie standard (console).
Voici à nouveau l'exemple mais non commenté :
# ===========================
# transform tabs into spaces
# ===========================
# -----------------
# defining the proc
# -----------------
# parm1: input file name or – (stdin)
# parm2: output file name or – (stdout)
# parm3: tabs size (defaults to 8)
# -----------------
proc tab2space {ifn ofn {tabs 8}} \
{
# open input file
if {$ifn == "-"} { set ifp stdin } \
else { set ifp [open $ifn r] }
# open output file
if {$ofn == "-"} { set ofp stdout } \
else { set ofp [open $ofn w] }
# read each line
set count 0
while {![eof $ifp]} \
{
set line [gets $ifp]
while {[set p [string first \t $line]] != -1} \
{
set n [expr {$p % $tabs}]
if {$n == 0} { set n $tabs }
set beg [string range $line 0 [incr n -1]]
set end [string range $line 0 [incr n 2] end]
set line "$beg[string repeat " " $n]$end"
}
puts $ofp $line
incr count
}
# return count
return $count
}
# -----------------
# using the proc
# -----------------
package require Tk
# get input file name
set ifn [tk_getOpenFile -title "tab2space: input file"]
# exit if no name
if {$ifn == ""} { exit }
# show console for result
catch { console show }
# call proc
tab2space $ifn - 2
Un mot est une suite de caractères qui se termine par un espace, la fin de la ligne ou la fin du script.
Un espace séparateur de mots peut être remplacé par une tabulation.
some words
Une ligne est une suite de mots qui se termine par un caractère fin de ligne.
Il est possible de continuer une ligne (logique) sur la ligne (physique) suivante en protégeant le caractère fin de ligne par un anti-slash (\).
# this is \
a line
Une commande est une liste d'éléments dont le premier est le nom de la commande et les suivants sont des arguments.
Une commande se termine au premier caractère point-virgule (;), à la fin de la ligne ou à la fin du script qui la contient.
cmd arg1 arg2
Une commande retourne toujours un résultat (même vide).
Il n’y a pas de structure de contrôle : if , while… sont des commandes.
Il n’y a pas de différences entre les commandes définies dans Tcl et les commandes définies dans le script (au moyen de la commande proc) : elles sont évaluées de la même façon.
Un commentaire est une suite de mots dont le premier est le caractère dièse (#) et se termine par une fin de ligne.
Un commentaire se termine à la fin de la ligne ou à la fin du script qui le contient.
# this is a comment
Sur sa ligne, un commentaire peut être précédé par des commandes (terminées par des points-virgules).
cmd1 args1; cmd2 args2; # this is a comment
Piège 1 :
Dans ce cas le point-virgule terminant la dernière commande est obligatoire.
Piège 2 :
Voir le piège de la section 14 (Constante chaîne protégée) pour les accolades incluses dans un commentaire qui doivent être appairées ou protégées.
Un script Tcl est une suite de commandes et de commentaires.
puts "Hello world!"; # display Hello on the console
exit; # exit from the script
Un script se termine à la fin du fichier qui le contient (script global), à la fin de la constante chaîne qui le contient (corps de procédure ou d’une autre commande), au crochet fermant (script immédiat).
Un script retourne toujours un résultat (même vide). Le résultat d’un script est le résultat de la dernière commande du script qui a été exécutée.
Le script global est inclus dans un fichier. Son exécution par Tcl correspond à l’application.
Un script immédiat est un script entouré par des crochets ([ ]) et qui ne contient pas de fin de ligne (non protégée).
set a [cmd1 args1; cmd2 args2; # comment]
Remarque 1 :
Un script immédiat peut contenir des chaînes de caractères qui contiennent des fins de lignes.
set answer [dialog "choose:
1 – continue
2 – cancel"]
Remarque 2 :
Un script immédiat contenu dans une constante chaîne est considéré comme un tout et équivalent à son résultat.
set answer "choice:\n\t[dialog "choose:
1 – continue
2 – cancel"]"
Une donnée peut être de type :
scalaire : un seul nom, une seule valeur,
set a 1
liste : un seul nom, une suite de valeurs,
set a [list 1 2 3 4 5]
tableau associatif : un nom global et un nom (clef) par valeur.
array set {one 1 two 2 three 3 four 4 five 5}
Scalaire
La valeur d'une donnée de type scalaire est TOUJOURS une chaîne de caractères.
Cette chaîne de caractères peut être interprétée comme une date, un entier, un nombre réel...
Liste
La valeur d'une donnée de type liste est une suite de valeurs scalaires (donc de chaînes de caractères).
Une liste peut être représentée par un chaîne de caractères utilisant des accolades pour le groupage et un espace pour la séparation des items.
En fait, Tcl ne différencie pas les données de type scalaire et les données de type liste, et les considère toutes comme des chaînes de caractères. Par contre, il existe des instructions qui interprètent les données scalaires comme des listes. On en fait un type à part à cause de l'importance des listes dans Tcl (les commandes sont des listes dont le premier élément est le nom de la commande).
set a {1 2 3 4 5}
fournit la même liste que précédemment.
Tableau associatif
Une donnée de type tableau n'a pas de valeur globale mais autant de valeurs scalaires que le tableau contient d’éléments.
Une variable est une donnée qui a un nom et une valeur.
Une donnée nommée de type scalaire est une variable.
Une donnée de type tableau est toujours nommée mais N'est PAS une variable (car un tableau n'a pas de valeur globale).
Les éléments de tableau sont des variables.
Le nom d'une variable permet de la référencer, c'est à dire de retrouver sa valeur.
set b $a
Le $ devant le nom de la variable a indique qu'il s'agit d'un référencement.
Un nom standard est une suite de lettres, de chiffres et de caractères souligné (_).
my_var
Un nom non standard peut contenir n'importe quel caractère sauf des accolades.
my'var
Le nom d'un élément de tableau est le nom du tableau suivi de l’index référençant l'élément et enfermé entre parenthèses.
my_array(name_of_the_element)
Pour référencer une variable dont le nom est standard, on précède son nom par le signe dollar ($).
$my_var
$my_array(name_of_the_element)
Pour référencer une variable dont le nom est non standard, il faut protéger le nom en l’enclosant dans des accolades ({}) et faire précéder l'ensemble par le signe dollar ($).
Piège :
Si l’index d’un élément de tableau est non standard, le nom de cet élément est non standard et doit être protégé.
${my'var}
${my'array(name_of_the_element)}
${my_array(name'of'the'element)}
Dans le cas des variables globales et des variables de namespaces, il existe un nom complet qui permet toujours de référencer –sans ambiguïté– la variable (cf. les namespaces, ci-après).
Piège :
Il n’est pas possible d’obtenir l’ensemble des valeurs d’un tableau en précédant le nom du tableau par un dollar.
Une donnée n’a pas besoin d’être déclarée.
Une donnée est définie dès qu’elle a une valeur.
La commande variable déclare une variable sans la définir (la variable n’a pas de valeur). Elle n’est utilisée que pour les namespaces.
Une valeur scalaire définit une variable scalaire.
La première définition d'un élément déclare un tableau (la variable ne peut plus être scalaire).
set scalar 1; # defining a scalar
set array(element) 1; # defining an array
Une chaîne protégée est une suite de caractères entre accolades ({...}).
{this is a protected string}
Si la chaîne protégée contient des accolades (ouvrantes ou fermantes), celles-ci doivent être appairées sinon elles doivent être précédées par un anti-slash (\).
Une chaîne peut contenir des sauts de ligne.
Une chaîne protégée n’est jamais interprétée pendant l’évaluation des arguments.
Piège :
Si une chaîne protégée contient un script (cas TRES fréquent), dans ce script les accolades apparaissant dans les commentaires et dans les chaînes standards doivent être (globalement) appairées ou protégées par un anti-slash.
Une chaîne standard est une suite de caractères entre guillemets ("…").
"this is a standard string"
Si la chaîne contient des guillemets, ceux-ci doivent être précédés par un anti-slash (\).
Une chaîne peut contenir des sauts de ligne.
Une chaîne standard est interprétée pendant l’évaluation des arguments. C’est à dire que les références à des variables sont remplacées par la valeur des variables et les script immédiats entre crochets sont remplacées par leur résultat.
set type standard
set s "this is a $type string"
Pour éviter l’interprétation, les signes dollar ($) et les crochets ouvrants ([) peuvent être protégés par un anti-slash (\).
Remarque :
Un script immédiat contenu dans une constante chaîne est considéré comme un tout et équivalent à son résultat. Il peut donc contenir des espaces non protégés et des constantes chaînes.
set answer "choice:\n\t[dialog "choose:
1 – continue
2 – cancel"]"
Piège :
Voir le piège de la section 14 (Constante chaîne protégée) pour les accolades incluses dans une chaîne standard qui doivent être appairées ou protégées.
Evaluation d’un script
Quand un script est évalué, chaque commande est évaluée dans l’ordre d’écriture.
Le résultat d’un script est le résultat de la dernière commande évaluée.
Evaluation d’une commande
Avant d’évaluer la commande, tous les éléments de la commande sont évalués.
Le nom de la commande peut être lui-même évalué.
Cette évaluation n’a lieu qu’une fois.
Ensuite la commande est invoquée en lui passant les arguments ainsi obtenus.
set _set set
set _a a
set _1 1
$_set $_a $_1
Après évaluation de $_set, $_a et $_1, la commande set a 1 est évaluée.
Evaluation des éléments
Un élément est une suite de caractères sans espaces non protégés qui peut comporter des références à des variables et des invocations de script immédiats.
set prefix "the result is: "
puts $prefix[compute some result]
Si la suite de caractères contient des espaces non protégés (hors accolades autour d'un nom de variable et hors crochets d'un script immédiat) elle doit être dans une chaîne de caractères.
puts "the result is: [compute some result]"
puts "the result is: ${some result}"
Un élément résultant est obtenu après avoir remplacé dans le texte ou dans la chaîne standard les références à des variables par leur valeur et les scripts entre crochets par leur résultat.
L'élément résultant peut contenir des espaces, mais dans ce cas il demeure un élément unique (les frontières de mot ne changent pas).
Le script
set prefix "the result is: "
set result "this is the result"
puts $prefix$result
renvoie sur la console "the result is: this is the result".
Evaluation d’un script immédiat
Un script immédiat est évalué comme un script à la différence que les variables et les commandes référençables et/ou définies appartiennent à la procédure ou au script englobant le script immédiat.
set init 10
set x2 [set x1 $init] ; # returns 10
Une procédure nommée peut être invoquée (appelée) par son nom. L'invocation d’une procédure initialise les paramètres de la procédure par les arguments de l'invocation avant d'exécuter la procédure.
proc max {n1 n2} \
{
if {$n1 > n2} { set res $n1 } else { set res $n2 }
}
set m [max $m 10]
Invocation
On appelle environnement (ou contexte) d'invocation l'ensemble des variables et commandes visibles au moment de l'invocation.
L’environnement d'invocation des commandes exécutées hors de toute procédure s’appelle l’environnement global.
Exécution
On appelle environnement (ou contexte) d'exécution l'ensemble des variables et commandes visibles à l'intérieur de la procédure quand elle est exécutée suite à une invocation.
Un script immédiat entre crochets est considéré comme une procédure anonyme et est exécuté dans son environnement d’invocation.
Les variables définies dans une procédure sont locales à la procédure.
Les variables définies hors de toute procédure sont globales.
Toutes les procédures sont globales (quand elles sont déclarées en dehors des namespaces, voir plus loin).
Il est possible dans une procédure de référencer :
les variables locales des procédures appelantes (commande upvar),
les variables globales (commande global),
les variables des namespaces (voir plus loin).
set max 10
proc check {n} \
{
upvar 1 max lmax
if {$n > $lmax} { error "n exceeds $lmax" }
}
La variable globale max est ajoutée à l'environnement d'exécution de la procédure sous le nom lmax.
set max 10
proc check {n} \
{
global max
if {$n > $max} { error "n exceeds $max" }
}
La variable globale max est ajoutée à l'environnement d'exécution de la procédure (sous son nom).
Il est aussi possible d’exécuter une procédure dans l’environnement d’une procédure appelante (commande uplevel).
set max 11
proc test {} \
{
uplevel 1 { if {$max > 10} { error "$max too big" } }
}
test
Lors de l'exécution de la procédure test, la variable max sera prise dans le contexte englobant la procédure, c'est à dire l'environnement global (où la variable max est définie).
Il est aussi possible d'exécuter une procédure dans son environnement de définition si c'est un namespace (voir ci-dessous).
Il existe des environnements indépendants des procédures et hiérarchisés. Ils sont nommés namespaces et gérés par la commande namespace.
L’environnement global est considéré comme le premier namespace et a un nom vide.
Les variables et commandes d’un namespace peuvent être référencées par ::namespace::name.
(En toute logique une variable ou commande globale devrait être référencée par ::::name. La raison a permis de les référencer par ::name.)
Un namespace contient des définitions de variables et de commandes et définit un contexte d'exécution pour les commandes qui y sont définies.
Déclaration/Définition
Les variables du namespace peuvent être déclarées par la commande variable.
namespace eval ::ns \
{
variable a
proc b {c} \
{
variable a
...
}
}
La variable a de la procédure b EST la variable a définie dans le namespace.
Cette même commande permet de définir la valeur de la variable déclarée.
namespace eval ::ns \
{
variable a 0
...
}
Pour ajouter à son environnement d'exécution des variables du namespace, une procédure définie dans un namespace utilise aussi la commande variable.
Il est possible de définir une variable ou une procédure d'un namespace en précédant son nom dans la définition par le nom du namespace.
namespace eval ::ns {}
set ::ns::a 0
proc ::ns::b {c} { ... }
C'est équivalent à l'exemple précédent.
Référence et invocation
Il est possible de référencer une variable ou d’évaluer une procédure définie dans un namespace en précédant son nom par le nom du namespace.
puts $::ns::a
puts [::ns::b ...]
Environnements
Une procédure définie dans un namespace et invoquée hors de son namespace est quand même exécutée dans le contexte de son namespace (c'est ce qui permet de référencer les variables du namespace déclarées par la commande variable dans la procédure).
namespace eval ::ns \
{
variable a
proc b {c} \
{
variable a
...
}
}
namespace eval ::ns2 \
{
set a 1
set b [::ns::b $a]
}
Lors de l'invocation de la procédure ::ns::b dans le namespace ::ns2, la variable a dont la valeur est passée en argument est la variable a du namespace d'invocation ::ns2.
Mais pendant l'exécution de la procédure ::ns::b, la variable a définie par variable a et référencée dans la procédure est la variable a du namespace ::ns où est définie la procédure.
En résumé : une procédure définie dans un namespace peut être invoquée partout et ses arguments sont évalués normalement (dans le contexte d'invocation), mais son contexte d'exécution reste son namespace de définition.
Il est possible de garder le namespace de déclaration de la procédure comme contexte d'invocation au moyen de la commande namespace code.
Noms relatifs/absolus
Pour référencer une variable d'un namespace défini au même niveau que la référence, il suffit de faire précéder le nom de la variable par le nom du namespace suivi de ::.
namespace eval ns { variable a }
set ns::a 1
Ce nom est relatif au namespace courant (ou à l'environnement global qui est le père de tous les namespaces).
Un nom relatif à l'environnement global est dit absolu car il est sans ambigüité et peut être utilisé dans toutes les circonstances. Tous les noms commençant par :: sont des noms absolus.
namespace eval ::ns1 { variable a }
namespace eval ::ns2 { set ::ns1::a 1 }
Un script Tcl est une suite de commandes.
Une commande est composée d’un mot-clef suivi d’arguments.
Les arguments peuvent être :
des mots,
des chaînes protégées,
des chaînes standards,
des références à des variables,
des évaluations de script immédiats.
# a Tcl script example
set fn myscript.tcl ;# the file name
set fp [open $fn] ;# opening the file
set script [read $fp] ;# reading the file
close $fp ;# closing the file
Le script, les références à une variable, les chaînes standards et les script immédiats entre crochets sont évalués et remplacés par leur valeur ou résultat.
$ remplace la variable par sa valeur.
[] remplacent la commande par son résultat.
"" encadrent une chaîne standard qui est évaluée.
{} encadrent une chaîne protégée (non évaluée).
\ enlève toute signification particulière au caractère qui suit.
# introduit un commentaire (si en début d’instruction).
A une invocation et à une exécution sont associés des environnements qui comprennent les variables et les commandes visibles lors de cette invocation ou de cette exécution. Ces environnements sont manipulables.
La commande set permet de modifier et de référencer une variable.
set varName ?value?
varName est le nom d’une variable ou un élément de tableau.
value est une chaîne de caractères ou une liste.
Modifier :
set varName value
set arrName(element) value
Référencer :
set varName
set arrName(element)
Résultat équivalent avec :
$varName
$arrName(element)
La commande puts permet d’écrire son argument suivi d’un caractère saut de ligne sur un canal.
puts ?-nonewline? ?channel? string
–nonewline permet de supprimer le caractère saut de ligne.
channel est le canal d’écriture (stdout, résultat d’un open...)
En l'absence de canal l'écriture est faite sur stdout (sortie standard, c’est à dire la console).
string est la chaîne qui est écrite.
puts $var1
La commande proc permet de définir une procédure.
Une procédure peut recevoir des arguments et retourne un résultat.
proc name parms body
name est le nom de la procédure.
parms est une liste (qui peut être vide) de paramètres décrivant les arguments reçus par la procédure lors de son invocation (appel).
Chaque élément de la liste correspond à un argument obligatoire s’il n’a pas de valeur par défaut et s’il est différents de args situé en dernière position.
Si le dernier élément de la liste est args il sera remplacé par la liste des derniers arguments qui n’auront pas été décrits dans les paramètres.
parm1 {parm2 default2} args
default2 est la valeur par défaut du paramètre parm2.
args représentent la liste des arguments suivants parm2 (la liste peut être vide).
body est un script qui peut référencer les éléments de la liste des paramètres
Lors de son exécution, une instruction return retourne à la commande suivant l’appel de la procédure. Si l’instruction return est suivie d’une valeur, c’est cette valeur qui sera le résultat de l’appel.
Le script body peut référencer de façon simple :
les paramètres de la procédure,
les variables globales déclarées par la commande global,
les variables locales créées dans la procédure
et les variables rendues visibles par la commande upvar.
Le script peut toujours référencer des variables globales ou de namespaces si elles sont référencées par leur nom absolu (commençant par ::).
Il est licite :
de définir une procédure dans une procédure,
de redéfinir une procédure.
Une procédure définie dans une procédure englobante est connue dans le namespace contenant la déclaration de la procédure englobante (à moins de préfixer le nom par un nom de namespace).
Il vaut mieux mettre sagement le script entre accolades.
On peut supprimer une procédure au moyen de l’instruction rename.
proc getFile (fileName) \
{
set fp [open $fileName]
set res [read $fp]
close $fp
return $res
}
La commande global redéclare dans l’environnement local une variable globale.
global varName ?varName-n?...
varName (respectivement varName-n) est le nom d’une variable globale (donc déclarée en dehors d’une procédure) qui va être connue au niveau local (dans une procédure).
set max 10
proc compute {args} { global max ; ... }
Remarque :
On peut référencer une variable globale depuis n'importe quel environnement en préfixant son nom par ::.
proc a {} { set ::v 1; set b $::v; ... }
La commande variable utilisée hors d'une procédure déclare une variable dans le namespace courant.
La commande variable utilisée dans une procédure redéclare dans l’environnement local une variable du namespace courant.
variable ?varName-1 value-1?... varName-n ?value-n?
varName-1 (respectivement varName-n) est le nom d’une variable définie dans le namespace courant.
value-1 (respectivement value-n) est la valeur donnée à la variable varName-1 (respectivement varName-n) .
variable max 10
proc compute {args} { variable max ; ... }
Remarque 1 :
La commande variable utilisée dans le script global (hors procédure) définit une variable globale.
La commande variable utilisée dans une procédure globale référence une variable globale.
En effet le script global et les procédures globales sont dans le namespace global.
Remarque 2 :
On peut référencer une variable d'un namespace depuis n'importe quel environnement en utilisant son nom absolu.
proc a {} { set ::v 1; set b $::v; ... }
La commande upvar redéclare dans l’environnement local une variable d’un environnement appelant.
upvar ?level? varName localName ?varName-n localName-n?...
level indique l’environnement visé.
0 environnement de la procédure
1 environnement de la procédure appelante
...
#0 environnement global
#1 environnement de la première procédure
...
Par défaut level vaut 1.
Pour éviter toute ambiguïté avec l’argument qui suit et pour des raisons de performance, il vaut mieux toujours indiquer level.
varName (respectivement varName-n) est le nom d’une variable d’un environnement englobant (déclarée en dehors d’une procédure) qu’on veut connaître au niveau local (dans une procédure).
set max 10
proc compute {args} { upvar 1 max mx ; ... }
La commande uplevel exécute un script dans un environnement appelant.
uplevel ?level? arg ?arg ?...
level indique l’environnement visé.
0 environnement de la procédure
1 environnement de la procédure appelante
...
#0 environnement global
#1 environnement de la première procédure
...
Par défaut level vaut 1.
Pour éviter toute ambiguïté avec l’argument qui suit et pour des raisons de performance, il vaut mieux toujours indiquer level.
Les différents arg sont concaténés avec la commande concat pour former le script exécuté.
Piège :
La commande concat transforme une liste en une suite d’éléments. Il faut donc protéger par [list …] les arguments que l’on veut conserver sous forme de liste et les constantes chaîne vides.
La commande expr évalue une expression.
expr exp
set sum [expr {$a + $b}]
La syntaxe est proche des expressions en C.
La commande a son propre analyseur syntaxique et c’est pourquoi il vaut souvent mieux mettre l’expression entre accolades pour éviter l’évaluation anticipée par Tcl.
Il vaut mieux mettre sagement l’expression entre accolades.
Fonctions arithmétiques :
int() double() abs() ceil() cos() log() …
Opérateurs arithmétiques :
+ - * / %
Opérateurs booléens :
&& || == != < > <= >=
Opérateur ternaire :
? :
Les constantes chaînes de caractères doivent être entre guillemets.
Les nombres peuvent être entiers ou flottants (syntaxe C). Ils sont contenus dans des chaînes (sans guillemets).
La valeur booléenne faux est 0 et la valeur vrai est 1 (il y en a d’autres).
Le résultat d’une expression est toujours une chaîne, même si elle représente un nombre.
La commande eval évalue un script. Elle est équivalente à uplevel 0.
Pour évaluer le script elle concatène (comme la commande concat) en une chaîne de caractères la liste des arguments (déjà évalués) et évalue le script résultant.
Il y a donc deux niveaux d’évaluation :
l’évaluation des arguments de eval par Tcl,
l’évaluation par eval (qui appelle récursivement Tcl).
eval arg-1 ?... arg-n ?
eval $cmd $opts $args
Piège :
Les deux niveaux d’évaluation et le passage d’une liste à une chaîne peuvent entraîner des phénomènes subtils et difficiles à analyser.
set str "a string"
eval puts $msg
ici eval va essayer d’interpréter : "puts a string"
où a sera considéré comme le canal sur lequel écrire et string comme la chaîne à écrire.
Remarque :
puts $msg
ne pose aucun problème.
Piège :
La commande concat transforme une liste en une suite d’éléments. Il faut donc protéger par [list …] les arguments que l’on veut conserver sous forme de liste et les constantes chaîne vides.
La commande incr permet d’incrémenter un nombre entier.
incr varName ?value?
varName est un NOM de variable.
La commande retourne la valeur de la variable après l’avoir modifiée.
value est un nombre entier.
Par défaut la valeur est 1.
incr n –1
Piège :
set n 1
incr $n
est équivalent à :
incr 1
et occasionne une erreur si la variable de nom "1" n’est pas définie (c’est rare qu’elle le soit).
La commande if implémente la structure de contrôle if.
if exp exp-script ?elseif exp1 exp1-script?… ??else? else-script ?
exp est une expression booléenne dont la syntaxe suit celle de la commande expr.
exp_script est un script qui est exécuté si exp a pour valeur vrai (1).
exp1 est une expression booléenne qui est évaluée si exp a pour valeur faux (0).
exp1_script est un script qui est exécuté si exp1 a pour valeur vrai (1).
else-script est un script qui est exécuté si toutes les expressions booléennes précédentes sont fausses.
if {$x < $y} { set x $y } else { set y 0 }
if {$type != "std"} { error "unknown type: $type" }
Il vaut mieux mettre sagement les expressions et les scripts entre accolades.
La commande while implémente la structure de contrôle while.
while exp script
exp est une expression booléenne dont la syntaxe suit celle de la commande expr.
script est un script qui est exécuté tant que exp a pour valeur vrai (1).
Les commandes continue et break situées dans script permettent de passer à l’itération suivante ou de sortir immédiatement de la boucle.
set fact 10
set res 1
set n 1
while {$n <= $fact} \
{
incr n
set res [expr {$res * $n}]
}
Il vaut mieux mettre sagement l’expression et le script entre accolades.
Piège :
l’expression, sans espace, peut être écrite sans les accolades :
while $n<=$fact { script }
c’est équivalent à :
while 1<=1 { script }
(car les arguments sont interprétés avant l’appel de la commande while)
c’est une boucle infinie.
Equivalent de do :
while 1 { script }
La commande for implémente la structure de contrôle for.
for init-script exp next-script script
Equivalent sémantique :
init-script
while {exp} { script; next-script }
init-script est le script d’initialisation de la boucle.
exp est l’expression de contrôle de la boucle : la boucle est exécutée tant que sa valeur est vrai.
next-script est le script d’avancement exécuté après chaque itération de la boucle.
script est le script principal exécuté à chaque itération de la boucle.
Les commandes continue et break situées dans script permettent de passer à l’itération suivante ou de sortir immédiatement de la boucle.
set max 10
for {set i 0} {$i < $max} {incr i} { puts $i }
Il vaut mieux mettre sagement l’expression et le script entre accolades.
La commande foreach est une boucle for spécialisée pour les listes.
foreach varName list script
foreach {varName-1 ... varName-n} list script
(il existe une forme plus complexe)
varName est le nom d’une variable qui n’a pas besoin d’être déjà définie.
list est une liste de valeurs.
script est le script exécuté pour chaque valeur de la liste.
Les commandes continue et break situées dans script permettent de passer à l’itération suivante ou de sortir immédiatement de la boucle.
Dans la deuxième forme, les n variables varName-1 ... varName-n reçoivent les n valeurs suivantes de la liste.
set list {one two three four}
foreach i $list { puts $i }
Il vaut mieux mettre sagement le script entre accolades.
La commande switch permet de choisir un script parmi n à partir d’une valeur.
switch ?opts? ?--? value { value-1 script-1 ... value-n script-n ?default default-script ? }
(il existe une forme plus complexe)
opts permet de définir le type de comparaison :
-exact comparaison directe
-glob comparaison semblable à celle de la commande glob (*, ? comme sous DOS)
-regexp comparaison semblable à celle de la commande regexp (expressions UNIX)
-- indique la fin des options (utile si la valeur suivante commence par un tiret).
value-1 (respectivement value-n) est une chaîne de caractères comparée à value.
script-1 (respectivement script-n) est le script exécuté si la comparaison d’égalité entre value-1 (respectivement value-n) et value retourne vrai.
default-script est le script exécuté si aucune comparaison ne retourne vrai.
Un seul script est exécuté.
Si est script est réduit à un tiret (-) c’est le script suivant qui est exécuté.
switch –exact -- $op \
{
+ -
- { return compute $op $a $b}
0 { set a 0; set b 0; return 0 }
}
Il vaut mieux mettre sagement le script entre accolades.
Piège :
Surtout ne pas insérer de commentaires à l’extérieur des scripts, ils seraient considérés comme un ensemble de couples valeur-script.
Par exemple :
switch # { # commentaire }
essaiera d’exécuter commentaire.
La commande catch permet de récupérer une erreur et le message associé.
La commande
renvoie 0 s’il n’y a pas d’erreur,
renvoie 1 s’il y a une erreur
et peut renvoyer d’autres valeurs dans des cas spéciaux contrôlés par l’option -code de la commande return.
catch script ?varName?
script est le script à exécuter.
varName est le nom de la variable qui recevra :
en cas d’erreur : le message d’erreur,
sinon : le résultat du script.
set rc [catch { set i $max } msg]
if {$rc == 1} \
{
# error
puts "error: $msg"
} \
else \
{
# no error
puts "result: $msg"
}
Il vaut mieux mettre sagement le script entre accolades.
La commande error permet de signaler une erreur en lui associant un message.
error msg
msg est une chaîne de caractères contenant le message associé à l’erreur.
error "unknown type $type"
Remarque :
Cette erreur pourra être interceptée par la commande catch.
La commande set permet de créer (entre autre) une chaîne.
Les différentes chaînes sont les chaînes protégées et les chaînes standards.
- chaîne protégée (pas d’interprétation) :
set prot {this is a protected string}
- chaîne standard (interprétation) :
set curr "current path : [pwd]"
Remarques :
Tout ce qui n’est pas un tableau est une chaîne.
Une variable créée sous forme de chaîne, et traitée entre-temps comme une liste, garde sa représentation de chaîne.
Une variable crée comme une liste a comme représentation de chaîne tous ses éléments séparés par un espace.
La commande string length retourne le nombre de caractères d’une chaîne.
string length string
string ne doit pas être un tableau.
La commande
string length "string"
retourne 6.
La commande string index permet d’accéder à un caractère d’une chaîne.
string index string index
string est une chaîne.
index indique le rang du caractère :
0 premier caractère
1 deuxième caractère
...
end dernier caractère
end-1 avant-dernier caractère
...
La commande
string index "string" 1
retourne le caractère "t".
La commande string range permet d’accéder à une sous-chaîne.
string range string index1 index2
string est une chaîne.
index1 et index2 indiquent le rang dans la chaîne du premier caractère et le rang dans la chaîne du dernier caractère de la sous-chaîne .
La commande
string range "string" end-1 end
retourne la sous-chaîne "ng".
La commande string first permet de retrouver l’index de la première sous-chaîne trouvée dans une chaîne.
Elle retourne l’index de la sous-chaîne si elle est trouvée, sinon elle retourne –1.
string first string-1 string-2
string-1 est la sous-chaîne à rechercher dans la chaîne.
string-2 est une chaîne.
if {[string first \n $string] == -1} { error "new line not found" }
La commande string last permet de retrouver l’index de la dernière sous-chaîne trouvée dans une chaîne.
Elle retourne l’index de la sous-chaîne si elle est trouvée, sinon elle retourne –1.
string last substring string
substring est la sous-chaîne à rechercher dans la chaîne.
string est une chaîne.
La commande
string last " " $string
retourne l’index du dernier caractère espace dans la chaîne contenue dans la variable string.
La commande append permet d’ajouter une sous-chaîne à la fin de la chaîne.
append varName substring
varName est le NOM d’une variable contenant une chaîne.
substring est une sous-chaîne à ajouter en fin de la chaîne.
Piège :
Contrairement aux autres commandes de chaîne, append a pour premier argument un NOM de variable.
La commande
append "one two three four" " five six"
retourne la chaîne "one two three four five six".
La commande string replace permet de remplacer une sous-chaîne positionnée dans une chaîne par une autre sous-chaîne.
string replace string first last ?substring?
string est une chaîne.
first, last sont les index définissant la sous-chaîne qui va être remplacée.
substring est la sous-chaîne à insérer.
Si elle est absente, la sous-chaîne définie par first et last n’est pas remplacée mais supprimée.
La commande
string replace "one two three four" 0 2 "first"
retourne la chaîne "first two three four five six".
La commande string map permet de remplacer dans une chaîne certaines sous-chaînes par d’autres sous-chaînes.
string map ?-nocase? charMap string
Si l’option –nocase est présente, les comparaisons se font sans différencier majuscules et minuscules.
charMap est une liste de sous-chaînes appairées : les impaires sont les sous-chaînes recherchées et remplacées, les paires sont les sous-chaînes qui remplacent la sous-chaîne qui précède dans la liste.
string est une chaîne.
La commande
string map {one 1 two 2 three 3 four 4} "one two three four"
retourne la chaîne "1 2 3 4".
Les commandes string tolower, string toupper et string totitle permettent de modifier la casse des caractères d’une chaîne.
tolower passe les caractères en minuscules.
toupper passe les caractères en majuscules.
totitle passe le premier caractère du premier mot en majuscule et les autres caractères en minuscules.
string tolower string
string toupper string
string totitle string
La commande
string totitle "THIS IS A STRING"
retourne la chaîne "This is a string".
|
encoding |
convertit les caractères d’une chaîne suivant les différents encodages |
|
format |
formatte une chaîne suivant une spécification (cf. printf) |
|
regexp |
détermine si une chaîne est conforme à une expression régulière |
|
regsub |
substitue dans une chaîne suivant une expression régulière |
|
scan |
scanne une chaîne suivant une spécification (cf. scanf) |
|
string bytelength |
retourne la longueur en octets d’un caractère (suivant l’encodage) |
|
string compare |
compare deux chaînes |
|
string equal |
détermine si deux chaînes sont égales |
|
string is |
détermine le type de donnée que représente une chaîne |
|
string match |
détermine si une chaîne correspond à une expression |
|
string repeat |
crée une chaîne en répétant une sous-chaîne |
|
string trim |
supprime certains caractères aux deux extrémités d’une chaîne |
|
string trimleft |
supprime certains caractères à gauche d’une chaîne |
|
string trimright |
supprime certains caractères à droite d’une chaîne |
|
string wordend |
retourne l’index de la fin d’un mot dans une chaîne |
|
string wordstart |
retourne l’index du début d’un mot dans une chaîne |
|
subst |
évalue une chaîne |
La commande list permet de créer une liste.
list ?string-1 ... string-n?
string-n est le nième élément de la liste.
set l [list one two three four]
Toute chaîne de caractères peut être considérée par Tcl comme une liste de mots séparés par des espaces.
set l "one two three four"
set l {one two three four}
La commande llength retourne le nombre d’élément d’une liste.
llength list
list est une liste.
La commande
llength [list one two three four]
retourne 4.
La commande lindex permet d’accéder à un élément d’une liste.
lindex list index
list est une liste.
index indique le rang de l’élément :
0 premier élément
1 deuxième élément
...
end dernier élément
end-1 avant-dernier élément
...
La commande
lindex [list one two three four] 1
retourne "two".
La commande lrange permet d’accéder à une sous-liste.
lrange list index1 index2
list est une liste.
index1 et index2 indiquent le rang dans la liste du premier élément et le rang dans la liste du dernier élément de la sous-liste.
La commande
lrange [list one two three four] end-1 end
retourne la liste {three four}.
La commande lset (nouveauté pour Tcl 8.4) permet de modifier un élément dans une liste.
Elle retourne la liste modifiée.
lset listName ?index?... value
lset listName {?index?...} value
(les deux formes sont équivalentes)
listName est le NOM d’une liste.
index est un index dans la liste.
value est la valeur à donner à l’élément sélectionné.
Si index est absent ou vide, la commande est équivalente à set listName value : la liste prend la valeur value.
La commande
lset myList {1 2 3 4}
lset myList {} {1 2 3 4}
retourne la liste {1 2 3 4}.
S’il y a plusieurs index, la commande :
set myList {{a b} {b c} {c d}}
lset myList 2 0 ""
retourne la liste {{a b} {b c} {{} d}}.
myList est considéré comme le nom d’une liste, l’élément d’index 2 est sélectionné, considéré comme une sous-liste puis l’élément 0 de cette sous-liste est sélectionné puis remplacé par "" .
La commande lsearch permet de retrouver l’index d’un élément dans une liste.
Elle retourne l’index de l’élément si il est trouvé, sinon elle retourne –1.
lsearch list value
list est une liste.
value est la chaîne de caractères à rechercher parmi les éléments de la liste.
if {[lsearch $list $item] == -1} { error "item not found" }
La commande lappend permet d’ajouter un ou des éléments à la fin de la liste.
Elle retourne la liste modifiée.
lappend listName string-1 ?... string-n?
listName est le NOM d’un liste.
string-n est la n-ième chaîne de caractères à ajouter en fin de liste.
La commande
set l [list one two three four]
lappend l five six
retourne la liste {one two three four five six}.
La commande linsert permet d’insérer un ou des éléments à partir d’un certain rang dans une liste.
Elle retourne la liste modifiée.
linsert list index string-1 ?... string-n?
list est une liste.
index est le rang où seront insérés les nouveaux éléments.
string-n est la n-ième chaîne de caractères à insérer dans la liste.
La commande
linsert {one two three four} 0 zero
retourne la liste {zero one two three four}.
La commande lreplace permet de remplacer un ou des éléments à partir d’un certain rang dans une liste.
Elle retourne la liste modifiée.
lreplace list index1 index2 ?string-1 ... string-n?
list est une liste.
index1 et index2 indiquent le rang dans la liste du premier élément et le rang dans la liste du dernier élément de la sous-liste qui sera remplacée.
string-n est la n-ième chaîne de caractères à insérer dans la liste à partir de index1.
S’il n’y a pas d’élément à insérer, cela revient à une suppression.
La commande
lreplace {one two three four} 1 end others
retourne la liste {one others}.
La commande lsort retourne une liste triée.
lsort ?opts? list
opts est une liste d’options :
-ascii séquence de comparaison ascii
-dictionary comparaison de type dictionnaire
-integer comparaison de type entiers
-real comparaison de type flottants
-command cmd commande de comparaison de deux éléments
-increasing tri en ordre croissant
-decreasing tri en ordre décroissant
-index index tri de sous-listes, index est l’index de la clef dans la sous-liste
-unique supprime les éléments en double
list est une liste.
La commande
lsort {one two three four}
retourne la liste (suivant le tri standard) {four one three two}.
La commande concat permet de créer une liste en concaténant des listes.
Les éléments de chaque liste sont ajoutés à la liste résultante.
concat ?list-1...list-n ?
list-1, ..., list-n sont les listes.
La commande
concat a b {c d e} {f {g h}}
retourne la liste {a b c d e f {g h}}.
Piège :
La commande concat transforme une liste en une suite d’éléments. Il faut donc protéger par [list …] les arguments que l’on veut conserver sous forme de liste et les constantes chaîne vides.
La commande join permet de créer une chaîne à partir d'une liste et d'une sous-chaîne servant de séparateur.
join list ?separ?
list est une liste.
separ est une chaîne de caractères qui sera utilisée comme séparateur.
Si separ est absent, le séparateur sera un espace.
La commande
join {a b c d} ,
retourne la chaîne "a,b,c,d".
La commande split permet de créer une liste à partir d'une chaîne et d'une sous-chaîne servant de séparateur.
split string ?separ?
string est une chaîne de caractères.
separ est une chaîne de caractères dont chacun sera un séparateur.
Si separ est absent, les séparateurs seront les caractères espace, tabulation et saut de ligne.
La commande
split {a:b,c:d} :,
retourne la liste {a b c d}.
Ce que Tcl appelle tableaux (array) sont en fait des tableaux associatifs ou collections : un ensemble de valeurs accessibles à partir d’un nom.
La commande array set crée un tableau en l’initialisant.
array set varName paired-list
varName ne doit pas être le nom d’une variable scalaire.
paired-list doit être une liste avec un nombre pair d’éléments. Les éléments pairs sont les noms des éléments du tableau, les éléments impairs sont les valeurs des éléments du tableau.
array set dirs {root / home ~ current .}
Si la variable existe déjà et est un tableau, array set ajoute les éléments de sa liste aux autres éléments du tableau.
Si un élément existe déjà, il est modifié.
On peut aussi créer un tableau en créant son premier élément.
set dir(root) /
Si la variable existe déjà et est un tableau, set ajoute l’élément aux autres éléments du tableau.
Si l’élément existe déjà, il est modifié.
Une variable scalaire ne peut pas être transformée en tableau.
De même un tableau ne peut pas être transformée en variable scalaire.
La commande array exists permet de tester l’existence d’un tableau.
array exists varName
varName est le nom à tester.
if {![array exists dirs]} { set dirs(root) / }
La commande array size permet de connaître le nombre d’éléments d’un tableau.
array size arrayName
arrayName est le nom du tableau.
La commande
array size dirs
retourne le nombre d’éléments du tableau dirs.
Pour référencer un élément d’un tableau on accole, au nom du tableau, le nom de l’élément entre parenthèses.
set dirs(selected) [pwd]
puts $dirs(selected)
foreach dir {root home current selected} { puts $dirs($dir) }
Il n’est pas possible de référencer un tableau en son entier.
Les commandes
array set nums {1 0.5 2 0.25 3 0.5 4 1.0}
set sum [array_add $nums]
occasionnent une erreur car $nums est illicite.
Pour passer un tableau à une procédure on passe le nom du tableau et on utilise la commande upvar qui rend visible, au niveau de la procédure, une variable du contexte appelant.
proc array_add {arrayName} \
{
upvar $arrayName array
set sum 0.0
foreach key [array names array] \
{ set sum [expr {$sum + $array($key)}] }
return $sum
}
array set nums {1 0.5 2 0.25 3 0.5 4 1.0}
set sum [array_add nums]
La commande array unset permet de supprimer un tableau ou des éléments d’un tableau.
array unset arrayName ?pattern?
arrayName doit être le nom d’un tableau.
pattern est une expression régulière telles que celles utilisées par l’option match de la commande string.
Si pattern est une chaîne vide, le tableau entier est supprimé.
Sinon, toutes les éléments correspondant à pattern sont supprimés.
Après la commande
array unset dirs cur*
tous les éléments du tableau dirs dont les noms commencent par "cur" sont supprimés.
La commande array names permet de retrouver tout ou partie des noms des éléments d’un tableau.
array names arrayName ?pattern ?
arrayName doit être le nom d’un tableau.
pattern est une expression régulière telles que celles utilisées par l’option match de la commande string.
Si pattern est une chaîne vide, tous les noms sont retournés.
Sinon, seuls les noms correspondant à pattern sont retournés.
La commande
array names dirs
retourne les noms de tous les éléments du tableau dirs.
La commande array get permet d’accéder au contenu d’un tableau. C’est le symétrique de array set).
Elle retourne une liste pairée. Les éléments pairs sont les noms des éléments du tableau, les éléments impairs sont les valeurs des éléments du tableau.
array get arrayName ?pattern ?
arrayName doit être le nom d’un tableau.
pattern est une expression régulière telles que celles utilisées par l’option match de la commande string.
Si pattern est une chaîne vide, tous les noms sont retournés.
Sinon, seuls les noms correspondant à pattern sont retournés.
La commande
array get dirs
retourne une liste contenant chaque valeur contenue dans la liste, précédée du nom correspondant (cf. l’exemple de array set).
Piège :
Dans la liste retournée par array get les noms des éléments NE SONT PAS dans l’ordre d’insertion mais dans l’ordre d’accès à la table de hashing utilisée.
De plus il n’y a AUCUN MOYEN de les garder dans un certain ordre.
Pour obtenir une liste triée des éléments d’un tableau il faut passer par les listes.
foreach name [lsort [array names dirs]] \
{ puts "$name\t$dirs($name)" }
Tcl permet de lire et d'écrire vers des canaux d'entré-sortie.
Ceux-ci sont des identifiants (handles) et permettent d'accéder à des périphériques (:COM1, /dev/ttyS0...), des fichiers, des pipe-lines (pipes) ou des sockets.
La commande open permet d'obtenir l'identifiant (handle) d'un canal vers un périphérique, un fichier ou un pipe-line.
L'accès peut se faire en différents modes.
open name ?access ?permissions??
name est le nom du périphérique, du fichier ou un pipe-line.
Un pipe-line est décrit sous la forme "|cmd ?args?" où cmd est le nom d'une commande externe (commande de l'OS) et args est la suite des arguments et/ou redirections tels que fourni au shell.
access
r ouverture en lecture, le fichier doit exister (valeur par défaut)
r+ ouverture en lecture-écriture, le fichier doit exister
w ouverture en écriture, tronque un fichier existant, sinon le crée
w+ ouverture en lecture-écriture, tronque un fichier existant, sinon le crée
a ouverture en ajout, crée le fichier s'il n'existe pas
a+ ouverture en lecture et en ajout, crée le fichier s'il n'existe pas
Remarque:
Il n'y a pas d'option b (pour binaire). Il faut utiliser la commande fconfigure avec l'option translation binary.
permissions est un entier interprété comme sous UNIX (valeur par défaut 0666).
Les commandes suivantes
open /dev/ttyS0
open myFile
open [list |ps –f $user | grep $cmd]
retournent un identifiant vers le canal ouvert.
La commande socket permet soit de définir un socket serveur, soit d'obtenir l'identifiant d'un canal vers un socket.client.
canal serveur
socket -server cmd ?-myaddr server_addr ? server_port
Lors d'une connexion au canal socket serveur Tcl créera automatiquement un nouveau canal socket et exécutera la commande cmd channel client_addr client_port .
channel sera l'identifiant du nouveau canal socket,
client_addr sera l'adresse réseau du client,
client_port sera le numéro de port IP du socket client.
server_addr est l'adresse réseau sur laquelle le socket serveur acceptera des connexions (utile seulement si le serveur a plusieurs adresses réseau).
Si l'option est absente, le socket serveur acceptera des connexions pour toutes les adresses réseau du serveur.
server_port est le port IP sur lequel le socket serveur acceptera des connexions.
proc connection {channel addr port} { ... }
socket -server connection 1234
canal client
socket ?options? server_addr server_port
options sont des options parmi :
-myaddr addr
Cette option est utile si le client a plusieurs adresses réseau. Dans ce cas addr précise l'adresse réseau à utiliser.
-myport port
port précise le numéro de port IP à utiliser du côté client. En l'absence de cette option, le numéro sera choisi par IP.
-async
Si cette option est précisée, le canal socket est en mode asynchrone.
server_addr et server_port sont l'adresse réseau et le port IP du socket serveur auquel on veut se connecter.
La commande
set channel [socket localhost 1234]
retourne l'identifiant du canal socket établi avec le serveur local à l'écoute du port 1234.
La commande read retourne le contenu d'un fichier ou d'un buffer.
read ?-nonewline? channel
read channel count
L'option –nonewline a pour effet de supprimer le saut de ligne en fin de fichier (s'il y en a un).
channel est l'identifiant d'un canal ouvert en lecture ou en lecture-écriture.
Dans la première forme la commande retourne tous les caractères disponibles sur le canal channel.
Dans la deuxième forme la commande retourne count caractères sur le canal channel (ou moins si Tcl rencontre une condition de fin de fichier).
Si le canal est en mode non bloquant, la commande read retourne immédiatement avec tous les caractères disponibles.
Les séquences de fin de ligne sont transformées suivant l'option –translation de fconfigure.
set text [read $channel]
La commande gets retourne une ligne (sans la séquence de fin de ligne).
gets channel ?varName?
channel est l'identifiant d'un canal ouvert en lecture ou en lecture-écriture.
varName est le nom d'une variable qui recevra la ligne.
Si le nom est présent, la commande retourne le nombre de caractères mis dans la variable (ou –1 en cas de fin de fichier).
S'il est omis, la commande retourne la ligne ou une chaîne vide.
En mode non bloquant le commande retourne une ligne vide s'il n'y a pas de ligne complète disponible.
En cas de fin de fichier avant la fin de ligne :
en mode bloquant la commande retourne la ligne incomplète,
en mode non bloquant la commande retourne une chaîne vide.
Remarque :
Les commandes eof et fblocked permettent de distinguer les différents cas où une ligne vide est retournée.
set count [gets $channel line]
if {$count > -1} { ... }
La commande puts permet d'écrire une chaîne de caractères sur un canal.
puts ?-nonewline? ?channel? string
L'option –nonewline empêche la commande d'ajouter une séquence de fin de ligne après la chaîne de caractères.
channel est l'identifiant d'un canal ouvert en écriture ou en lecture-écriture.
Si le canal n'est pas spécifié les caractères sont envoyés sur stdout.
string est la chaîne de caractères à écrire sur le canal.
Les séquences de fin de ligne sont transformées suivant l'option –translation de fconfigure.
Les caractères sont bufferisés. La commande flush permet de forcer l'écriture immédiate sur le canal.
Pour utiliser le mode non bloquant, il faut utiliser la commande vwait pour activer la boucle de traitement des évènements de Tcl.
En mode non bloquant la commande puts retourne immédiatement. Dans ce cas il est préférable d'utiliser fileevent pour savoir quand écrire à nouveau avec puts.
set ::fp [open $::fn w]
fconfigure $::fp -blocking 0
proc write_line {} \
{
puts $::fp [create_line]
if {[incr ::count] == $::max} \
{
close $::fp
set ::ended 1
}
}
fileevent $::fp writable write_line
vwait ::ended
(après écriture du fichier le script est quitté)
wiki francophone
wiki international
forum francophone
http://groups.google.com/group/fr.comp.lang.tcl
forum international
http://groups.google.com/group/comp.lang.tcl
tcltk.free.fr
ulis’ code
http://perso.wanadoo.fr/maurice.ulis/tcl