3. Exemples
3.1 Bonjour
tcl est un langage de commandes, disponible sous Unix et sous Dos, Windows, NT... Il est interprété et utilise beaucoup de listes, chaines, tableaux. Ses primitives sont dérivées de fonctions unix standard. Couplé à tk, il permet d'écrire rapidement des interfaces utilisateurs simples avec des boites, des fenêtres etc. Couplé à tix, il fournit des interfaces encore plus sophistiquées.
L'intérêt de tcl est d'être "petit", gratuit, multi-plateforme. Il est assez facile à apprendre, sans trop de subtilité, un peu long à écrire, assez pénible à débogger mais c'est une façon simple de permettre à des programmes sans interface graphique (dbase, dos,awk, perl...) de communiquer avec des fenêtres windows et X-window...
Une instruction se termine par une fin de ligne ou un point-virgule. Un commentaire commence par un dièse (#). Il faut écrire un point-virgule avant un dièse si on veut mettre un commentaire sur la même ligne qu'une instruction. Ainsi
set somDiv 1 # on a toujours 1 comme diviseurest incorrect. Il faut mettreset somDiv 1 ; # on a toujours 1 comme diviseurSi une ligne est trop longue, on peut mettre un \ pour indiquer que l'instruction se termine. Tout appel de fonction tcl requiert les délimiteurs [ et ]. Un bloc se délimite par { et }. Utiliser des " déclenche une interprétation des variables.
L'affectation se fait par set mais d'autres commandes affectent aussi, comme append (pour concaténer des chaines de caractères). Un calcul doit utiliser l'instruction expr. La plupart des fonctions mathématiques de base existent déjà et sont accessibles via expr. On donne le nom de la variable après set. Toute référence à une variable doit par contre être précédée de $. Exemples d'affectation :
set somDiv 0 set maDate [ clock format [clock seconds] \ -format " Le %d/%m/%y vers %H:%M" ] set debInt [ expr (exp(1.0)) ] set a [incr a 3] ; # met 3 de plus dans a set a [expr $a + 3] ; # met 3 de plus dans a set msgTxt "bon" ; # met bon dans msgTxt append msgTxt "jour" ; # met bonjour dans msgTxt set txtMsg "$msgTxt !" ; # met bonjour ! dans txtMsfOn peut désaffecter par unset. C'est surtout utile pour les tableaux. les tableaux utilisent des références parenthésées dont les indices ne sont pas limités à des entiers. Exemples :
set nbl(0) 12 set tmp($i) [expr 1 + $nb(0)] set tab($i,$j) 0 set prenom "Pierre" set valeur "Pierre" set ref($prenom) $valeur set num($valeur) $prenom
Une boucle "tant_que" se définit par while. On peut ainsi écrire la boucle "pour" traditionnelle de 1 à n par
set i 1 while { $i <= $n } { ... set i [incr i] } ; # fin tant que sur iLa boucle "for" existe et elle a même un dérivé nommé foreach pour le passage en revue de structure.
for { set i 1 } { $i <= $n } { set i [incr i] } { ... } ; # fin pour foreach nomBre { 1998 2000 2025 } { ... maCommande $nomBre }; # fin pour chaque
Un test se fait avec l'instruction if. Compte-tenu de l'interprétation des variables, il faut parfois utiliser des comparaisons de chaines pour garantir le résultat. On peut utiliser else et elsif en option.
L'instruction switch gère les structures de cas multiples. Elle admet les paramètres --, -exact, -regexp, glob pour tester des expressions "globales", "régulières" (comme *.*, [a|A]mis? etc.).
On écrit avec puts et on lit avec gets. De nombreux formats sont possibles (voir plus bas les exemples complets). tcl a de nombreuses fonctions pour les listes, les chaines et les fichiers Citons :
list lindex llength lrange lappend linsert lreplace lsearch lsort concat join split (string) compare first index last length match range tolower toupper trim wordend wordstart (file) readable isdirectory atime attributes copy delete dirname executable exists extension isfile join lstat mkdir mtime owned rename size
Un sous-programme se définit par proc. Il admet des paramètres en nombre variable, avec des valeurs par défaut. On écrit global pour définir des variables globales. L'instruction catch permet de récupérer une erreur éventuelle. Il y a de nombreuses variables prédéfinies comme $tcl_platform(os).
3. Exemples
3.1 Bonjour
# on demande le prénom, on le traduit en majuscules, # et on affiche aussi la date et l'heure puts " Bonjour (en tcl) ; votre prenom ? " set pren [gets stdin] set p " \"bel inconnu\" ! " if { [string length $pren] > 0 } { set p [string toupper $pren] } set h [ clock format [clock seconds] -format " Le %d/%m/%y a %H:%M" ] puts " $h au revoir, $p."Affichage de l'exécution sous Dos/Windows :Affichage de l'exécution sous Unix/Linux :
L:\GH\MMM\POURTCL>tcl bonjour.tkl Bonjour (en tcl) ; votre prenom ? gilles Le 30/09/98 a 16:42 au revoir, GILLES.
@vega~/Tmp|(~gH)> wish bonjour.tkl Bonjour (en tcl) ; votre prenom ? gilles Le 30/09/98 a 16:43 au revoir, GILLES.
3.2 Table de multiplication
puts "\nCeci est un programme tcl $tcl_version sous : " puts "$tcl_platform(os) $tcl_platform(osVersion)\n" if { ($argc > 0)} { set n $argv } else { puts " syntaxe : tcl table Nombre " puts " exemple : tcl table 5 " exit } ; # fin de si puts " table de Multiplication de n = $n (passé en paramètre) \n" for { set i 1 } { $i <= 10 } { incr i } { puts [ format " %7d fois %7d = %7d " $i $n [expr $i*$n] ] } ; # fin de pourAffichage de l'exécution sans paramètre sous Dos/Windows :Affichage de l'exécution avec le paramètre 1998 sous Dos/Windows :
+++++++++++++++++++++++++++++++++++++++++++++++ + + + Ceci est un programme tcl 8.0 sous : + + Windows NT 4.0 + + + + syntaxe : tcl table Nombre + + exemple : tcl table 5 + + + +++++++++++++++++++++++++++++++++++++++++++++++
Affichage de l'exécution sans paramètre sous Unix/Linux :
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + + Ceci est un programme tcl 8.0 sous : + + Windows NT 4.0 + + + + table de Multiplication de n = 1998 (passe en parametre) + + + + 1 fois 1998 = 1998 + + 2 fois 1998 = 3996 + + 3 fois 1998 = 5994 + + 4 fois 1998 = 7992 + + 5 fois 1998 = 9990 + + 6 fois 1998 = 11988 + + 7 fois 1998 = 13986 + + 8 fois 1998 = 15984 + + 9 fois 1998 = 17982 + + 10 fois 1998 = 19980 + + + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Affichage de l'exécution avec le paramètre 1998 sous Unix/Linux :
++++++++++++++++++++++++++++++++++++++++++ + + + Ceci est un programme tcl 7.6 sous : + + Linux 2.0.35 + + + + syntaxe : tcl table Nombre + + exemple : tcl table 5 + + + ++++++++++++++++++++++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + + Ceci est un programme tcl 7.6 sous : + + Linux 2.0.35 + + + + table de Multiplication de n = 4 (pass' en paramStre) + + + + 1 fois 4 = 4 + + 2 fois 4 = 8 + + 3 fois 4 = 12 + + 4 fois 4 = 16 + + 5 fois 4 = 20 + + 6 fois 4 = 24 + + 7 fois 4 = 28 + + 8 fois 4 = 32 + + 9 fois 4 = 36 + + 10 fois 4 = 40 + + + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3.3 Lecture d'un fichier QCM
################################ # # # programme litexo.tcl # # # ################################ proc queueDe { LaL } { set lR "" set mc 0 foreach mot $LaL { incr mc ; if { $mc > 1 } { append lR $mot " " } } ; # fin de pour chaque return $lR } ; # fin de proc queueDe proc litex { nic } { # exemple de format du fichier ## # ## +------------------------------------------------------------+ # ## ! ! # ## ! # exo_01 : compréhension de la notion d'union d'ouverts ! # ## ! TROU ! # ## ! Question Complétez la phrase avec LE bon mot ! # ## ! Début Une intersection ! # ## ! Fin d'ouverts est un ouvert. ! # ## ! Réponse 0.5 finie ! # ## ! Commentaire c'est vrai, mais ce n'est pas suffisant. ! # ## ! Réponse 0 continue ! # ## ! Commentaire mais... cela n'a aucun sens ! ! # ## ! Réponse 1 quelconque ! # ## ! Commentaire très bien. ! # ## ! ! # ## +------------------------------------------------------------+ # set nbrep 0 set nbcmt 0 set fic [ open $nic r] set lexo { } while { [eof $fic] ==0 } { gets $fic ligne # puts " LIGNE LUE $ligne " set nbmots [expr [llength $ligne]] if {$nbmots > 2} { set prem [ lindex $ligne 0 ] set deuz [ lindex $ligne 1 ] set troz [ lindex $ligne 2 ] # puts " avec $nbmots élément(s), le premier étant $prem" if {$prem == "Question"} { set texte [ queueDe $ligne] ; set lexo [ lappend lexo $texte] } if {$prem == "Début"} { set debut [ queueDe $ligne] ; set lexo [ lappend lexo $debut] } if {$prem == "Fin"} { set fin [ queueDe $ligne] set lexo [ lappend lexo $fin] } if {$prem == "Réponse"} { incr nbrep set larep $deuz set lexo [ lappend lexo $larep] set larep $troz set lexo [ lappend lexo $larep] } ; # fin de si if {$prem == "Commentaire"} { incr nbcmt set lecmt [ queueDe $ligne] set lexo [ lappend lexo $lecmt] } ; # fin de si } ; # fin de si }; # fin de while return $lexo } ; # fin de proc litex3.4 Conversion Francs/Euros
# fichier cfe.tcl if ($argc<=0) { puts " pour utiliser cfe, taper cfe puis une somme en francs\n" ; puts " par exemple : cfe 100 \n "; exit } ; # fin de si set sef $argv ; # somme en francs set eur [expr $sef/6.55957] puts " $sef francs font $eur euros " puts " soit en arrondi : [ format "%10.2f" $eur] euros "