Herezh_dev/Lecture/UtilLecture.cc

947 lines
42 KiB
C++
Raw Normal View History

// 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.
//
2023-05-03 17:23:49 +02:00
// Copyright (C) 1997-2022 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 <iostream>
using namespace std; //introduces namespace std
#include <stdlib.h>
#include "Sortie.h"
#include "UtilLecture.h"
#include "Sortie.h"
#include <fstream>
#include <cstdlib>
#include <iomanip>
#include <algorithm>
#include "ParaGlob.h"
#include "CharUtil.h"
#include "TypeQuelconque.h"
#include <limits>
// méthodes de classe internes
// surcharge de l'operateur d'ecriture
ostream & operator << (ostream & sort,const UtilLecture::Position_BI & a)
{ // écriture du type
sort << "incre_posi_(nb_et_posi): ";
// les données
sort << a.num_incr << " " ;
// pour la position c'est plus délicat et peut-être pas portable ??
// normalement on a la position et un paramètre state ?
// que l'on sauvegarde manuellement because pas de surcharge actuellement
// () donne normalement l'ofset, et la fonction state() donne le state (?)
streamoff errt = (streamoff) a.position; // utilisation de la conversion de type forcée
#ifndef ENLINUX_STREAM
sort << errt << " " << a.position.state() << " ";
#else
sort << errt;
#endif
return sort;
};
// surcharge de l'operator de lecture
istream & operator >> (istream & entree, UtilLecture::Position_BI& a)
{ // vérification du type
string type;
entree >> type;
if (type != "incre_posi_(nb_et_posi):")
{Sortie (1);
return entree;
};
// entrée des données
entree >> a.num_incr;
// en fait pour la position du stream il y a deux grandeurs (sur mac)
// et on est obligé d'utiliser la surcharge standard de copie (?)
// pour remplir a !! car
// streampos contiend deux éléments sur mac !! qui sont en private !!
// sur unix !!!!! a priori un seul élément
#ifndef ENLINUX_STREAM
{long long titi1;
long long int titi2;
entree >> titi1 >> titi2;
streampos ee(titi1); ee.state(titi2);
a.position = ee;
}
#else
{long long titi1;
entree >> titi1 ;
streampos ee(titi1);
a.position = ee;
};
#endif
return entree;
};
// CONSTRUCTEURS :
// il y a passage éventuelle d'argument : argc=le nombre d'argument
// argv : donne un tableau correspondant de mots clés
// ---> lecture de la racine du nom du fichier princial
UtilLecture::UtilLecture (int argc, const char * argv[]) :
2023-05-03 17:23:49 +02:00
longueur(2500) // longueur maxi du tableau de travail
,nomCourant(),nomRacine(),ptrfich(NULL),tablcar(NULL),tableau(NULL),lec_ent_info(-10)
,liste_posi_BI()
#ifndef UTILISATION_MPI
,ent_BI(NULL),sort_BI(NULL),ent_PI(NULL),sort_PI(NULL)
#else
,ent_MPI_BI(NULL),sort_MPI_BI(NULL),ent_MPI_PI(NULL),sort_MPI_PI(NULL)
,taille_buffer_Nouvelle_enreg_MPI(10000),buffer_MPI(NULL)
,lecture_MPI_BI_en_cours(0),taille_actuelle_buffer(0)
,dernier_posi_dans_buffer(0)
#endif
,dernier_increment_lu(0),ptrcommandefich(NULL),ptrschemaXMLfich(NULL)
,sort_princ_vrml(NULL),sort_legende_vrml(NULL),sort_princ_maple(NULL)
,sort__temps_cpu(NULL)
,sort_princ_geomview(NULL),sort_legende_geomview(NULL)
,sort_initial_Gid(NULL), sort_resultat_Gid(NULL)
,ent_CommandeVisu(NULL),sort_CommandeVisu(NULL)
,tablcarCVisu(NULL),tableauCVisu(NULL),maille1(NULL)
,ptnomCVisu(NULL),pteurnom(NULL),nomRacineCVisu()
,sort_initial_Gmsh(NULL),sort_resultat_Gmsh(),noms_base_fichiers_gmsh()
,tabMultiLignes(NULL)
2023-05-03 17:23:49 +02:00
#ifdef UTILISATION_MPI
// cas d'un calcul //, num du cpu en cours dans les opérations
,num_cpu_en_cours_BI(0) // d'i/o sur .BI et .PI
#endif
{ bool fr = ParaGlob::Francais(); // pour simplifier
#ifdef UTILISATION_MPI
num_cpu_en_cours_BI = ParaGlob::Monde()->rank();
#endif
// information concernant l'entrée des données
if (fr){cout << "\n -- initialisation de l'entree des donnees ";}
else {cout << "\n -- initialisation of the data input ";};
// tout d'abord on regarde qu'elle etait le nom utilise lors de la derniere
// execution du programme
ifstream auxi("ancienNom");
string ancien; bool ouverture_ancien=false;
// on regarde l'utilisation de la sauvegarde de l'ancienne racine
if (!auxi)
//cas d'une erreur a l'ouverture parce que pas de fichier
// lecture de la racine du nom du fichier princial
{ ouverture_ancien=false;}
else
{ auxi >> ancien; // lecture de l'ancien nom
// lecture de la racine du nom du fichier princial
if (ancien.length() == 0)
{ouverture_ancien=false;}
else
{ouverture_ancien=true;};
};
// on regarde maintenant s'il y a passage du nom dans les arguments
lec_ent_info=-10; // init
bool entree_par_argument= EntreeParArgument(argc,argv);
// on regarde s'il y a eu pb et que rien n'est initialisé, il faut arrêter
if (entree_par_argument)
if (lec_ent_info==-100) return;
// s'il n'y a pas eu d'entrée par argument on effectue une entrée interactive
if (!entree_par_argument)
EntreeInteractive(ancien,ouverture_ancien);
// on regarde s'il y a eu pb et que rien n'est initialisé, il faut arrêter
if (lec_ent_info==-100) return;
// traitement en fonction de lec_ent_info
switch (lec_ent_info)
{ case -12 : // --------- cas de la construction shema XML d'entrée de données .info ----
{ if (fr) {cout << " racine du nom de fichier principal = " << nomRacine << endl;}
else {cout << " first part of the name for the principal file = " << nomRacine << endl;};
// stockage du nom de fichier courant ouvert
nomCourant = nomRacine;
break;
}
case -11 : // --------- cas de la construction d'un fichier de commande .info ----
{ if (fr) {cout << " racine du nom de fichier principal = " << nomRacine << endl;}
else {cout << " first part of the name for the principal file = " << nomRacine << endl;};
// stockage du nom de fichier courant ouvert
nomCourant = nomRacine;
break;
}
case 0 : case 3: // ------------ cas d'une entrée via un fichier .info ----------
{ if (fr) {cout << " racine du nom de fichier principal = " << nomRacine << endl;}
else {cout << " first part of the name for the principal file = " << nomRacine << endl;};
// stockage du nom de fichier courant ouvert
nomCourant = nomRacine;
break;
}
case 1 : // --------------cas d'une entrée via un fichier .base-info------------
{ if (fr) {cout << "\n entrer le nom du fichier .base-info : (" << ancien <<").base-info \n"
<< " ou repondre o ou 0 si l'on veut l'ancien nom (le dernier utilise)\n";}
else {cout << "\n enter the name of the file .base-info : (" << ancien <<").base-info \n"
<< " or answer y or Y if you want the old name (last used) \n";};
nomRacine= lect_chaine();
if ((nomRacine == "0")||(nomRacine == "o")||(nomRacine == "y")||(nomRacine == "Y"))
{ nomRacine = ancien;
// stockage du nom de fichier courant ouvert
nomCourant = nomRacine;
};
break;
}
case 2 : // --------------cas d'une entrée via un serveur .base-info------------
{ if (fr) {cout << " cas actuellement non traite = entree de donnees via un serveur base-info \n";}
else {cout << " at this time, not possible = input data with a server for <base-info> file\n";};
cout << " UtilLecture::UtilLecture () " << endl;
Sortie(1);
break;
}
default :
if (fr) {cout << "\nErreur : valeur incorrecte de lec_ent_info =" << lec_ent_info << " !\n";}
else {cout << "\nError : incorrect value for lec_ent_info =" << lec_ent_info << " !\n";};
cout << "UtilLecture::UtilLecture () " << endl;
Sortie(1);
};
// sauvegarde de la racine dans le cas où on ne veut pas un schéma
auxi.close();
if (lec_ent_info != -12)
{ofstream auxo("ancienNom");
if (auxo)
{auxo << nomRacine;} // sauvegarde de la racine
else
{if (fr) {cout << "pb en ouverture en ecriture du fichier <ancienNom> , on continu quand meme ";}
else {cout << "problem in the opening of the file <ancienNom> but we continue as we can !! ";};
};
};
tablcar = new char [longueur] ; // def du tableau de travail
tableau = new char [longueur] ; // def du tableau intermediaire
tabMultiLignes = new char [longueur]; // def du tableau pour le stockage de plusieurs lignes
#ifndef UTILISATION_MPI
buffer_MPI = new char [taille_buffer_Nouvelle_enreg_MPI];
#endif
// def du flot d'entree filtree en memoire
// utilise pour les conversions de type en lecture
#ifndef ENLINUX_STREAM
entree = new istringstream(tablcar,longueur) ;
#else
entree = new istrstream(tablcar,longueur) ;
#endif
// adressage du pointeur de nomRacine
pteurnom = (char*)nomRacine.c_str();
nomRacineCVisu = nomRacine; // par défaut le nom de la racine de .CVisu est identique
ptnomCVisu = (char*)nomRacineCVisu.c_str();
// lecture des commandes de visualisation (même technique en simplifié que pour .info)
tablcarCVisu = new char [longueur] ; // def du tableau de travail
tableauCVisu = new char [longueur] ; // def du tableau intermediaire
// def du flot d'entree filtree en memoire
// utilise pour les conversions de type en lecture
#ifndef ENLINUX_STREAM
entCVisu = new istringstream(tablcarCVisu,longueur) ;
#else
entCVisu = new istrstream(tablcarCVisu,longueur) ;
#endif
};
// DESTRUCTEUR :
UtilLecture::~UtilLecture ()
{ if (ptrfich!= NULL) {delete ptrfich;ptrfich=NULL;}
if (ptrcommandefich!= NULL) {delete ptrcommandefich;ptrcommandefich=NULL;}
if (ptrschemaXMLfich!= NULL) {delete ptrschemaXMLfich;ptrschemaXMLfich=NULL;}
// ****** pour l'instant la suite ne marche pas ?? mais ce n'est pas normal
// ****** erreur bizarre
// c'est sans doute qu'il y a une confusion entre des vrais tableaux c de charactères = chaine de caractère
// et le tableau du type caractère et je me demande s'il faut des destructeurs pour ce type de tableau
//// = modif nov 2009 avec le passage sur linux .... il faudra regarder cela du plus près ***************
// if (tablcar != NULL) {delete [] tablcar;tablcar=NULL;}
//// if (tableau != NULL) {delete [] tableau;tableau=NULL;};
// if (tablcarCVisu != NULL) {delete [] tablcarCVisu;tablcarCVisu=NULL;}
//// if (tableauCVisu != NULL) {delete [] tableauCVisu;tableauCVisu=NULL;};
//// if (tabMultiLignes != NULL) {delete [] tabMultiLignes; tabMultiLignes=NULL;};
#ifndef UTILISATION_MPI
if (buffer_MPI != NULL) delete[] buffer_MPI;
#endif
Fermeture_base_info();
Fermeture_fichier_principal_vrml();
Fermeture_fichier_principal_vrml();
Fermeture_fichier_principal_maple();
Fermeture_fichier_principal_geomview();
Fermeture_fichier_principal_geomview();
Fermeture_fichier_initial_Gid();
Fermeture_fichier_resultat_Gid();
Fermeture_fichier_initial_Gmsh();
Fermeture_TousLesFichiersResultats_Gmsh();
Fermeture_fichier_temps_cpu();
} ;
// ouverture du fichier principal principal de lecture
int UtilLecture::OuvrirFichier ()
{ char nomm[132];
char*fileName = nomm;
bool fr = ParaGlob::Francais(); // pour simplifier
strcpy(fileName, pteurnom);
// traitement en fonction de lec_ent_info
switch (lec_ent_info)
{ case -12 : // --------- cas de la construction shema XML d'entrée de données .info ----
{ ptrschemaXMLfich = new ofstream(strcat(fileName,".xsd"));
if(!(ptrschemaXMLfich->is_open()))
{ if (fr){cout << "\n erreur en ouverture du fichier " << fileName << endl;}
else {cout << "\n error in opening of the file " << fileName << endl;};
Sortie(1);
};
break;
}
case -11 : // ------------ cas d'une sortie via un fichier .info ----------
{// on va essayer d'éviter d'écraser un fichier déjà existant.
// a) on essaie d'ouvrir le fichier en lecture
ifstream * essai = new ifstream(strcat(fileName,".info"));
string rep(" ");
if (essai->is_open())
{// l'ouverture est ok ==> il existe déjà
cout << "\n ****** attention, le fichier "<<fileName
<< " existe deja !!\n voulez-vous vraiment l'ecraser ? (o / n) "<<flush;
rep = lect_o_n(false);
Minuscules(rep);
if (rep != "o")
{ cout << "\n pas d'ecrasement ==> donc on termine l'execution ";
Sortie(1);
}
else // sinon on veut vraiment l'écraser
{essai->close();
}; // on ferme le fichier en lecture et on continue
};
// cas où le fichier n'existe pas ou qu'on veut écraser un fichier existant
// ptrcommandefich = new ofstream(strcat(fileName,".info"));
ptrcommandefich = new ofstream(fileName); // fileName contient déjà le suffixe .info
if(!(ptrcommandefich->is_open()))
{ if (fr){cout << "\n erreur en ouverture du fichier " << fileName << endl;}
else {cout << "\n error in opening of the file " << fileName << endl;};
Sortie(1);
};
break;
}
case 0 : // ------------ cas d'une entrée via un fichier .info ----------
{ ptrfich = new ifstream(strcat(fileName,".info"));
if(!(ptrfich->is_open()))
{ if (fr){cout << "\n erreur en ouverture du fichier " << fileName << endl;}
else {cout << "\n error in opening of the file " << fileName << endl;};
Sortie(1);
};
// initialisation de la liste chainee d'ouverture de fichier
string no(fileName);
maille1 = new PointFich (NULL,ptrfich,no);
break;
}
case 1 : // --------------cas d'une entrée via un fichier .base-info------------
{ Ouverture_base_info("lecture");
break;
}
case 2 : // --------------cas d'une entrée via un serveur .base-info------------
{ if (fr){cout << " cas actuellement non traite = entree de données via un serveur base-info \n";}
else {cout << " case not possible for the moment = input data with a server for <base-info> file \n";};
cout << " UtilLecture::OuvrirFichier () " << endl;
Sortie(1);
break;
}
default :
if (fr){cout << "\nErreur : valeur incorrecte de lec_ent_info =" << lec_ent_info << " !\n";}
else {cout << "\nerror : incorrect value of lec_ent_info =" << lec_ent_info << " !\n";};
cout << "UtilLecture::OuvrirFichier () " << endl;
Sortie(1);
};
return lec_ent_info;
};
// raffraichir le dernier fichier de lecture .info en cours
// il y a fermeture puis ouverture au même endroit du fichier .info
void UtilLecture::Raffraichir_pointInfo()
{ // on commence par récupérer l'adresse actuelle dans le fichier
streampos position = maille1->sauvePtr->tellg();
// puis le nom
string nom_du_pointInfo = maille1->nom;
// on ferme le fichier
delete maille1->sauvePtr;
// on le reouvre
maille1->sauvePtr = new ifstream(nom_du_pointInfo.c_str());
bool fr = ParaGlob::Francais(); // pour simplifier
if(!(maille1->sauvePtr->is_open()))
{ if (fr){cout << "\n erreur en re-ouverture du fichier " << nom_du_pointInfo << endl;}
else {cout << "\n error in re-opening of the file " << nom_du_pointInfo << endl;};
Sortie(1);
};
// on se repositionne dans le fichier
maille1->sauvePtr->clear(); // on remet à 0 les bits de contrôle au cas où
maille1->sauvePtr->seekg(position, ios::beg);
};
// fermeture du fichier .info
void UtilLecture::fermeture_pointInfo()
{ if (ptrcommandefich!= NULL) {delete ptrcommandefich;ptrcommandefich=NULL;}
};
// fermeture du fichier SchemaXML
void UtilLecture::fermetureSchemaXML()
{ if (ptrschemaXMLfich!= NULL) {delete ptrschemaXMLfich;ptrschemaXMLfich=NULL;}
};
// ouverture du fichier de copie des infos lue par le programme
void UtilLecture::OuvrirCopie()
{ char noml[132];
char*fileName = noml;
strcpy(fileName, pteurnom);
copie = new ofstream(strcat(fileName,".copie"));
if(!(copie->is_open()))
{ cout << "\n erreur en ouverture du fichier de copie " << fileName << endl;
Sortie(1);
};
};
//fermeture du fichier de copie des infos lue par le programme
void UtilLecture::FermerCopie()
{ delete copie;
};
// lecture d'une nouvelle ligne de donnee utilisable pour l'entree de donnee
void UtilLecture::NouvelleDonnee()
{
int indicboucle = 0; // indicateur pour sortir de la boucle globale
2023-05-03 17:23:49 +02:00
// int indicfichier = 0 ; // indicateur pour la fermeture de fichier
try
{
while (indicboucle == 0)
{
Nouvel_enreg(); // lecture d'un enreg ds le fichier courant
char* pentree ; // position du carractere "<"
pentree = strchr(tablcar,'<'); // position eventurelle de "<"
if ( pentree != NULL)
{ pentree++;NouveauFichier(pentree); }
else
{ indicboucle = 1; };
};
// on repositionne le flot au debut du tableau de carractere
// ouverture du flot a la longueur sans blanc
delete entree;
#ifndef ENLINUX_STREAM
entree = new istringstream(tablcar,strlen (tablcar)) ;
#else
entree = new istrstream(tablcar,(long)strlen (tablcar)) ;
#endif
}
// sortie normale du programme
catch (ErrNouvelEnreg erreur)
{ if ( erreur.lecture == 1) // on a atteind une fin de fichier
{ int indic; FermetureFichier(indic);
if (indic == 0) // cas ou il reste encore un fichier ouvert
{ NouvelleDonnee(); // appel recursif de la lecture
// on repositionne le flot au debut du tableau de carractere
// ouverture du flot a la longueur sans blanc
delete entree;
#ifndef ENLINUX_STREAM
entree = new istringstream(tablcar,strlen (tablcar)) ;
#else
entree = new istrstream(tablcar,(long)strlen (tablcar)) ;
#endif
}
else
throw (ErrNouvelleDonnee(1)); // fin de tous les fichiers atteind
}
else
throw (ErrNouvelleDonnee(-1)); // erreur en fermeture de fichier
}
};
// idem avec la méthode NouvelleDonnee()
// mais sans ouverture de fichier automatique
// le signe < est conservé dans la ligne
void UtilLecture::NouvelleDonneeSansInf()
{
int indicboucle = 0; // indicateur pour sortir de la boucle globale
2023-05-03 17:23:49 +02:00
// int indicfichier = 0 ; // indicateur pour la fermeture de fichier
try
{
while (indicboucle == 0)
{
Nouvel_enreg(); // lecture d'un enreg ds le fichier courant
indicboucle = 1;
};
// on repositionne le flot au debut du tableau de carractere
// ouverture du flot a la longueur sans blanc
delete entree;
#ifndef ENLINUX_STREAM
entree = new istringstream(tablcar,strlen (tablcar)) ;
#else
entree = new istrstream(tablcar,(long)strlen (tablcar)) ;
#endif
}
// sortie normale du programme
catch (ErrNouvelEnreg erreur)
{ if ( erreur.lecture == 1) // on a atteind une fin de fichier
{ int indic; FermetureFichier(indic);
if (indic == 0) // cas ou il reste encore un fichier ouvert
{ NouvelleDonnee(); // appel recursif de la lecture
// on repositionne le flot au debut du tableau de carractere
// ouverture du flot a la longueur sans blanc
delete entree;
#ifndef ENLINUX_STREAM
entree = new istringstream(tablcar,strlen (tablcar)) ;
#else
entree = new istrstream(tablcar,(long)strlen (tablcar)) ;
#endif
}
else
throw (ErrNouvelleDonnee(1)); // fin de tous les fichiers atteind
}
else
throw (ErrNouvelleDonnee(-1)); // erreur en fermeture de fichier
};
};
// Retour du flot au debut de l'enregistrement
void UtilLecture::FlotDebutDonnee()
{// on repositionne le flot au debut du tableau de carractere
delete entree;
#ifndef ENLINUX_STREAM
entree = new istringstream(tablcar,strlen (tablcar)) ;
#else
entree = new istrstream(tablcar,(long) strlen (tablcar)) ;
#endif
};
// ecriture d'un message d'erreur du a une mauvaise lecture
void UtilLecture::ErreurLecture
(UtilLecture::ErrNouvelleDonnee erreur,char* message)
{ cout << "\n***** erreur en lecture *********"<< '\n';
cout << message << '\n';
if ( erreur.lecture == 1)
{ cout << " fin de fichier atteinte" << '\n'; }
else if ( erreur.lecture == -1 )
{ cout << "erreur de lecture \n";}
else
cout << " cas non prevu\n " ;
cout << " contenu de la ligne courante filtree lue " << tablcar << '\n';
cout << " contenu de la ligne courante non filtree lue " << tableau << '\n';
cout << "racine du fichier principal = " << nomRacine << '\n';
cout << " fichier courant ouvert en lecture = " << nomCourant << '\n';
cout << " numero de la ligne courante = " << maille1->numLigne << '\n';
cout << endl;
};
// ecriture d'un message et du contenu des buffers courant
void UtilLecture::MessageBuffer(string message)
{
cout << "\n****** " << message << "******** " << '\n';
cout << "\n** information sur les buffers **"<< '\n';
cout << " contenu de la ligne courante filtree lue = " << tablcar << '\n';
cout << " contenu de la ligne courante non filtree lue = " << tableau << '\n';
cout << "racine du fichier principal = " << nomRacine << '\n';
cout << " fichier courant ouvert en lecture = " << nomCourant << '\n';
if (maille1 != NULL)
cout << " numero de la ligne courante = " << maille1->numLigne << '\n';
cout << endl;
};
// recherche d'une chaine de carractere pointee par nom
void UtilLecture::Cherche(const char * nom)
{ do { NouvelleDonnee(); }
while(strstr(tablcar,nom)==NULL);
};
// ouverture d'un nouveau fichier
void UtilLecture::NouveauFichier(char* ptr)
{
ifstream * sPtr = ptrfich; // sauve de l'adresse
// passage des carracteres "espace" eventuelle
int fii = 1;
while((*ptr == ' ')&&(fii<longueur)) {fii++; ptr++;};
ptrfich = new ifstream(ptr); // ouverture d'un nouveau fichier
nomCourant = ptr;
// gestion d'erreur d'ouverture non admise pour la suite du programme
if(!(ptrfich->is_open()))
{ if (ParaGlob::Francais())
{cout << " cas d'un fichier decrit par la commande < " << '\n'
<< " erreur en ouverture du fichier = " << (string(ptr)) << endl;
}
else
{cout << " case of an include file, introduced by the command < " << '\n'
<< " error in opening the file = " << (string(ptr)) << endl;
};
Sortie(1);
};
// ajout d'un maillon a la liste chainee d'ouverture de fichier
PointFich* poi = maille1;
maille1 = new PointFich (poi,sPtr,nomCourant);
};
// fermeture d'un fichier
void UtilLecture::FermetureFichier(int& indic)
{
// retour sur le fichier precedent si possible
if (maille1->t1 != NULL)
{
delete ptrfich; //fermeture du fichier
ptrfich = maille1->sauvePtr; // recup de l'adresse fichier
PointFich* poi = maille1->t1; // sauve adresse precedente
delete maille1; // suppression de la maille courante
maille1 = poi; // et pointage sur la maille precedente
nomCourant = maille1->nom; // mise a jour du nomcourant de fichier ouvert
indic = 0; // operation reussie
}
else
indic = 1; // fin des fichiers intermediaires atteinte
};
// affichage sur la sortie standard de l'enregistrement courant
void UtilLecture::AfficheEnreg () const
{ cout << tablcar << '\n';
};
// entrée par argument au niveau de la construction de l'objet UtilLecture
// dans le cas où il y a eu un pb lec_ent_info=-100, et rien n'est initialisé
bool UtilLecture::EntreeParArgument(int argc, const char * argv[])
{ // on regarde maintenant s'il y a passage par arguments
// le premier argument est le nom du programme qui est lancé (semblerait-il)
// donc se qui nous intéresse c'est les arguments suivants
bool entree_par_argument=false;
// par défaut on signale que l'on est en mode de demande de renseignement d'UtilLecture
// mais rien n'est initialisé, il faut arrêter
if (argc > 1)
lec_ent_info=-100; // initialisation par défaut
// === cas où il y a qu'un seul argument ===
if (argc==2)
{int i=1;entree_par_argument=true;
if (argv[i][1]=='f') // -- cas d'une entrée par fichier, il faudrait un second argument
{ cout << "\n usage: -f <nom_fichier_entree>" << endl; }
else if (argv[i][1]=='n') // -- cas de la construction d'un fichier, il faudrait un second argument
{ cout << "\n usage: -n <nom_fichier_sortie(sans le .info)>" << endl; }
else if (argv[i][1]=='x') // -- cas de la construction du shema xml d'entree de donnees
{ entree_par_argument=true;
lec_ent_info = -12;
nomRacine="Herezhpp"; // nom prédéterminé
}
else if (argv[i][1]=='u') // -- cas de l'utilisation d'herezh sous forme d'une procédure umat abaqus
// il faudrait un autre argument
{ cout << "\n usage: -uf <nom_fichier_entree>" << endl; }
else if (argv[i][1]=='h') // -- cas du rappel de l'usage
{ cout << "\n usage: HZpp -[fnxh] <fichier>"
<< "\n -h rappel de l'usage"
<< "\n -f execution avec le fichier de commande qui suit"
<< "\n -x creation du schema XML pour fichier de commande: Herezhpp.xsd"
<< "\n -n creation interactive d'un fichier de commande";
}
}
else // === cas où il y a plusieurs arguments ===
{for (int i=1;i< argc;i++)
{if (argv[i][1]=='f') // -- cas d'une entrée par fichier
{if(i<argc-1)
{ i++;
entree_par_argument=true;
lec_ent_info = 0;
string motinter(argv[i]); // on récupère en string
nomRacine=motinter; // copie
// dans le cas où ".info" figure dans la racine, on supprime cette chaine
int posi = nomRacine.find(".info");
if (posi != string::npos)
{ string nom_inter = nomRacine.substr(0,posi);
nomRacine = nom_inter;
};
}
else
{ cout << "\n usage: -f <nom_fichier_entree>" << endl; }
break; // pour l'instant une seule passe
}
else if (argv[i][1]=='n') // -- cas de la construction d'un fichier
{if(i<argc-1)
{ i++;
entree_par_argument=true;
lec_ent_info = -11;
string motinter(argv[i]); // on récupère en string
nomRacine=motinter; // copie
// dans le cas où ".info" figure dans la racine, on supprime cette chaine
int posi = nomRacine.find(".info");
if (posi != string::npos)
{ string nom_inter = nomRacine.substr(0,posi);
nomRacine = nom_inter;
};
}
else
{ cout << "\n usage: -n <nom_fichier_sortie(sans le .info)>" << endl; }
break; // pour l'instant une seule passe
}
else if (argv[i][1]=='x') // -- cas de la construction d'un shema xml d'entree de donnees
{ cout << "\n usage: -x " << endl;
break;
}
else if (argv[i][1]=='h') // -- cas du rappel de l'usage
{ cout << "\n usage: HZpp -[fnxh] <fichier>"
<< "\n -h rappel de l'usage"
<< "\n -f execution avec le fichier de commande qui suit"
<< "\n -x creation d'un schema XML pour fichier de commande: Herezhpp.xsd"
<< "\n -n creation interactive d'un fichier de commande";
break; // pour l'instant une seule passe
}
};
};
// retour
return entree_par_argument;
};
// entrée interactive au niveau de la construction de l'objet UtilLecture
// dans le cas où il y a eu un pb lec_ent_info=-100, et rien n'est initialisé
void UtilLecture::EntreeInteractive(string& ancien,bool& ouverture_ancien)
{ // entrée interactive
if (!ouverture_ancien)
// pas de possibilité d'utilisation de racine déjà existante
{ nomRacine = "";
while (!((nomRacine.length () != 0) ||
(nomRacine == "1") || (nomRacine == "2")))
{ cout << "\n pb en ouverture en lecture du fichier : ancien"
<< " , on continu quand meme ";
cout << "\n entrer la racine du nom du fichier .info :\n"
<< " ou repondre 1 pour une entree via le fichier base-info\n"
<< " ou repondre 2 pour une entree via un serveur base-info\n"
<< " ou repondre x pour la creation d'un schema XML pour creer\n"
<< " un fichier de commade: Herezhpp.xsd\n"
<< " ou repondre n pour la construction d'un nouveau fichier de commande\n";
nomRacine= lect_chaine();
if (nomRacine == "1")
lec_ent_info = 1;
else if (nomRacine == "2")
lec_ent_info = 2;
else if (nomRacine == "n")
{lec_ent_info = -11;
cout << "\n entrer la racine du nom du fichier de commande a cree : \n";
nomRacine= lect_chaine();
}
else if (nomRacine == "x")
{lec_ent_info = -12;
cout << "\n ====================================== \n";
cout << "\n $$$$$ construction du schema XML $$$$ \n";
cout << "\n $$$$$ fichier: Herezhpp.xsd $$$$ \n";
cout << "\n ====================================== \n";
nomRacine="Herezhpp";
}
else
lec_ent_info = 0;
}
}
else
// utilisation de la racine existante
{ nomRacine = "";
while (!((nomRacine.length () != 0) || (nomRacine == "0") || (nomRacine == "o")
|| (nomRacine == "1") || (nomRacine == "2")))
{ cout << "\n entrer la racine du nom du fichier .info : (" << ancien <<").info \n"
<< " ou repondre o ou 0 si l'on veut l'ancien nom \n"
<< " ou repondre 1 pour une entree via le fichier base-info\n"
<< " ou repondre 2 pour une entree via un serveur base-info\n"
<< " ou repondre x pour la creation d'un schema XML pour creer\n"
<< " un fichier de commade: Herezhpp.xsd\n"
<< " ou repondre n pour la construction d'un nouveau fichier de commande\n";
nomRacine= lect_chaine();
if (nomRacine == "1")
lec_ent_info = 1;
else if (nomRacine == "2")
lec_ent_info = 2;
else if ((nomRacine == "0")||(nomRacine == "o"))
{ lec_ent_info = 0;
nomRacine = ancien;
}
else if (nomRacine == "n")
{lec_ent_info = -11;
cout << "\n entrer la racine du nom du fichier de commande a cree : \n";
nomRacine= lect_chaine();
}
else if (nomRacine == "x")
{lec_ent_info = -12;
cout << "\n ====================================== \n";
cout << "\n $$$$$ construction du schema XML $$$$ \n";
cout << "\n $$$$$ fichier: Herezhpp.xsd $$$$ \n";
cout << "\n ====================================== \n";
nomRacine="Herezhpp";
}
else if (nomRacine.length () != 0)
lec_ent_info = 0;
}
};
// dans le cas où ".info" figure dans la racine, on supprime cette chaine
int posi = nomRacine.find(".info");
if (posi != string::npos)
{ string nom_inter = nomRacine.substr(0,posi);
nomRacine = nom_inter;
};
};
//------------- utilitaires de lecture d'une grandeurs qui peut-être une constante utilisateur ---
double UtilLecture::lect_avec_const_double_utilisateur(string nom_erreur) const
{string nom;
double val; // le retour
*entree >> nom ;
// on regarde si les 3 premières lettres sont C__
if ((nom[0]== 'C')&&(nom[1]== '_')&&(nom[2]== '_'))
// il s'agit d'une constante utilisateur, on récupère sa valeur
{
// on récupère le pointeur correspondant à la grandeur
const void* pointe = (ParaGlob::param->GrandeurGlobal(nom));
if (pointe != NULL)
{TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe);
if ((gr_quelc->Grandeur_pointee()->Type_structure_grandeurAssocie()==TYPE_SIMPLE)
&& (gr_quelc->Grandeur_pointee()->Type_enumGrandeurParticuliere()==PARTICULIER_SCALAIRE_DOUBLE)
)
{val = gr_quelc->Grandeur_pointee()->GrandeurNumOrdre(1);
}
else // sinon pb
{ cout << "\n *** pb dans dans l'utilisation de la constante globale "<< nom
<< " le conteneur lu " << nom << " n'est pas d'un type correct !! "
<< "\n >>> lecture : " << nom_erreur;
if (ParaGlob::NiveauImpression() > 3)
cout << "\n UtilLecture::Lect_avec_const_double_utilisateur(...";
Sortie(1);
};
}
else // sinon pb
{ cout << "\n *** erreur dans l'utilisation de la constante globale "<< nom
<< " la variable n'existe pas !! "
<< "\n >>> lecture : " << nom_erreur
<< "\n >>> lecture : " << nom_erreur;
if (ParaGlob::NiveauImpression() > 3)
cout << "\n UtilLecture::Lect_avec_const_double_utilisateur(...";
Sortie(1);
};
}
else // c'est directement une valeur, on traduit
{val = ChangeReel(nom);};
// retour de la valeur
return val;
};
// modification interactive d'une constante utilisateur
// la constante doit déjà exister
void UtilLecture::Modif_interactive_constante_utilisateur()
{
try
{string nom;
cout << "\n nom de la constante utilisateur a modifier ? ";
cin >> nom ;
cout << " (nom lu: "<< nom << ") ";
// on regarde si les 3 premières lettres sont C__
if ((nom[0]== 'C')&&(nom[1]== '_')&&(nom[2]== '_'))
// il s'agit d'une constante utilisateur, on récupère sa valeur
{
// on récupère le pointeur correspondant à la grandeur
const void* pointe = (ParaGlob::param->GrandeurGlobal(nom));
if (pointe != NULL)
{TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe);
// récup du typeQuelconque
const TypeQuelconque_enum_etendu& enu = gr_quelc->EnuTypeQuelconque();
if (enu == GENERIQUE_UNE_CONSTANTE_GLOB_DOUBLE_UTILISATEUR)
{if ((gr_quelc->Grandeur_pointee()->Type_structure_grandeurAssocie()==TYPE_SIMPLE)
&& (gr_quelc->Grandeur_pointee()->Type_enumGrandeurParticuliere()==PARTICULIER_SCALAIRE_DOUBLE)
)
{// valeur initiale
double val_init = gr_quelc->Grandeur_pointee()->GrandeurNumOrdre(1);
// lecture de la nouvelle valeur
double nevezval;
cout << "\n valeur actuelle " << val_init
<< " nouvelle valeur ? " ;
cin >> nevezval;
if (ParaGlob::NiveauImpression() > 0)
{cout << "\n modification de la constante utilisateur : "<< nom;
cout << " ancienne valeur " << val_init;
cout << " nouvelle valeur lue "<< nevezval ;
};
ParaGlob::param->Mise_a_jour_grandeur_consultable_Scalaire_double(nom,nevezval);
}
else // sinon pb
{ cout << "\n *** pb dans dans la modification de la constante utilisateur "<< nom
<< " le conteneur lu " << nom << " n'est pas d'un type correct !! ";
if (ParaGlob::NiveauImpression() > 3)
cout << "\n UtilLecture::Modif_interactive_constante_utilisateur(...";
Sortie(1);
};
}
else // cas ou on a détecter que la grandeur globale n'est pas une constante utilisateur
{ cout << "\n *** erreur dans l'utilisation de la grandeur globale "<< nom
<< " ce n'est pas une constante utilisateur !! "
<< " *** on ne change rien " ;
if (ParaGlob::NiveauImpression() > 3)
cout << "\n UtilLecture::Modif_interactive_constante_utilisateur(...";
cout <<flush;
};
}
else // cas ou la constante n'existe pas
{ cout << "\n *** erreur dans l'utilisation de la constante utilisateur "<< nom
<< " la variable n'existe pas !! "
<< " *** on ne change rien " ;
if (ParaGlob::NiveauImpression() > 3)
cout << "\n UtilLecture::Modif_interactive_constante_utilisateur(...";
cout <<flush;
};
}
else //cas ou ce n'est pas une constante utilisateur
{cout << "\n *** erreur en lecture d'une constante utilisateur "<< nom
<< " la variable doit commencer par C__ !! "
<< " et on a lue : " << nom
<< " *** on ne change rien " ;
if (ParaGlob::NiveauImpression() > 3)
cout << "\n UtilLecture::Modif_interactive_constante_utilisateur(...";
cout <<flush;
};
}
// sortie anormale normale du programme
catch (ErrSortieFinale)
// cas d'une direction voulue vers la sortie
// on relance l'interuption pour le niveau supérieur
{ ErrSortieFinale toto;
throw (toto);
}
catch (...)
{cout << "\n *** erreur inconnue en modification d'une constante utilisateur "
<< " *** on ne change rien " ;
if (ParaGlob::NiveauImpression() > 3)
cout << "\n UtilLecture::Modif_interactive_constante_utilisateur(...";
cout <<flush;
};
std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );// purge de cin
};