What did you Expect?

Pour assurer un certain nombre de services au sein de votre application Ada, il peut être intéressant et élégant d’utiliser des applications déjà existantes. Par exemple, si je dois faire des requêtes FTP, il est évidemment plus simple d’utiliser le client du même nom. Si l’application que vous voulez utiliser est en mode interactif (c’est le cas de la commande ftp) alors, la tâche risque d’être ardue.

Tcl/Expect

Dans les années quatre-vingt-dix, le langage de script Tcl/Expect avait été créé comme une extension du langage Tcl (Tool Command Language). Il permettait de facilement automatiser l’utilisation d’outils comme telnet, ftp, etc. Associé à Tk (ToolKit), il permettait de « donner » une interface graphique à ces mêmes applications.

Le principe d’Expect est simple : il envoie des commandes à l’application et il attend des réponses (expect).

GNAT.Expect

Ce paquetage Ada propose des services proches de ceux de Tcl/Expect. On peut ainsi :

  • Démarrer l’application que vous souhaitez contrôler de façon interactive : spawn().

  • Envoyer des commandes à cette même application : send().

  • Attendre en retour une réponse et la comparer à une expression régulière : expect().

Exemple

Ici, on demande à l’application ftp de télécharger un fichier distant fichier.zip.

Après avoir démarré le programme ftp, on voit parfaitement les interactions de type questions/réponses (ou plus exactement commandes/réponses) entre l’application Ada test_expect et l’application ftp.

procedure Test_Expect is
   Process : Process_Descriptor;
   Args    : Argument_List_Access := Argument_String_To_List ("ftp 127.0.0.1");
   Result  : Expect Match;
begin
   Process.Non_Blocking_Spawn (Command => Args (Args'First).all,
                               Args    => Args (Args'First + 1 .. Args'Last));
   Process.Expect (Result, Regexp => "Utilisateur");

   Process.Send ("anonymous");
   Process.Expect (Result, Regexp => "Mot de passe");

   Process.Send ("*******");
   Process.Expect (Result, Regexp => ".+");

   Process.Send ("binary");
   Process.Expect (Result, Regexp => ".+");

   Process.Send ("ls *.zip") ;
   Process.Expect (Result, Regexp => "fichier\.zip");

   Process.Send ("get fichier.zip") ;
   Process.Expect (Result, Regexp => ".+");

   ...
   Process.Send ("bye") ;
   Process.Close;
   ...

end Test_Expect;

Conclusion

What did you Expect? : une solution simple à un problème qui ne l’est pas !

Comments