Herezh_dev/Lecture/nouvelle_enreg.cc

365 lines
17 KiB
C++

// This file is part of the Herezh++ application.
//
// The finite element software Herezh++ is dedicated to the field
// of mechanics for large transformations of solid structures.
// It is developed by Gérard Rio (APP: IDDN.FR.010.0106078.000.R.P.2006.035.20600)
// INSTITUT DE RECHERCHE DUPUY DE LÔME (IRDL) <https://www.irdl.fr/>.
//
// Herezh++ is distributed under GPL 3 license ou ultérieure.
//
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
// AUTHOR : Gérard Rio
// E-MAIL : gerardrio56@free.fr
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License,
// or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//
// For more information, please consult: <https://herezh.irdl.fr/>.
#include <fstream>
//#ifdef SYSTEM_MAC_OS_X
// #include <stringfwd.h> // a priori ce n'est pas portable
//#el
#if defined SYSTEM_MAC_OS_CARBON
#include <stringfwd.h> // a priori ce n'est pas portable
#else
#include <string.h> // pour le flot en memoire centrale
#endif
#include <string>
//#include "Debug.h"
#ifndef ENLINUX_STREAM
#include <ios>
#else
#include <iostream>
#include <strstream>
#endif
#include "UtilLecture.h"
using namespace std;
//
// ----- routine de la classe UtilLecture -------
//
// routine pour acquerir un nouvel enregistrement et
// passer les commentaires dans les fichiers d'entree d'herezh
// Un commentaire se trouve apres le symbole #
// une ligne est consideree comme non_commentaire si elle possede au moins un carractere non
// identique a l'espace avant le carractere #
// dans le cas ou il y a une erreur de lecture ou que la fin de fichier est ateinte
// le programme genere une exception de tye : errNouvelEnreg, =1 -> fin de fichier
// = -1 autre probleme de lecture
void UtilLecture::Nouvel_enreg()
{
char delim = '\n'; // fin de ligne utilise
int nouvelleligne = 0; /* initialisation de l'indicateur pour sortie de
la boucle de recherche, quand = 1 on a trouve une ligne interessante */
char* fin = NULL ; // position du carractere #
char* lienLigne = NULL; // position éventuelle d'un caractère \ de continuation de ligne unix
bool suiteLigne = false; // indique si oui ou non la ligne lue se continue
char* finReturn = NULL; // position éventuelle d'un caractère \r (cariage return)
ifstream & fichier = *ptrfich;
tabMultiLignes[0] = '\0'; // on met à 0 le tableau de stockage de plusieurs lignes
do // on test jusqu'a une ligne interessante
{ suiteLigne=false;
fichier.getline(tableau,longueur,delim); // lecture d'une ligne dans le fichier
// reta = -1 s'il y a eu un pb qui fait qu'aucune lecture viable n'a été faite
(maille1->numLigne)++; // incrementation du numero de ligne
/*// -- debug
if (fichier.eof() && (reta != -1) )
cout << "\n ** debug UtilLecture::Nouvel_enreg() "
<< " fichier.rdstate()= "<< fichier.rdstate() << endl;
*/// -- fin debug
// ---- traitement d'un cas particulier que je ne vois pas comment traiter autrement
int long_ligne = 0; // une longeur de ligne intermédiaire, ne sert que pour le test plus bas
if ( (fichier.rdstate() != 6) && fichier.eof()) // on a atteind la fin de ligne,
long_ligne = (int) strlen (tableau); // mais on a lue quelque chose
/* pour mémoire:
enum io_state
{ badbit = 1<<0, // -> 1 dans rdstate()
eofbit = 1<<1, // -> 2
failbit = 1<<2, // -> 4
goodbit = 0 // -> O
};
rdstate() == 6 cela signifie eofbit + failbit
*/
// test de l'etat du flux d'entree
if (( fichier.rdstate() == 0 ) // cas normal
|| (long_ligne > 0 ) // cas où on a quand même lue quelque chose
) // car reta != -1, mais que l'on a atteind la fin de ligne
{
int finLigne = (int) strlen (tableau); // longueur de la ligne (surabondant / à
// long_ligne mais on garde pour ne pas mélanger
if ( finLigne > 0 )
{ // cas d'une ligne non vide
fin = strchr(tableau,'#'); // position du debut de commentaire s'il existe
finReturn = strchr(tableau,'\r'); // position d'un "cariage return" s'il existe
if (finReturn != NULL)
{ // on supprime le caractère pour pas que cela pose des pb par la suite
*finReturn = '\0';
};
lienLigne = strchr(tableau,'\\'); // position du caractère de continuation de ligne
if ( (lienLigne != NULL) && // on n'intervient que s'il y a un caractère de continuation
( ((fin != NULL) && (lienLigne < fin)) // si le caractère de continuation est après un #, on n'en tient pas compte
|| (fin == NULL) // sinon on en tiens compte
)
)
{ // on supprime le caractère pour pas que cela pose des pb par la suite mais on sait avec lienLigne que
// la ligne continue
*lienLigne = '\0'; suiteLigne = true;
//cout << "\n on a trouvé un antislash !! ";
//Sortie(1);
}
else if ( (lienLigne != NULL) && // on n'intervient que s'il y a un caractère de continuation
((fin != NULL) && (lienLigne > fin))
)
{ // on supprime le caractère pour pas que cela pose des pb par la suite mais on sait avec lienLigne que
// la ligne continue
*lienLigne = '\0'; suiteLigne = false;lienLigne=NULL;
//cout << "\n on a trouvé un antislash !! ";
//Sortie(1);
};
char* ptr = tableau; // initialisation de la boucle do dans le if else suivant
int debut = -1; // indiquera le premier caractère non nul
// on cherche un carractere different de l'espace
if ((fin != NULL)&&(fin != tableau) ) // cas ou il y a un #
{
do { // on cherche jusqu'a un
// if (*ptr != ' ') // carractere non espacement
if ((*ptr != ' ') &&(*ptr != '\t')&&(*ptr != '\0')) // carractere non espacement et non tabulation
nouvelleligne = 1 ; //
ptr++; debut++;
} while ((nouvelleligne == 0)&&(ptr <= fin-1));
if (nouvelleligne == 1) // sortie de la ligne interessante
{ // mise à nul du tableau tablcar
// nouvelle méthode: on se contente de mettre un caractère nul après la zone lue
//essai---------------- for (int ii =0; ii<= longueur; ii++) tablcar[ii] = '\0';
// recopie uniquement à partir du premier caractère non nul
int ii,ii2;
for (ii =debut,ii2=0; ii<= (int) (fin - tableau) -1; ii++,ii2++)
// for (ii =debut,ii2=0; ii<= ((int) fin - (int) tableau) -1; ii++,ii2++)
tablcar[ii2] = tableau[ii];
// on met un caractère de fin de chaine
tablcar[ii2]='\0';
// suppression des caractères nuls et des tabulations de fin de ligne
for (int ii3 = ii2-1; ii3 >= 0; ii3--)
// if (tablcar[ii3] == ' ') tablcar[ii3] = '\0'; else break;
if ((tablcar[ii3] == ' ') || (tablcar[ii3] == '\t'))
tablcar[ii3] = '\0';
else break;
};
}
else if (fin != tableau) // cas ou la ligne ne contiend pas de #
{
do { // on cherche jusqu'a un
// if (*ptr != ' ') // carractere non espacement
if ((*ptr != ' ') &&(*ptr != '\t')&&(*ptr != '\0')) // carractere non espacement et non tabulation
nouvelleligne = 1 ; //
ptr++;debut++;
} while ((nouvelleligne == 0)&&(ptr <= tableau + finLigne-1));
if (nouvelleligne == 1) // sortie de la ligne interessante
{ // mise à nul du tableau tablcar
// nouvelle méthode: on se contente de mettre un caractère nul après la zone lue
//essai---------------- for (int ii =0; ii<= longueur; ii++) tablcar[ii] = '\0';
// recopie uniquement à partir du premier caractère non nul
// jusqu'au caractère
int ii,ii2;
for (ii =debut,ii2=0; ii<= finLigne-1; ii++,ii2++)
tablcar[ii2] = tableau[ii];
// on met un caractère de fin de chaine
tablcar[ii2]='\0';
// suppression des caractères nuls de fin de ligne
for (int ii3 = ii2-1; ii3 >= 0; ii3--)
if (tablcar[ii3] == ' ')
tablcar[ii3] = '\0';
else
break;
};
};
}; // sinon cas d'une ligne vide, on passe a la suivante
}
else
{ // traitement des erreurs du flux d'entree
// if ( fichier.eofbit == 1 )
#ifndef ENLINUX_STREAM
if ( (fichier.rdstate() & ios_base::eofbit) == ios_base::eofbit)
#else
if ( (fichier.rdstate() & ios::eofbit) == ios::eofbit)
#endif
{ ErrNouvelEnreg sortie(1) ; // fin du fichier atteind
throw (sortie);
nouvelleligne = 1;
}
else
{
ErrNouvelEnreg sortie(-1) ; // probleme de lecture indetermine
throw (sortie); // erreur de lecture
nouvelleligne = 1;
}
};
// dans le cas où il y a un caractère de continuation on sauvegarde le résultat et on continue
if ((suiteLigne) || (tabMultiLignes[0] != '\0')) // cas ou on a lue un caractère de continuation
{ //ou bien que l'on lit la dernière ligne d'une suite
strcat(tabMultiLignes,tablcar);
};
}while ((nouvelleligne == 0 ) || (suiteLigne));
// on boucle tant qu'il n'y a rien dans la ligne et qu'il n'y a pas de caractère de continuation
// dans le cas ou le tableau tabMultiLignes a été utilisé on recopie le résultat dans tabcar
if (tabMultiLignes[0] != '\0')
strcpy(tablcar,tabMultiLignes);
//--pour la mise au point
//cout << "\n " << tablcar ;
//--fin mise au point
};
//
// ----- routine de la classe UtilLecture -------
//
// même routine que nouvel enreg, mais pour la lecture des commandes de visualisation
// On utilise grosso modo une struture simplifiée de nouvel_enreg car ici il n'y a pas de fichier
// Imbriqué
// Permet de passer les commentaires dans le fichier d'entree
// Un commentaire se trouve apres le symbole #
// une ligne est consideree comme non_commentaire si elle possede au moins un carractere non
// identique a l'espace avant le carractere #
// dans le cas ou il y a une erreur de lecture ou que la fin de fichier est ateinte
// le programme genere une exception de tye : errNouvelEnreg, =1 -> fin de fichier
// = -1 autre probleme de lecture
void UtilLecture::Nouvel_enregCvisu ()
{
char delim = '\n'; // fin de ligne utilise
int nouvelleligne = 0; // initialisation de l'indicateur pour sortie de la boucle
//de recherche, quand = 1 on a trouve une ligne interessante
char* fin ; // position du carractere #
fstream & fichier = *ent_CommandeVisu;
int numLigne=0; // numéro de la ligne courante en lecture
do // on test jusqu'a une ligne interessante
{
fichier.getline(tableauCVisu,longueur,delim); // lecture d'une ligne dans le fichier
numLigne++; // incrementation du numero de ligne
if ( fichier.rdstate() == 0 ) // test de l'etat du flux d'entree
{
int finLigne = (int) strlen (tableauCVisu); // longueur de la ligne
if ( finLigne > 0 )
{ // cas d'une ligne non vide
fin = strchr(tableauCVisu,'#'); // position du debut de commentaire s'il existe
char* ptr = tableauCVisu; // initialisation de la boucle do dans le if else suivant
int debut = -1; // indiquera le premier caractère non nul
// on cherche un carractere different de l'espace
if ((fin != NULL)&&(fin != tableauCVisu) ) // cas ou il y a un #
{
do { // on cherche jusqu'a un
if (*ptr != ' ') // carractere non espacement
nouvelleligne = 1 ; //
ptr++; debut++;
} while ((nouvelleligne == 0)&&(ptr <= fin-1));
if (nouvelleligne == 1) // sortie de la ligne interessante
{ // mise à nul du tableauCVisu tablcarCVisu
// nouvelle méthode: on se contente de mettre un caractère nul après la zone lue
//essai---------------- for (int ii =0; ii<= longueur; ii++) tablcarCVisu[ii] = '\0';
// recopie uniquement à partir du premier caractère non nul
int ii,ii2;
for (ii =debut,ii2=0; ii<= (int) (fin - tableauCVisu) -1; ii++,ii2++)
// for (ii =debut,ii2=0; ii<= ((int) fin - (int) tableauCVisu) -1; ii++,ii2++)
tablcarCVisu[ii2] = tableauCVisu[ii];
// on met un caractère de fin de chaine
tablcarCVisu[ii2]='\0';
// suppression des caractères nuls de fin de ligne
for (int ii3 = ii2-1; ii3 >= 0; ii3--)
if (tablcarCVisu[ii3] == ' ') tablcarCVisu[ii3] = '\0'; else break;
};
}
else if (fin != tableauCVisu) // cas ou la ligne ne contiend pas de #
{
do { // on cherche jusqu'a un
if (*ptr != ' ') // carractere non espacement
nouvelleligne = 1 ; //
ptr++;debut++;
} while ((nouvelleligne == 0)&&(ptr <= tableauCVisu + finLigne-1));
if (nouvelleligne == 1) // sortie de la ligne interessante
{ // mise à nul du tableauCVisu tablcarCVisu
for (int ii =0; ii<= longueur; ii++) tablcarCVisu[ii] = '\0';
// recopie uniquement à partir du premier caractère non nul
// jusqu'au caractère
int ii,ii2;
for (ii =debut,ii2=0; ii<= finLigne-1; ii++,ii2++)
tablcarCVisu[ii2] = tableauCVisu[ii];
// suppression des caractères nuls de fin de ligne
for (int ii3 = ii2-1; ii3 >= 0; ii3--)
if (tablcarCVisu[ii3] == ' ')
tablcarCVisu[ii3] = '\0';
else
break;
};
};
}; // sinon cas d'une ligne vide, on passe a la suivante
}
else
{ // traitement des erreurs du flux d'entree
// if ( fichier.eofbit == 1 )
#ifndef ENLINUX_STREAM
if ( (fichier.rdstate() & ios_base::eofbit) == ios_base::eofbit)
#else
if ( (fichier.rdstate() & ios::eofbit) == ios::eofbit)
#endif
{ ErrNouvelEnregCVisu sortie(1) ; // fin du fichier atteind
throw (sortie);
nouvelleligne = 1;
}
else
{
ErrNouvelEnregCVisu sortie(-1) ; // probleme de lecture indetermine
throw (sortie); // erreur de lecture
nouvelleligne = 1;
}
};
// dans le cas
}while (nouvelleligne == 0 ) ;
};