Re: Ada.Text_IO

Thomas De Contes via Ada-france <[email protected]> Mon, 6 Dec 2021 16:25:52 +0100
Newsgroups gmane.comp.lang.ada.france
Message-ID <[email protected]>
Le 29 sept. 2021 à 19:48, Jean-Pierre Rosen via Ada-france a écrit :

> Le 29/09/2021 à 17:53, Thomas De Contes via Ada-france a écrit :
>> Bonjour :-)
>> 1)
>> Standard_Error

>> Par contre, il n'y a pas de raccourci equivalent pour Current_Error ?
> non.

Ok.

> 
>> Y a-t-il des "bonnes pratiques", quand on veut écrire sur Standard_Error ?
>> Vaut-il mieux préférer Standard_Error ou Current_Error ?
> Standard_Error si tu veux être sûr d'écrire sur la sortie d'erreur en toute circonstances, Current_Error si tu veux pouvoir d'éventuelles redirections par Set_Error
> 
>> Y a-t-il une différence entre les 2 si Set_Error n'est utilisé nulle part dans l'application ?
> Non
> 
>> Et si on écrit sur Standard_Error dans une bibliothèque, faut il prévoir que l'usager de la bibliothèque puisse vouloir utiliser Set_Error ?
> A priori, si l'utilisateur fait un Set_Error, c'est qu'il veut rediriger la sortie (par exemple dans un fichier). Je ne vois pas pourquoi on voudrait l'en empêcher...

Ok. La "bonne pratique" est donc Current_Error. Merci :-)



> 
>> 2)
>> Close
>> File_Type n'est pas un type contrôlé, donc quand c'est une variable locale il n'est pas finalisé au moment de sa disparition,
>> donc si on veut que ça soit fermé proprement, Close est obligatoire (notamment en cas d'exceptions).
>> Est-ce que ça a été conçu comme ça exprès ?
> Ca a été conçu avant l'existence des types contrôlés, donc si on a un fichier local F, on devrait toujours avoir à la fin:
> exception
>   when others =>
>      if Is_open (F) then
>         Close (F);
>      end if;

Ok, j'ai corrigé tout ce que j'ai vu, merci :-)


Pourquoi est-ce que c'était compliqué à corriger au moment de la création des types contrôlés ?
Est-ce que ça impliquait des changements d'usage, jugés trop cher pour les "gros utilisateurs" ?
Ou alors, pas de changement d'usage, mais des changements dans les compilateurs, jugés trop cher pour les fabricants de compilateurs ?

Pourquoi est-ce que Close réclame que le fichier soit ouvert (et que, avec un fichier fermé, il ne se contente pas de ne rien faire, comme Ada.Unchecked_Deallocation avec les pointeurs nuls) ?
(Si la raison est uniquement historique : même question sur le changement du langage.)


Il se trouve que je vais avoir besoin de mettre un Ada.Text_IO.File_Type dans un type composé plus gros.

Est-ce que c'est bien, puisque j'en ai l'occasion (je ne le fais pas exprès pour ça), d'en faire un type contrôlé, d'appeler Close automatiquement à la fin, et de ne même pas le proposer comme primitive puisque c'est inutile ?
Ou bien est-ce que c'est une mauvaise pratique, et il vaut beaucoup mieux reproduire le comportement de Ada.Text_IO.File_Type à travers le type englobant ?



> 
>> 3)
>> Create(Name => "")
>> J'avais déjà lu quelque part ce que ça fait, mais je ne parviens pas à retrouver où.

J'ai retrouvé : A.8.2 l 4, indiqué par A.10 l 2.

> Ca crée un fichier temporaire (effacé automatiquement au Close)

Par contre, c'est indiqué "A null string for Name specifies an external file that is not accessible after the completion of the main program".
Donc a priori, ça laisse penser qu'il est encore "accessible" après un Close, tant qu'on est dans la même séquence d'exécution (ou session ? je ne connais pas bien le vocabulaire) du "main program".
Qu'en dis-tu ?

>> 
>> Est-ce que, en combinaison avec Name ("function  Name   (File : in File_Type) return String;") ça permet d'obtenir un répertoire pour fichiers temporaires,
>> pour nous permettre de créer des fichiers temporaires qui durent un petit peu plus (qu'on puisse fermer et rouvrir avec l'application) mais pas trop quand même (qui soient effacés par le système régulièrement) ?
> Non, le fichier disparaît au Close, et il n'y a pas nécessairement de répertoire associé (i.e. dans les systèmes bien faits, on a la notion de fichier temporaire - c'est parcequ'on n'a pas cette notion dans le système qu'Unix/DOS utilise /tmp ou équivalent).
> 
> Mais Reset permet de relire le fichier SANS le fermer.

