Tuteur Tcl
     - gilles Hunault,
Angers 1998

novalid      

Table des matières

     1. Présentation du Langage

     2. Eléments du Langage

     3. Exemples

            3.1 Bonjour

            3.2 Table de multiplication

            3.3 Lecture d'un fichier QCM

            3.4 Conversion Francs/Euros

 


1. Présentation du Langage

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...

2. Eléments du Langage

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 diviseur
est incorrect. Il faut mettre
  set  somDiv 1 ; # on a toujours 1 comme diviseur

Si 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 txtMsf

On 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 i

La 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 :


 L:\GH\MMM\POURTCL>tcl bonjour.tkl

   Bonjour (en tcl) ; votre prenom ?

 gilles

   Le 30/09/98 a 16:42 au revoir, GILLES.

Affichage de l'exécution sous Unix/Linux :


   @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 pour

Affichage de l'exécution sans paramètre 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 avec le paramètre 1998 sous Dos/Windows :

        ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        +                                                                      +
        +    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 sans paramètre sous Unix/Linux :

        ++++++++++++++++++++++++++++++++++++++++++
        +                                        +
        + Ceci est un programme tcl 7.6 sous :   +
        + Linux 2.0.35                           +
        +                                        +
        +  syntaxe : tcl table Nombre            +
        +  exemple : tcl table 5                 +
        +                                        +
        ++++++++++++++++++++++++++++++++++++++++++

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                                                +
        +                                                              +
        +   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 litex

      3.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 "