J'ai hérité d'un projet qui a deux modes de sortie, console et fichier en texte brut. Le projet utilise Ada.Text_IO.SET_OUTPUT pour sélectionner l'un ou l'autre.

Je veux créer une troisième option SET_OUTPUT, qui peut facilement rediriger la sortie vers une variété de formats autres que stdout ou un fichier disque. Je voudrais que la sortie soit une sorte d'objet en RAM ou "fichier" afin qu'il puisse être lu rapidement par plusieurs clients. J'ai également besoin de garder le code portable, donc idéalement, la solution s'en tenir aux bibliothèques standard.

J'ai essayé les instanciations de Sequential_IO, mais la base de code est trop grande et incohérente (surcharges et renommage des procédures de Text_IO et si Text_IO est appelé par la notation par points) pour remplacer rapidement et de manière fiable les appels.

Je dois être peu créatif (et je suis certainement nouveau dans Ada), mais la solution à laquelle je n'arrête pas d'arriver semble trop complexe et alambiquée - créer un conteneur de File_Type de Text_IO dans un pool de mémoire géré à un bas niveau; puis SET_OUTPUT dans ce fichier dans la RAM, d'où il peut être poussé ou extrait vers les clients.

J'espère qu'il me manque quelque chose et que quelqu'un pourra m'aider à trouver un moyen plus simple. Merci d'avance.

ada
4
ds_j2 17 mai 2020 à 06:34

3 réponses

Meilleure réponse

Text_IO est spécifiquement pour les fichiers, il n'y a donc pas de moyen portable de l'utiliser pour écrire en mémoire. La manière normale d'autoriser l'écriture dans des fichiers, de la mémoire ou tout autre élément que vous pouvez définir est d'utiliser des flux, mais cela nécessiterait de remplacer la plupart des utilisations de Text_IO pour utiliser des flux à la place. Si cela est acceptable, alors Ada.Text_IO.Text_Streams autorise l'écriture dans Current_Output en tant que flux.

3
Jeffrey R. Carter 17 mai 2020 à 05:20

Je donnerais un essai avec quelque chose comme ça:

  type Extended_File_Type is record
    Is_Normal : Boolean;
    File      : Ada.Text_IO.File_Type;
    Special   : Integer;  --  <- Dummy, replace by your fancy in-RAM object.
  end record;

  procedure Put_Line (EFile : Extended_File_Type; S : String) is
  begin
    if EFile.Is_Normal then
      Ada.Text_IO.Put_Line (Efile.File, S);
    else
      null;  --  Output to your special object.
    end if;
  end;
0
Zerte 18 mai 2020 à 20:22

Si vous ne modifiez pas tous les appels Text_IO, vous serez bloqué avec une sortie textuelle vers votre stockage en mémoire choisi (par exemple), ce qui signifiera probablement du contenu textuel (à moins que vos développeurs historiques ont respecté rigoureusement les normes de format analysables!)

En supposant que GNAT, la manière dont IO traite les fichiers est décrite dans le GNAT Manuel de référence; en particulier, il n'est pas nécessaire qu'un fichier soit un fichier disque normal, tant qu'il est accessible via des appels système C, par ex. fopen(). Vous pouvez donc diriger vers un gestionnaire de stockage de journaux.

D'un autre côté, vous pouvez simplement utiliser un fichier partagé (voir le FORM strings de la RM GNAT).

Le système n'a-t-il qu'une seule sortie de fichier texte possible? Cela faciliterait les choses ...

2
Simon Wright 17 mai 2020 à 07:55