Ok. Je vois que c'est pratique quand on a de gros volumes de données temporaires, trop gros pour tenir en mémoire vive.


En fait, l'usage que je voulais en faire c'est implémenter un mécanisme pour minimiser les inconvénients en cas d'interruption pendant l'écriture  :

- Trouver un répertoire pour fichiers temporaires
- Écrire le nouveau fichier dedans
- Effacer l'ancien fichier
- Déplacer le nouveau fichier à sa place

Ça permet de remplacer l'ancien fichier par le nouveau de façon quasi-atomique (pas tout à fait, puisqu'on doit faire Ada.Directories.Delete_File avant Ada.Directories.Rename, mais presque).

As-tu des recommandations à me donner dans ce domaine ?



> 
>> 4)
>> (Pendant que j'y suis, pour un peu plus tard : )
>> Fins de ligne portables
>> Dans mon code, j'ai :
>>    Ada.Text_IO.Get_Line (Input_File, Line, Last);
>>    if Line (Last) = ASCII.CR then
>>       Last := Last - 1;  -- ignore DOS line end
>>    end if;
>> Je suppose que sur chaque plateforme, les fins de ligne sont bien gérées chacunes de leur coté,
>> et que ce code est là seulement pour le cas où on transfère des fichiers entre Windows et Linux.
> A priori, oui. La fin de ligne, si c'est un ou plusieurs caractères, n'est jamais retournée. Cela n'arrive qu'en cas de fichier "mal formé".

Ok.

> Ceci dit, il me semble (à vérifier) que Gnat admet indiféremment CR, CR/LF, LF/CR, LF comme Termine-Ligne.
> 
>> C'est du très vieux code : est-il toujours utile ?
> Je pense que non, à vérifier
> 
>> Si oui, ce morceau est là pour le cas où on lit sous Linux un fichier Windows.
>> Mais pour le cas inverse (où on lit sous Windows un fichier Linux), y a-t-il des précautions à prendre ?
>> Est-ce que tout le fichier se retrouve sur une seule ligne, avec des ASCII.LF non-interprétés ?
> Cf. ci-dessus, à essayer...

Ok, j'ai trouvé le moyen de faire un test, et (sauf erreur lors du test) chez moi ça ne marche pas comme ça.
(Peut-être qu'il "ratisse large" sous Windows mais pas sous Linux, ou peut-être que ça dépend des versions selon d'autres critères.)

À coté de ça, un outil comme SVN est capable de gérer l'interopérabilité (est-ce le bon terme ?) des fins de ligne, mais il ne le fait pas par défaut, il faut le lui demander.
Je devine qu'il y a des cas aussi avec des outils comme les gestionnaires d'archives.
(Je me demande à quoi ressemble l'interopérabilité entre les plateformes courantes et celles où les fins de ligne sont gérées tout autrement ...)

Donc il faut garder quelque chose.
En fait, pas besoin de surveiller spécialement le début ou la fin de la ligne, il suffit d'intégrer les 2 caractères CR et LF comme autorisés et signifiant un blanc / une séparation, il me semble que ça devrais bien marcher.


Pendant que j'y suis, j'en profite pour faire une petite suggestion (connexe ?) pour le langage :

Est-ce que ça existe encore, des SE qui utilisent CR comme Termine-Ligne ?
Si non, on n'est pas obligé de lui conserver une signification de Termine-Ligne.
(Je ne connais que Mac OS Classic, et même si on trouve peut-être encore des gens qui s'amusent avec MachTen CodeBuilder, ça m'étonnerais qu'ils aillent jusqu'à fabriquer un compilateur compatible avec une nouvelle version du langage.)

Je propose de simplifier le travail des compilateurs, en supprimant dans 2.1 l 16 le cas particulier de la séquence CR/LF, de manière à ne laisser que du traitement de caractère individuel.
Comme nouvelle signification pour CR, la même que HT serait probablement la plus appropriée : comme ça, ça reste un format_effector, sans doubler les n° de ligne sous Windows.

(Et pendant que j'y suis aussi, pourquoi donner des significations particulières à des caractères hors ASCII ? Ça complique des choses, et je n'en vois pas l'intérêt.)


-- 
RAPID maintainer
http://savannah.nongnu.org/projects/rapid/

_______________________________________________
Ada-france mailing list
[email protected]
https://mail.ada-france.org/cgi-bin/mailman/listinfo/ada-france