1492 lines
68 KiB
C++
Executable file
1492 lines
68 KiB
C++
Executable file
// 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 "Fonction_externe_nD.h"
|
|
#include "Sortie.h"
|
|
#include "ConstMath.h"
|
|
#include "MathUtil.h"
|
|
#include "ParaGlob.h"
|
|
#include "MotCle.h"
|
|
#include "TypeQuelconqueParticulier.h"
|
|
#include "CharUtil.h"
|
|
|
|
// --- fichier pour le tube ------
|
|
#ifdef SYSTEM_MAC_OS_CARBON
|
|
#include <types.h>
|
|
#include <stat.h>
|
|
#else
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#endif
|
|
|
|
#include <stdio.h>
|
|
#include <fcntl.h> /* Pour O_WRONLY, etc */
|
|
|
|
#include <unistd.h> // pour les ordres read write close
|
|
|
|
|
|
int stat(const char *path, struct stat *buf);
|
|
|
|
|
|
|
|
// CONSTRUCTEURS :
|
|
Fonction_externe_nD::Fonction_externe_nD(string nom) :
|
|
Fonction_nD(nom,FONCTION_EXTERNE_ND)
|
|
,passage(0),envoi(nom+"_envoi_Hz.FIFO"),reception(nom+"_reception_Hz.FIFO")
|
|
,tab_fVal(),tab_ret()
|
|
|
|
// ,ordre_troncature(2)
|
|
{};
|
|
|
|
// def de toutes les grandeurs -> donne une fonction utilisable
|
|
Fonction_externe_nD::Fonction_externe_nD
|
|
( string nom_ref // nom de ref de la fonction
|
|
,Tableau <string >& nom_variables_non_globales // les variables non globales
|
|
,Tableau <Enum_GrandeurGlobale >& enu_variables_globale // enu globaux
|
|
,Tableau <string >& nom_variables_globales_ // idem sous forme de strings
|
|
,int nb_double_ret): // nombre de grandeur en retour de fonction externe
|
|
Fonction_nD(nom_ref,nom_variables_non_globales,enu_variables_globale
|
|
,nom_variables_globales_,FONCTION_EXTERNE_ND )
|
|
// ---- la partie spécifiques à la fonction externe
|
|
,passage(0),envoi(nom_ref+"_envoi_Hz.FIFO"),reception(nom_ref+"_reception_Hz.FIFO")
|
|
,tab_fVal(),tab_ret(nb_double_ret)
|
|
{// Contruction des index pour les grandeurs évoluées, ainsi que les conteneurs
|
|
// --> c'est déjà effectué dans le constructeur de Fonction_nD
|
|
};
|
|
|
|
// de copie
|
|
Fonction_externe_nD::Fonction_externe_nD(const Fonction_externe_nD& Co) :
|
|
Fonction_nD(Co)
|
|
,passage(Co.passage),envoi(Co.envoi),reception(Co.reception)
|
|
,tab_fVal(Co.tab_fVal)
|
|
,tab_ret(Co.tab_ret)
|
|
{ // Contruction des index pour les grandeurs évoluées, ainsi que les conteneurs
|
|
Fonction_nD::Construction_index_conteneurs_evoluees();
|
|
};
|
|
// de copie à partir d'une instance générale
|
|
Fonction_externe_nD::Fonction_externe_nD(const Fonction_nD& Coo) :
|
|
Fonction_nD(Coo)
|
|
,tab_fVal(),tab_ret()
|
|
{ if (Coo.Type_Fonction() != FONCTION_EXTERNE_ND)
|
|
{ cout << "\n erreur dans le constructeur de copie pour une Fonction_externe_nD "
|
|
<< " à partir d'une instance générale ";
|
|
cout << "\n Fonction_externe_nD::Fonction_externe_nD(const Fonction_nD& Co) ";
|
|
Sortie(1);
|
|
};
|
|
// définition des données
|
|
Fonction_externe_nD & Co = (Fonction_externe_nD&) Coo;
|
|
tab_fVal=Co.tab_fVal;
|
|
|
|
// opérations pipe
|
|
passage = Co.passage;
|
|
envoi = Co.envoi; reception = Co.reception;
|
|
|
|
// Contruction des index pour les grandeurs évoluées, ainsi que les conteneurs
|
|
Fonction_nD::Construction_index_conteneurs_evoluees();
|
|
};
|
|
|
|
// DESTRUCTEUR :
|
|
Fonction_externe_nD::~Fonction_externe_nD()
|
|
{};
|
|
|
|
// METHODES PUBLIQUES :
|
|
|
|
// --------- virtuelles ---------
|
|
|
|
// Surcharge de l'operateur = : realise l'egalite de deux fonctions
|
|
Fonction_nD& Fonction_externe_nD::operator= (const Fonction_nD& elt)
|
|
{ // la suite ne peut fonctionner que s'il s'agit d'une fonction de même type
|
|
if (typeFonction != elt.Type_Fonction())
|
|
{cout << "\n *** erreur d'affectation entre fonction nD "
|
|
<< nom_ref << " et " << elt.NomFonction()
|
|
<< "\n Fonction_externe_nD::operator= (..."
|
|
<< endl;
|
|
Sortie(1);
|
|
};
|
|
// on commence par appeler la méthode ad hoc pour la fonction Fonction_nD
|
|
Fonction_nD::Transfert_info(elt);
|
|
// puis on s'occupe des variables de la fonction
|
|
const Fonction_externe_nD & Co = ((Fonction_externe_nD &) elt);
|
|
tab_fVal=Co.tab_fVal;
|
|
|
|
// opérations pipe
|
|
passage = Co.passage;
|
|
envoi = Co.envoi; reception = Co.reception;
|
|
|
|
// Contruction des index pour les grandeurs évoluées, ainsi que les conteneurs
|
|
Fonction_nD::Construction_index_conteneurs_evoluees();
|
|
|
|
return *this;
|
|
};
|
|
|
|
// affichage de la courbe
|
|
void Fonction_externe_nD::Affiche(int niveau) const
|
|
{ cout << " Fonction_externe_nD " << nom_ref ;
|
|
cout << " \n arguments= " << nom_variables
|
|
<< " \n variables_globales_en_enumere= " ;
|
|
int nb_enu = enu_variables_globale.Taille();
|
|
cout << "taille " << nb_enu << " ";
|
|
for (int i=1;i<= nb_enu;i++)
|
|
cout << Nom_GrandeurGlobale(enu_variables_globale(i)) << " ";
|
|
|
|
cout << " \n variables_globales_en_string= " ;
|
|
int nb_str = nom_variables_globales.Taille();
|
|
cout << "taille " << nb_str << " ";
|
|
for (int i=1;i<= nb_str;i++)
|
|
cout << nom_variables_globales(i) << " ";
|
|
|
|
cout << "\n taille vecteur de retour: "<< this->NbComposante()
|
|
<< "\n f(x)= fonction utilisateur externe, dialogue via des pipes nommes"
|
|
<< "\n pipe d'envoi: "<< envoi << " , pipe de reception: "<< reception ;
|
|
// appel de la méthode associée de la classe virtuelle
|
|
Affiche_interne(niveau);
|
|
if (niveau > 0)
|
|
{ cout << "\n derniers parametres d'appel: ";
|
|
int nb_var = tab_fVal.Taille();
|
|
for (int j=1;j<=nb_var;j++)
|
|
{ cout << " para("<<j<<")= "<< tab_fVal(j);}
|
|
cout << "\n dernieres valeurs de retour de la fonction: ";
|
|
cout << tab_ret ;
|
|
};
|
|
cout << "\n ----- fin fonction Fonction_externe_nD ----- ";
|
|
};
|
|
|
|
// vérification que tout est ok, pres à l'emploi
|
|
// ramène true si ok, false sinon
|
|
bool Fonction_externe_nD::Complet_Fonction(bool affichage)const
|
|
{ bool ret = Complet_var(); // on regarde du coté de la classe mère tout d'abord
|
|
// puis les variables propres
|
|
return ret;
|
|
} ;
|
|
|
|
// Lecture des donnees de la classe sur fichier
|
|
// le nom passé en paramètre est le nom de la courbe
|
|
// s'il est vide c-a-d = "", la methode commence par lire le nom sinon
|
|
// ce nom remplace le nom actuel
|
|
void Fonction_externe_nD::LectDonnParticulieres_Fonction_nD(const string& nom,UtilLecture * entreePrinc)
|
|
{
|
|
if (nom == "") { *(entreePrinc->entree) >> nom_ref;}
|
|
else {nom_ref=nom;};
|
|
entreePrinc->NouvelleDonnee(); // lecture d'une nouvelle ligne
|
|
|
|
// on initialise le tableau de retour qui doit-être redimensionné en lecture
|
|
tab_ret.Change_taille(0);
|
|
|
|
// on lit tant que l'on ne rencontre pas la ligne contenant "fin_parametres_fonction_externe_"
|
|
// ou un nouveau mot clé global auquel cas il y a pb !!
|
|
MotCle motCle; // ref aux mots cle
|
|
list < string> list_de_variables; // liste intermédiaire
|
|
list <Enum_GrandeurGlobale > list_enu_variables_glob; // idem enum glob
|
|
list < string> list_de_variables_nom_globales; // idem string glob
|
|
string titi;
|
|
while (strstr(entreePrinc->tablcar,"fin_parametres_fonction_externe_")==0)
|
|
{
|
|
// si on a un mot clé global dans la ligne courante c-a-d dans tablcar --> erreur
|
|
if ( motCle.SimotCle(entreePrinc->tablcar))
|
|
{ cout << "\n erreur de lecture des parametre de definition d'une courbe avec expression litterale : on n'a pas trouve le mot cle "
|
|
<< " fin_parametres_fonction_externe_ et par contre la ligne courante contient un mot cle global ";
|
|
entreePrinc->MessageBuffer("** erreur des parametres d'une courbe expression litterale **");
|
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
|
Sortie(1);
|
|
};
|
|
|
|
// lecture d'un mot clé
|
|
*(entreePrinc->entree) >> titi;
|
|
|
|
if ((entreePrinc->entree)->rdstate() == 0)
|
|
{} // lecture normale
|
|
#ifdef ENLINUX
|
|
else if ((entreePrinc->entree)->fail())
|
|
// on a atteind la fin de la ligne et on appelle un nouvel enregistrement
|
|
{ // on lit sans tenir compte des < éventuelles
|
|
entreePrinc->NouvelleDonneeSansInf();
|
|
*(entreePrinc->entree) >>titi;
|
|
}
|
|
#else
|
|
else if ((entreePrinc->entree)->eof())
|
|
// la lecture est bonne mais on a atteind la fin de la ligne
|
|
{ if(titi != "fin_parametres_fonction_externe_")
|
|
// on lit sans tenir compte des < éventuelles
|
|
{entreePrinc->NouvelleDonneeSansInf();
|
|
*(entreePrinc->entree) >> titi;
|
|
};
|
|
}
|
|
#endif
|
|
else // cas d'une erreur de lecture
|
|
{ cout << "\n erreur de lecture inconnue ";
|
|
entreePrinc->MessageBuffer("** erreur2 des parametres d'une courbe expression litterale**");
|
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
|
Sortie(1);
|
|
};
|
|
|
|
// on lit maintenant la ou les variables
|
|
// cas de la lecture d'une variable
|
|
if(titi == "un_argument=")
|
|
{string truc; *(entreePrinc->entree) >> truc;
|
|
// on regarde s'il s'agit d'une variable globale correspondant à un énuméré global
|
|
if (EstUneGrandeurGlobale(truc))
|
|
{ list_enu_variables_glob.push_back(Id_nom_GrandeurGlobale (truc));}
|
|
// idem mais sous forme d'un string
|
|
else if (ParaGlob::param->GrandeurGlobal(truc) != NULL)
|
|
{ list_de_variables_nom_globales.push_back(truc);}
|
|
else // sinon ce n'est pas une grandeur globale
|
|
{list_de_variables.push_back(truc);};
|
|
}
|
|
else if(titi == "deb_list_var_") // lecture d'une liste d'argument
|
|
{// on va lire juqu'au mot clé fin_list_var_
|
|
int nb_boucle = 0; // indicateur pour éviter une boucle infinie
|
|
do
|
|
{string truc; *(entreePrinc->entree) >> truc;
|
|
if (truc == "fin_list_var_")
|
|
break;
|
|
// on regarde s'il s'agit d'une variable globale
|
|
if (EstUneGrandeurGlobale(truc))
|
|
{ list_enu_variables_glob.push_back(Id_nom_GrandeurGlobale (truc));}
|
|
// idem mais sous forme d'un string
|
|
else if (ParaGlob::param->GrandeurGlobal(truc) != NULL)
|
|
{ list_de_variables_nom_globales.push_back(truc);}
|
|
else // sinon ce n'est pas une grandeur globale
|
|
{list_de_variables.push_back(truc);};
|
|
nb_boucle++;
|
|
} while (nb_boucle < 200);
|
|
if (nb_boucle > 199)
|
|
{ cout << "\n erreur de lecture au niveau d'une liste de variable "
|
|
<< " deb_list_var_ nom1 nom2 ... fin_list_var_";
|
|
entreePrinc->MessageBuffer("** erreur lecture parametre d'une courbe expression litterale **");
|
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
|
Sortie(1);
|
|
}
|
|
else // sinon la lecture est ok a priori
|
|
;
|
|
}
|
|
// cas de la lecture du niveau d'impression pour les erreurs
|
|
else if(titi == "permet_affichage_")
|
|
{*(entreePrinc->entree) >> permet_affichage;
|
|
}
|
|
// cas de la lecture du type d'expression du tenseur
|
|
else if(titi == "Tenseur_base_ad_hoc_")
|
|
{*(entreePrinc->entree) >> absolue;
|
|
}
|
|
// cas de la lecture de la taille du vecteur retour
|
|
else if(titi == "nb_double_ret_")
|
|
{int nb_double_ret; // nombre de grandeur en retour de fonction externe
|
|
*(entreePrinc->entree) >> nb_double_ret;
|
|
if (nb_double_ret < 1)
|
|
{cout << "\n erreur en lecture du nombre de grandeur en retour de fonction externe "
|
|
<< " qui doit etre >= 1, on a lu : " << nb_double_ret << endl;
|
|
entreePrinc->MessageBuffer("**Fonction_externe_nD::LectureDonneesParticulieres**");
|
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
|
Sortie(1);
|
|
}
|
|
else tab_ret.Change_taille(nb_double_ret); // cas ok
|
|
}
|
|
// sinon ce n'est pas un mot clé connu, on le signale
|
|
else if(titi != "fin_parametres_fonction_externe_")
|
|
{ cout << "\n erreur en lecture d'un parametre, le mot cle est inconnu "
|
|
<< " on a lu : " << titi << endl;
|
|
entreePrinc->MessageBuffer("**Fonction_externe_nD::LectureDonneesParticulieres**");
|
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
|
Sortie(1);
|
|
};
|
|
|
|
}; //-- fin du while
|
|
|
|
// on vérifie que l'on a bien redimensionné le tableau de retour
|
|
if ( tab_ret.Taille() == 0)
|
|
{cout << "\n erreur en definition de la fonction externe, il manque le dimensionnement du vecteur de retour !! "
|
|
<< " qui doit etre >= 1 " << endl;
|
|
entreePrinc->MessageBuffer("**Fonction_externe_nD::LectureDonneesParticulieres**");
|
|
throw (UtilLecture::ErrNouvelleDonnee(-1));
|
|
Sortie(1);
|
|
};
|
|
|
|
// on supprime les doublons dans les variables globales
|
|
list_enu_variables_glob.sort();
|
|
list_enu_variables_glob.unique();
|
|
list_de_variables_nom_globales.sort();
|
|
list_de_variables_nom_globales.unique();
|
|
// on parcours les variables globales patentées
|
|
int nb_enu = list_enu_variables_glob.size();
|
|
int ienu=1; enu_variables_globale.Change_taille(nb_enu);
|
|
{list <Enum_GrandeurGlobale >::iterator il,ilfin=list_enu_variables_glob.end();
|
|
for (il=list_enu_variables_glob.begin();il!=ilfin;il++,ienu++)
|
|
enu_variables_globale(ienu) = *il;
|
|
};
|
|
// idem pour les noms de ref
|
|
int nb_nom = list_de_variables_nom_globales.size();
|
|
int i_nom=1; nom_variables_globales.Change_taille(nb_nom);
|
|
{list <string >::iterator il,ilfin=list_de_variables_nom_globales.end();
|
|
for (il=list_de_variables_nom_globales.begin();il!=ilfin;il++,i_nom++)
|
|
nom_variables_globales(i_nom) = *il;
|
|
};
|
|
|
|
// --- on définie les variables qui ne sont pas globales ---
|
|
// par contre on va changer l'ordre d'apparition des variables
|
|
// en 1) les scalaires, 2) les coordonnées , 3) les tenseurs
|
|
// et .... rajouter
|
|
int taille = list_de_variables.size(); // récup de la taille
|
|
nom_variables.Change_taille(taille); // mise à jour de la taille
|
|
tab_fVal.Change_taille(taille+nb_enu+nb_nom); // idem mais en tenant compte des var globales
|
|
|
|
// vérif qui normalement est inutile, mais on ne sait jamais
|
|
if (tab_fVal.Taille() > 115)
|
|
{ cout << "\n ** erreur dans la construction de la fonction "
|
|
<< nom_ref ;
|
|
cout << " le nombre de parametres d'appel:" << tab_fVal.Taille()
|
|
<< " est superieur a 115 = la limite superieur autorisee "
|
|
<< "\n Fonction_externe_nD::Valeur_FnD_interne(..."<<endl;
|
|
// on génère une interruption ce qui permettra de dépiler les appels
|
|
this->Affiche();ErrCalculFct_nD toto;throw (toto);
|
|
Sortie(1);
|
|
};
|
|
|
|
// cas des variables non globales
|
|
list < string>::iterator il,ilfin = list_de_variables.end();
|
|
int i= 1;
|
|
for (il = list_de_variables.begin();il != ilfin;il++,i++)
|
|
{ nom_variables(i)=(*il); // on récupère le nom
|
|
};
|
|
|
|
// Contruction des index pour les grandeurs évoluées, ainsi que les conteneurs
|
|
Fonction_nD::Construction_index_conteneurs_evoluees();
|
|
// on définit le paramètre depend_M de la classe maître en fonction des nom_variables
|
|
if (permet_affichage > 6)
|
|
cout << "\n == >>> lecture donnees particuliere de la fct: " << nom_ref << ") "
|
|
<< " operations finales: " ;
|
|
Fonction_nD::Definition_depend_M();
|
|
// idem pour le temps
|
|
Fonction_nD::Definition_depend_temps();
|
|
|
|
// initialisation des pipes
|
|
Fonction_externe_nD::InitialisationPipesNommes();
|
|
|
|
};
|
|
|
|
// mise à jour des variables globales: en fonction de l'apparition de nouvelles variables
|
|
// globales en cours de calcul
|
|
void Fonction_externe_nD::Mise_a_jour_variables_globales()
|
|
{ // appel de la fonction interne pour modifier les noms de variables
|
|
Fonction_nD::Mise_a_jour_variables_globales_interne();
|
|
};
|
|
|
|
// def info fichier de commande
|
|
void Fonction_externe_nD::Info_commande_Fonctions_nD(UtilLecture & entreePrinc)
|
|
{ ofstream & sort = *(entreePrinc.Commande_pointInfo()); // pour simplifier
|
|
cout << "\n cas de la fonction Fonction_externe_nD : "
|
|
<< " \ndefinition standart (rep o) ou documentation exhaustive (rep n'importe quoi) ? ";
|
|
string rep = "_"; rep = lect_return_defaut(false,"o");
|
|
sort << "\n# ....... fonction litterale nD ........";
|
|
// cas particulier
|
|
if ((rep == "o") || (rep == "O" ) || (rep == "0") )
|
|
{sort << "\n# exemple de definition d'une fonction Fonction_externe_nD"
|
|
<< " qui renvoi une seule valeur (un reel) "
|
|
<< "\n exemple_fonct_ext_nD FONCTION_EXTERNE_ND "
|
|
<< "\n un_argument= i un_argument= j "
|
|
<< "\n nb_double_ret_ 1 "
|
|
<< "\n fin_parametres_fonction_externe_ "
|
|
<< endl;
|
|
}
|
|
else // cas d'une description exhaustive
|
|
{ sort << "\n# Il s'agit d'une fonction utilisateur qui est definie en dehors d'Herezh "
|
|
<< "\n# a chaque appel de la fonction: "
|
|
<< "\n# 1) les variables sont copiees sur le pipe nomme <nom fonction>_envoi_Hz.FIFO "
|
|
<< "\n# 2) puis Herezh lit la reponse sur le pipe nomme: <nom fonction>_reception_Hz.FIFO "
|
|
<< "\n# ==> tant que les informations ne sont pas disponibles sur le pipe de reception "
|
|
<< "\n# l'execution d'Herezh est stoppee "
|
|
<< "\n# "
|
|
<< "\n# L'utilisation de cette fonction impose donc a l'utilisateur, de construire un programme"
|
|
<< "\n# externe qui lit les donnes sur <nom fonction>_envoi_Hz.FIFO, en deduit les valeurs de retour "
|
|
<< "\n# qui doivent etre ecrite sur <nom fonction>_reception_Hz.FIFO "
|
|
<< "\n# "
|
|
<< "\n# Format d'echange: "
|
|
<< "\n# en ecriture, Herezh ecrit sur le pipe d'envoi: "
|
|
<< "\n# - 2 entiers codes sur 4 octets chacun, qui representent: "
|
|
<< "\n# . le premier n1 = le nombre de variables de la fonction"
|
|
<< "\n# . le second n2 = la taille du vecteur de retour attendu sur le pipe de reception "
|
|
<< "\n# - puis n1 reels, chacun code sur 8 octets "
|
|
<< "\n# "
|
|
<< "\n# en retour, Herezh lit sur le pipe de reception: "
|
|
<< "\n# - 2 entiers codes sur 4 octets chacun, qui representent: "
|
|
<< "\n# . le premier n1 = le nombre de variables de la fonction"
|
|
<< "\n# . le second n2 = la taille du vecteur de retour attendu sur le pipe de reception "
|
|
<< "\n# - puis n2 reels, chacun code sur 8 octets "
|
|
<< "\n# "
|
|
<< "\n# NB: le nombre maximal possible de reels est actuellement de 115 "
|
|
<< "\n# "
|
|
<< "\n# "
|
|
<< "\n# Par exemple, pour une utilisation via un programme C ou C++, une methode est de definir "
|
|
<< "\n# une structure union. Supposons 4 variables, et un vecteur de 2 composantes en retour "
|
|
<< "\n# cela signifie qu'il faut une taille minimale de tampon de passage de: 2*4+4*8= 40 octets"
|
|
<< "\n# equivalent a 5 reels, 10 entiers d'ou un exemple de declaration: "
|
|
<< "\n# union Tab_car_double_int "
|
|
<< "\n# { char tampon[40]; "
|
|
<< "\n# double x[5]; "
|
|
<< "\n# int n[10]; "
|
|
<< "\n# } ; "
|
|
<< "\n# Ensuite, le programme C lit l'information sur le pipe d'envoi de nom ici: envoi, ex: "
|
|
<< "\n# Tab_car_double_int t_car_x_n; "
|
|
<< "\n# char* tampon = &(t_car_x_n.tampon[0]); "
|
|
<< "\n# int nb_carac_a_lire = 40 ; "
|
|
<< "\n# int tub = open(envoi.c_str(),O_RDONLY); "
|
|
<< "\n# read (tub,tampon_,nb_carac_a_lire); "
|
|
<< "\n# close (tub); "
|
|
<< "\n# "
|
|
<< "\n# Les variables sont alors disponible dans le tableau x "
|
|
<< "\n# Puis le programme C calcule les valeurs de retour et les sauvegarde dans x "
|
|
<< "\n# Reste a ramener les infos a Herezh. Pour cela le programme C doit ecrire dans "
|
|
<< "\n# le pipe de retour, ici de nom reception, par ex: "
|
|
<< "\n# "
|
|
<< "\n# int tub = open(reception.c_str(),O_WRONLY); "
|
|
<< "\n# int nb_carac_a_ecrire = 2 * 8 + 2*4 ; "
|
|
<< "\n# write (tub,t_car_x_n.reception,nb_carac_a_ecrire); "
|
|
<< "\n# close (tub); "
|
|
<< "\n# "
|
|
<< "\n# ======= definition d'une fonction externe ===== "
|
|
<< "\n# 1) --- on definit la liste de variables "
|
|
<< "\n# cette liste inclu des variables avec les 2 syntaxes suivantes "
|
|
<< "\n# a) soit une variable par ligne selon la syntaxe: "
|
|
<< "\n# un_argument= nom_argument"
|
|
<< "\n# ou "
|
|
<< "\n# un_argument= : le mot cle "
|
|
<< "\n# nom_argument : le nom de la variable "
|
|
<< "\n# b) soit une liste de variables (sur une ligne) selon la syntaxe "
|
|
<< "\n# deb_list_var_ nom1 nom2 ... fin_list_var_ "
|
|
<< "\n# ou "
|
|
<< "\n# deb_list_var_ et fin_list_var_ : balises encadrant la liste"
|
|
<< "\n# nom1 nom2 ... : le nom de chaque variable "
|
|
<< "\n# "
|
|
<< "\n# NB: les variables peuvent etre des grandeurs locales ou globales"
|
|
<< "\n# "
|
|
<< "\n# 2) --- on definit la taille du vecteur de retour de la fonction externe "
|
|
<< "\n# (note n2 dans les explications precedantes) "
|
|
<< "\n# NB: il n'y a pas de definition par defaut "
|
|
<< "\n# la definition s'effectue via le mot cle: nb_double_ret_ "
|
|
<< "\n# suivi de la taille du vecteur de retour, ex: "
|
|
<< "\n# nb_double_ret_ 1 "
|
|
<< "\n# La liste des variables et la definition de n2 "
|
|
<< "\n# doit se terminer par le mot cle (sur une ligne seule ): "
|
|
<< "\n# fin_parametres_fonction_externe_ "
|
|
<< "\n# "
|
|
<< "\n#............................................"
|
|
<< "\n# exemple de definition d'une fonction Fonction_externe_nD"
|
|
<< " qui renvoi une seule valeur (un reel) "
|
|
<< "\n exemple_fonct_ext_nD FONCTION_EXTERNE_ND "
|
|
<< "\n un_argument= i un_argument= j "
|
|
<< "\n nb_double_ret_ 1 "
|
|
<< "\n fin_parametres_fonction_externe_ "
|
|
<< "\n# "
|
|
<< "\n# type d'expression des tenseurs: "
|
|
<< "\n# Tenseur_base_ad_hoc_ suivi de "
|
|
<< "\n# 0 si dans la base ad hoc "
|
|
<< "\n# 1 si dans une base globale "
|
|
<< "\n# NB: les deux sont en orthonorme "
|
|
<< "\n# par defaut, c'est dans une base ad hoc"
|
|
<< "\n# ex: Tenseur_base_ad_hoc_ 0 "
|
|
<< "\n# "
|
|
<< "\n# niveau d'impression: dans certain cas il peut-etre utile d'afficher "
|
|
<< "\n# les resultats intermediaires des calculs et egalement des erreurs intermediaires "
|
|
<< "\n# pour mettre en route ce fonctionnement il faut indiquer sur une ligne seule le mot cle "
|
|
<< "\n# permet_affichage_ suivi d'un chiffre donnant le niveau d'impression (entre 0 et 10) "
|
|
<< "\n# ex: permet_affichage_ 5 "
|
|
<< "\n# Remarques: 1) ceci ne fonctionne qu'avec la version non fast "
|
|
<< "\n# cependant, la lecture reste correcte avec le mot cle permet_affichage_ "
|
|
<< "\n# mais la presence du mot cle n'entraine aucune action en fast "
|
|
<< "\n# 2) le mot cle doit etre indique avant le dernier mot cle : "
|
|
<< "\n# fin_parametres_fonction_externe_ "
|
|
<< endl;
|
|
};
|
|
};
|
|
|
|
// calcul des valeurs de la fonction, retour d'un tableau de scalaires
|
|
Tableau <double> & Fonction_externe_nD::Valeur_FnD_interne(Tableau <double >* xi)
|
|
{
|
|
|
|
int i_in_xi=1; // indice pour se déplacer dans xi
|
|
int i_fval=1; // indice pour se déplacer dans fval_int
|
|
int taille_xi=0; // init par défaut
|
|
if (xi != NULL)
|
|
taille_xi=xi->Taille();
|
|
|
|
try
|
|
{
|
|
|
|
int nb_var_int = nom_variables.Taille();
|
|
int tail_enu = enu_variables_globale.Taille(); // les variables globales
|
|
int tail_nom = nom_variables_globales.Taille(); // idem avec des noms
|
|
#ifdef MISE_AU_POINT
|
|
if (tab_fVal.Taille() != (taille_xi+tail_enu+tail_nom))
|
|
{ cout << "\n *** pb de dimensions d'argument non coherentes !! "
|
|
<< " taille_xi "<<taille_xi
|
|
<< ", tab_fVal.Taille()= "<<tab_fVal.Taille()
|
|
<< " enu_variables_globale.Taille()= "<<enu_variables_globale
|
|
<< "\n Fonction_externe_nD::Valeur_FnD(..."<<endl;
|
|
this->Affiche();
|
|
// on génère une interruption ce qui permettra de dépiler les appels
|
|
ErrCalculFct_nD toto;
|
|
throw (toto);
|
|
Sortie(1);
|
|
};
|
|
|
|
#endif
|
|
|
|
// on remplit le tableau de passage pour la fonction maître
|
|
// 1) tout d'abord pour les variables patentées
|
|
for (int ii = 1;ii<= nb_var_int;ii++,i_fval++)
|
|
{
|
|
// on se déplace d'abord dans xi
|
|
if (i_in_xi <= taille_xi)
|
|
{tab_fVal(i_fval) = xi->operator()(i_in_xi);i_in_xi++;}
|
|
else
|
|
{ cout << "\n *** pb de nombre d'argument non coherentes !! "
|
|
<< " on n'a pas assez d'arguments pour l'appel de la fonction globale: ";
|
|
this->Affiche();
|
|
cout << "\n revoir la mise en donnees "
|
|
<< "\n Fonction_externe_nD::Valeur_FnD_interne(..."<<endl;
|
|
// on génère une interruption ce qui permettra de dépiler les appels
|
|
ErrCalculFct_nD toto;
|
|
throw (toto);
|
|
Sortie(1);
|
|
};
|
|
};
|
|
|
|
// 2) puis les valeurs globales éventuelles typées énuméré
|
|
/* if (tail_enu>0)
|
|
{
|
|
// en debug on vérifie que les grandeurs globales sont présentent
|
|
#ifdef MISE_AU_POINT
|
|
try
|
|
{ int taille = enu_variables_globale.Taille();
|
|
for (int i=1;i<= taille;i++)
|
|
{// on récupère le pointeur correspondant à la grandeur
|
|
const void* pointe = (ParaGlob::param->GrandeurGlobal(enu_variables_globale(i)));
|
|
if (pointe == NULL)
|
|
{ cout << "\n *** pb dans Fonction_externe_nD " << nom_ref << " !! "
|
|
<< " la variable globale "<< Nom_GrandeurGlobale(enu_variables_globale(i))
|
|
<< ", n'est pas disponible, on ne peut pas continuer "
|
|
<< "\n Fonction_externe_nD::Valeur_FnD_interne(..."<<endl;
|
|
// on génère une interruption ce qui permettra de dépiler les appels
|
|
this->Affiche();ErrCalculFct_nD toto;throw (toto);
|
|
Sortie(1);
|
|
};
|
|
};
|
|
}
|
|
catch(...)
|
|
{ cout << "\n ** erreur dans l'appel de la fonction "
|
|
<< nom_ref ;
|
|
cout << " verifier la presence des grandeurs globales voulues "
|
|
<< "\n Fonction_externe_nD::Valeur_FnD_interne(..."<<endl;
|
|
// on génère une interruption ce qui permettra de dépiler les appels
|
|
this->Affiche();ErrCalculFct_nD toto;throw (toto);
|
|
Sortie(1);
|
|
};
|
|
#endif
|
|
// on parcours les variables globales
|
|
int taille = enu_variables_globale.Taille();
|
|
for (int i=1;i<= taille;i++,i_fval++)
|
|
{// on récupère le pointeur correspondant à la grandeur
|
|
const void* pointe = (ParaGlob::param->GrandeurGlobal(enu_variables_globale(i)));
|
|
TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe);
|
|
switch(gr_quelc->Grandeur_pointee()->Type_structure_grandeurAssocie())
|
|
{ case TYPE_SIMPLE:
|
|
{ switch(gr_quelc->Grandeur_pointee()->Type_enumGrandeurParticuliere())
|
|
{case PARTICULIER_SCALAIRE_ENTIER:
|
|
{Grandeur_scalaire_entier& gr
|
|
= *((Grandeur_scalaire_entier*) gr_quelc->Grandeur_pointee()); // pour simplifier
|
|
tab_fVal(i_fval) = *(gr.ConteneurEntier());
|
|
break;
|
|
}
|
|
case PARTICULIER_SCALAIRE_DOUBLE:
|
|
{Grandeur_scalaire_double& gr
|
|
= *((Grandeur_scalaire_double*) gr_quelc->Grandeur_pointee()); // pour simplifier
|
|
tab_fVal(i_fval) = *(gr.ConteneurDouble());
|
|
break;
|
|
}
|
|
case PARTICULIER_DDL_ETENDU:
|
|
{Grandeur_Ddl_etendu& gr
|
|
= *((Grandeur_Ddl_etendu*) gr_quelc->Grandeur_pointee()); // pour simplifier
|
|
tab_fVal(i_fval) = (gr.GrandeurNumOrdre(1));
|
|
break;
|
|
}
|
|
default:
|
|
{ cout << "\n *** pb dans dans l'appel de la fonction "<< nom_ref
|
|
<< " la variable globale "<< Nom_GrandeurGlobale(enu_variables_globale(i))
|
|
<< ", n'est pas prise en compte actuellement , on ne peut pas continuer "
|
|
<< "\n Fonction_externe_nD::Valeur_FnD_interne(..."
|
|
<<endl;
|
|
// on génère une interruption ce qui permettra de dépiler les appels
|
|
this->Affiche();ErrCalculFct_nD toto;throw (toto);
|
|
Sortie(1);
|
|
};
|
|
}
|
|
|
|
break;
|
|
}
|
|
default:
|
|
{ cout << "\n *** pb dans dans l'appel de la fonction "<< nom_ref
|
|
<< " la variable globale "<< Nom_GrandeurGlobale(enu_variables_globale(i))
|
|
<< ", n'est pas prise en compte actuellement , on ne peut pas continuer "
|
|
<< "\n Fonction_externe_nD::Valeur_FnD_interne(..."
|
|
<<endl;
|
|
// on génère une interruption ce qui permettra de dépiler les appels
|
|
this->Affiche();ErrCalculFct_nD toto;throw (toto);
|
|
Sortie(1);
|
|
};
|
|
};
|
|
};
|
|
};
|
|
// 3) idem pour les globaux en nom c-a-d typées sous forme de string
|
|
if (tail_nom>0)
|
|
{
|
|
// en debug on vérifie que les grandeurs globales sont présentent
|
|
#ifdef MISE_AU_POINT
|
|
try
|
|
{ for (int i=1;i<= tail_nom;i++)
|
|
{// on récupère le pointeur correspondant à la grandeur
|
|
const void* pointe = (ParaGlob::param->GrandeurGlobal(nom_variables_globales(i)));
|
|
if (pointe == NULL)
|
|
{ cout << "\n *** pb dans Fonction_externe_nD " << nom_ref << " !! "
|
|
<< " la variable globale "<< nom_variables_globales(i)
|
|
<< ", n'est pas disponible, on ne peut pas continuer "
|
|
<< "\n Fonction_externe_nD::Valeur_FnD_interne(..."<<endl;
|
|
// on génère une interruption ce qui permettra de dépiler les appels
|
|
this->Affiche();ErrCalculFct_nD toto;throw (toto);
|
|
Sortie(1);
|
|
};
|
|
};
|
|
}
|
|
catch(...)
|
|
{ cout << "\n ** erreur dans l'appel de la fonction "
|
|
<< nom_ref ;
|
|
cout << " verifier la presence des grandeurs globales voulues "
|
|
<< "\n Fonction_externe_nD::Valeur_FnD_interne(..."<<endl;
|
|
// on génère une interruption ce qui permettra de dépiler les appels
|
|
this->Affiche();ErrCalculFct_nD toto;throw (toto);
|
|
Sortie(1);
|
|
};
|
|
#endif
|
|
// on parcours les variables globales
|
|
int taille = nom_variables_globales.Taille();
|
|
for (int i=1;i<= taille;i++,i_fval++)
|
|
{// on récupère le pointeur correspondant à la grandeur
|
|
const void* pointe = (ParaGlob::param->GrandeurGlobal(nom_variables_globales(i)));
|
|
TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe);
|
|
switch(gr_quelc->Grandeur_pointee()->Type_structure_grandeurAssocie())
|
|
{ case TYPE_SIMPLE:
|
|
{ switch(gr_quelc->Grandeur_pointee()->Type_enumGrandeurParticuliere())
|
|
{case PARTICULIER_SCALAIRE_ENTIER:
|
|
{Grandeur_scalaire_entier& gr
|
|
= *((Grandeur_scalaire_entier*) gr_quelc->Grandeur_pointee()); // pour simplifier
|
|
tab_fVal(i_fval) = *(gr.ConteneurEntier());
|
|
break;
|
|
}
|
|
case PARTICULIER_SCALAIRE_DOUBLE:
|
|
{Grandeur_scalaire_double& gr
|
|
= *((Grandeur_scalaire_double*) gr_quelc->Grandeur_pointee()); // pour simplifier
|
|
tab_fVal(i_fval) = *(gr.ConteneurDouble());
|
|
break;
|
|
}
|
|
case PARTICULIER_DDL_ETENDU:
|
|
{Grandeur_Ddl_etendu& gr
|
|
= *((Grandeur_Ddl_etendu*) gr_quelc->Grandeur_pointee()); // pour simplifier
|
|
tab_fVal(i_fval) = (gr.GrandeurNumOrdre(1));
|
|
break;
|
|
}
|
|
case PARTICULIER_VECTEUR_NOMMER:
|
|
{Grandeur_Vecteur_Nommer& gr
|
|
= *((Grandeur_Vecteur_Nommer*) gr_quelc->Grandeur_pointee()); // pour simplifier
|
|
tab_fVal(i_fval) = (gr.GrandeurNumOrdre(1));
|
|
#ifdef MISE_AU_POINT
|
|
// on vérifie qu'une seule grandeur est stockée
|
|
if (gr.NbMaxiNumeroOrdre() > 1)
|
|
{ cout << "\n *** pb dans dans l'appel de la fonction "<< nom_ref
|
|
<< " la variable globale "<< nom_variables_globales(i)
|
|
<< ", correspond a un vecteur a plusieur composantes, ce n'est pas pris en "
|
|
<< " compte pour l'intant, on ne peut pas continuer "
|
|
<< "\n Fonction_externe_nD::Valeur_FnD_interne(..."
|
|
<<endl;
|
|
// on génère une interruption ce qui permettra de dépiler les appels
|
|
this->Affiche();ErrCalculFct_nD toto;throw (toto);
|
|
Sortie(1);
|
|
};
|
|
#endif
|
|
break;
|
|
}
|
|
default:
|
|
{ cout << "\n *** pb dans dans l'appel de la fonction "<< nom_ref
|
|
<< " la variable globale "<< nom_variables_globales(i)
|
|
<< ", n'est pas prise en compte actuellement , on ne peut pas continuer "
|
|
<< "\n Fonction_externe_nD::Valeur_FnD_interne(..."
|
|
<<endl;
|
|
// on génère une interruption ce qui permettra de dépiler les appels
|
|
this->Affiche();ErrCalculFct_nD toto;throw (toto);
|
|
Sortie(1);
|
|
};
|
|
}
|
|
|
|
break;
|
|
}
|
|
case TABLEAU_T: // valable uniquement pour les vecteur nommer
|
|
// dans ce cas on n'utilise pour l'instant que la première valeur
|
|
{ switch(gr_quelc->Grandeur_pointee()->Type_enumGrandeurParticuliere())
|
|
{ case PARTICULIER_VECTEUR_NOMMER:
|
|
{Grandeur_Vecteur_Nommer& gr
|
|
= *((Grandeur_Vecteur_Nommer*) gr_quelc->Grandeur_pointee()); // pour simplifier
|
|
tab_fVal(i_fval) = (gr.GrandeurNumOrdre(1));
|
|
#ifdef MISE_AU_POINT
|
|
// on vérifie qu'une seule grandeur est stockée
|
|
if (gr.NbMaxiNumeroOrdre() > 1)
|
|
{ cout << "\n *** pb dans dans l'appel de la fonction "<< nom_ref
|
|
<< " la variable globale "<< nom_variables_globales(i)
|
|
<< ", correspond a un vecteur a plusieur composantes, ce n'est pas pris en "
|
|
<< " compte pour l'intant, on ne peut pas continuer "
|
|
<< "\n grandeur= "<<gr<< " NbMaxiNumeroOrdre()= "<< gr.NbMaxiNumeroOrdre()
|
|
<< "\n Fonction_externe_nD::Valeur_FnD_interne(..."
|
|
<<endl;
|
|
// on génère une interruption ce qui permettra de dépiler les appels
|
|
this->Affiche();ErrCalculFct_nD toto;throw (toto);
|
|
Sortie(1);
|
|
};
|
|
#endif
|
|
break;
|
|
}
|
|
default:
|
|
{ cout << "\n *** pb dans dans l'appel de la fonction "<< nom_ref
|
|
<< " la variable globale "<< nom_variables_globales(i)
|
|
<< ", n'est pas prise en compte actuellement , on ne peut pas continuer "
|
|
<< "\n Fonction_externe_nD::Valeur_FnD_interne(..."
|
|
<<endl;
|
|
// on génère une interruption ce qui permettra de dépiler les appels
|
|
this->Affiche();ErrCalculFct_nD toto;throw (toto);
|
|
Sortie(1);
|
|
};
|
|
}
|
|
|
|
break;
|
|
}
|
|
default:
|
|
{ cout << "\n *** pb dans dans l'appel de la fonction "<< nom_ref
|
|
<< " la variable globale "<< nom_variables_globales(i)
|
|
<< ", n'est pas prise en compte actuellement , on ne peut pas continuer "
|
|
<< "\n Fonction_externe_nD::Valeur_FnD_interne(..."
|
|
<<endl;
|
|
// on génère une interruption ce qui permettra de dépiler les appels
|
|
this->Affiche();ErrCalculFct_nD toto;throw (toto);
|
|
Sortie(1);
|
|
};
|
|
};
|
|
};
|
|
};
|
|
*/
|
|
// on récupère les grandeurs globales
|
|
Fonction_nD::Recup_Grandeurs_globales();
|
|
// on affecte les grandeurs
|
|
int taille = x_glob.Taille();
|
|
for (int i=1;i<= taille;i++,i_fval++)
|
|
tab_fVal(i_fval) = x_glob(i);
|
|
|
|
// maintenant on appelle la fonction et on récupère les grandeurs
|
|
// 1) écriture des données sur le pipe
|
|
EcritureDonneesPipe();
|
|
// 2) lecture des données sur le pipe
|
|
LectureResultatsPipe();
|
|
|
|
#ifdef MISE_AU_POINT
|
|
// vérification d'une norme infinie
|
|
// if (permet_affichage > 0)
|
|
{int nNum = tab_ret.Taille();
|
|
double absret_Fi= 0.;
|
|
for (int i=0; i<nNum; ++i)
|
|
absret_Fi += Dabs(tab_ret(i+1));
|
|
if ((!isfinite(absret_Fi)) || (isnan(absret_Fi)) )
|
|
{ cout << "\n probleme dans le calcul de la fonction "
|
|
<< " on obtient en norme euclidienne: " << absret_Fi
|
|
<< "\n Fonction_externe_nD::Valeur_FnD_interne(...";
|
|
cout << "\n parametres d'appel: ";
|
|
int nb_var = tab_fVal.Taille();
|
|
for (int j=1;j<=nb_var;j++)
|
|
{ cout << " para("<<j<<")= "<< tab_fVal(j);}
|
|
cout <<"\n >>> arbre d'appel : fonction this : ";
|
|
this->Affiche(5);
|
|
cout << endl;
|
|
// on génère une interruption ce qui permettra de dépiler les appels
|
|
ErrCalculFct_nD toto;throw (toto);Sortie(1);
|
|
};
|
|
};
|
|
#endif
|
|
}
|
|
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 non determinee dans l'appel de la fonction "
|
|
<< nom_ref << " d'expression "
|
|
<< " \n xi= "<<xi ;
|
|
this->Affiche();
|
|
cout << "\n Fonction_externe_nD::Valeur_FnD_interne(...";
|
|
// on génère une interruption ce qui permettra de dépiler les appels
|
|
ErrCalculFct_nD toto;throw (toto);
|
|
Sortie(1);
|
|
};
|
|
return tab_ret;
|
|
};
|
|
|
|
|
|
// calcul des valeurs de la fonction, dans le cas où les variables
|
|
// sont toutes des grandeurs globales: pour l'instant que pour des variables scalaires
|
|
Tableau <double> & Fonction_externe_nD::Valeur_pour_variables_globales_interne()
|
|
{
|
|
|
|
/* // en debug on vérifie que les grandeurs globales sont présentent
|
|
#ifdef MISE_AU_POINT
|
|
try
|
|
{ // on vérifie tout d'abord que toutes les variables sont globales
|
|
if (nom_variables.Taille() != 0)
|
|
{ cout << "\n ** erreur dans l'appel de la fonction "
|
|
<< nom_ref ;
|
|
cout << " toutes les variables ne sont pas globales !! "
|
|
<< "\n Fonction_externe_nD::Valeur_pour_variables_globales_interne(..."<<endl;
|
|
this->Affiche();
|
|
// on génère une interruption ce qui permettra de dépiler les appels
|
|
ErrCalculFct_nD toto;throw (toto);
|
|
Sortie(1);
|
|
};
|
|
// maintenant on vérifie la présence des variables globales
|
|
int taille = enu_variables_globale.Taille();
|
|
for (int i=1;i<= taille;i++)
|
|
{// on récupère le pointeur correspondant à la grandeur
|
|
const void* pointe = (ParaGlob::param->GrandeurGlobal(enu_variables_globale(i)));
|
|
if (pointe == NULL)
|
|
{ cout << "\n *** pb dans Fonction_externe_nD " << nom_ref << " !! "
|
|
<< " la variable globale "<< Nom_GrandeurGlobale(enu_variables_globale(i))
|
|
<< ", n'est pas disponible, on ne peut pas continuer "
|
|
<< "\n Fonction_externe_nD::Valeur_pour_variables_globales_interne(..."<<endl;
|
|
this->Affiche();
|
|
// on génère une interruption ce qui permettra de dépiler les appels
|
|
ErrCalculFct_nD toto;throw (toto);
|
|
Sortie(1);
|
|
};
|
|
};
|
|
}
|
|
catch(...)
|
|
{ cout << "\n ** erreur dans l'appel de la fonction "
|
|
<< nom_ref ;
|
|
cout << " verifier la presence des grandeurs globales voulues "
|
|
<< "\n Fonction_externe_nD::Valeur_pour_variables_globales_interne(..."<<endl;
|
|
this->Affiche();
|
|
// on génère une interruption ce qui permettra de dépiler les appels
|
|
ErrCalculFct_nD toto;throw (toto);
|
|
Sortie(1);
|
|
};
|
|
#endif
|
|
// idem pour les grandeurs indicées avec des string
|
|
#ifdef MISE_AU_POINT
|
|
try
|
|
{ int tail_nom = nom_variables_globales.Taille();
|
|
for (int i=1;i<= tail_nom;i++)
|
|
{// on récupère le pointeur correspondant à la grandeur
|
|
const void* pointe = (ParaGlob::param->GrandeurGlobal(nom_variables_globales(i)));
|
|
if (pointe == NULL)
|
|
{ cout << "\n *** pb dans Fonction_externe_nD " << nom_ref << " !! "
|
|
<< " la variable globale "<< nom_variables_globales(i)
|
|
<< ", n'est pas disponible, on ne peut pas continuer "
|
|
<< "\n Fonction_externe_nD::Valeur_pour_variables_globales_interne(..."<<endl;
|
|
// on génère une interruption ce qui permettra de dépiler les appels
|
|
this->Affiche();ErrCalculFct_nD toto;throw (toto);
|
|
Sortie(1);
|
|
};
|
|
};
|
|
}
|
|
catch(...)
|
|
{ cout << "\n ** erreur dans l'appel de la fonction "
|
|
<< nom_ref ;
|
|
cout << " verifier la presence des grandeurs globales voulues "
|
|
<< "\n Fonction_externe_nD::Valeur_pour_variables_globales_interne(..."<<endl;
|
|
this->Affiche();
|
|
// on génère une interruption ce qui permettra de dépiler les appels
|
|
ErrCalculFct_nD toto;throw (toto);
|
|
Sortie(1);
|
|
};
|
|
#endif
|
|
*/
|
|
// arrivée ici toutes les grandeurs existent
|
|
try
|
|
{
|
|
/* // on parcours les variables globales
|
|
int i_fval=1; // indice pour se déplacer dans plusieurs boucles
|
|
int taille = enu_variables_globale.Taille();
|
|
for (int i=1;i<= taille;i++,i_fval++)
|
|
{// on récupère le pointeur correspondant à la grandeur
|
|
const void* pointe = (ParaGlob::param->GrandeurGlobal(enu_variables_globale(i)));
|
|
TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe);
|
|
switch(gr_quelc->Grandeur_pointee()->Type_structure_grandeurAssocie())
|
|
{ case TYPE_SIMPLE:
|
|
{ switch(gr_quelc->Grandeur_pointee()->Type_enumGrandeurParticuliere())
|
|
{case PARTICULIER_SCALAIRE_ENTIER:
|
|
{Grandeur_scalaire_entier& gr
|
|
= *((Grandeur_scalaire_entier*) gr_quelc->Grandeur_pointee()); // pour simplifier
|
|
tab_fVal(i_fval) = *(gr.ConteneurEntier());
|
|
break;
|
|
}
|
|
case PARTICULIER_SCALAIRE_DOUBLE:
|
|
{Grandeur_scalaire_double& gr
|
|
= *((Grandeur_scalaire_double*) gr_quelc->Grandeur_pointee()); // pour simplifier
|
|
tab_fVal(i_fval) = *(gr.ConteneurDouble());
|
|
break;
|
|
}
|
|
case PARTICULIER_DDL_ETENDU:
|
|
{Grandeur_Ddl_etendu& gr
|
|
= *((Grandeur_Ddl_etendu*) gr_quelc->Grandeur_pointee()); // pour simplifier
|
|
tab_fVal(i_fval) = (gr.GrandeurNumOrdre(1));
|
|
break;
|
|
}
|
|
default:
|
|
{ cout << "\n *** pb dans dans l'appel de la fonction "<< nom_ref
|
|
<< " la variable globale "<< Nom_GrandeurGlobale(enu_variables_globale(i))
|
|
<< ", n'est pas prise en compte actuellement , on ne peut pas continuer "
|
|
<< "\n Fonction_externe_nD::Valeur_pour_variables_globales_interne(..."
|
|
<<endl;
|
|
// on génère une interruption ce qui permettra de dépiler les appels
|
|
this->Affiche();ErrCalculFct_nD toto;throw (toto);
|
|
Sortie(1);
|
|
};
|
|
}
|
|
|
|
break;
|
|
}
|
|
default:
|
|
{ cout << "\n *** pb dans dans l'appel de la fonction "<< nom_ref
|
|
<< " la variable globale "<< Nom_GrandeurGlobale(enu_variables_globale(i))
|
|
<< ", n'est pas prise en compte actuellement , on ne peut pas continuer "
|
|
<< "\n Fonction_externe_nD::Valeur_pour_variables_globales_interne(..."
|
|
<<endl;
|
|
// on génère une interruption ce qui permettra de dépiler les appels
|
|
this->Affiche();ErrCalculFct_nD toto;throw (toto);
|
|
Sortie(1);
|
|
};
|
|
};
|
|
};
|
|
// idem mais typées sous forme de string
|
|
{// on parcours les variables globales
|
|
int taille = nom_variables_globales.Taille();
|
|
for (int i=1;i<= taille;i++,i_fval++)
|
|
{// on récupère le pointeur correspondant à la grandeur
|
|
const void* pointe = (ParaGlob::param->GrandeurGlobal(nom_variables_globales(i)));
|
|
TypeQuelconque* gr_quelc = (TypeQuelconque*) (pointe);
|
|
switch(gr_quelc->Grandeur_pointee()->Type_structure_grandeurAssocie())
|
|
{ case TYPE_SIMPLE:
|
|
{ switch(gr_quelc->Grandeur_pointee()->Type_enumGrandeurParticuliere())
|
|
{case PARTICULIER_SCALAIRE_ENTIER:
|
|
{Grandeur_scalaire_entier& gr
|
|
= *((Grandeur_scalaire_entier*) gr_quelc->Grandeur_pointee()); // pour simplifier
|
|
tab_fVal(i_fval) = *(gr.ConteneurEntier());
|
|
break;
|
|
}
|
|
case PARTICULIER_SCALAIRE_DOUBLE:
|
|
{Grandeur_scalaire_double& gr
|
|
= *((Grandeur_scalaire_double*) gr_quelc->Grandeur_pointee()); // pour simplifier
|
|
tab_fVal(i_fval) = *(gr.ConteneurDouble());
|
|
break;
|
|
}
|
|
case PARTICULIER_DDL_ETENDU:
|
|
{Grandeur_Ddl_etendu& gr
|
|
= *((Grandeur_Ddl_etendu*) gr_quelc->Grandeur_pointee()); // pour simplifier
|
|
tab_fVal(i_fval) = (gr.GrandeurNumOrdre(1));
|
|
break;
|
|
}
|
|
case PARTICULIER_VECTEUR_NOMMER:
|
|
{Grandeur_Vecteur_Nommer& gr
|
|
= *((Grandeur_Vecteur_Nommer*) gr_quelc->Grandeur_pointee()); // pour simplifier
|
|
tab_fVal(i_fval) = (gr.GrandeurNumOrdre(1));
|
|
#ifdef MISE_AU_POINT
|
|
// on vérifie qu'une seule grandeur est stockée
|
|
if (gr.NbMaxiNumeroOrdre() > 1)
|
|
{ cout << "\n *** pb dans dans l'appel de la fonction "<< nom_ref
|
|
<< " la variable globale "<< nom_variables_globales(i)
|
|
<< ", correspond a un vecteur a plusieur composantes, ce n'est pas pris en "
|
|
<< " compte pour l'intant, on ne peut pas continuer "
|
|
<< "\n Fonction_externe_nD::Valeur_pour_variables_globales_interne(..."
|
|
<<endl;
|
|
// on génère une interruption ce qui permettra de dépiler les appels
|
|
this->Affiche();ErrCalculFct_nD toto;throw (toto);
|
|
Sortie(1);
|
|
};
|
|
#endif
|
|
break;
|
|
}
|
|
default:
|
|
{ cout << "\n *** pb dans dans l'appel de la fonction "<< nom_ref
|
|
<< " la variable globale "<< nom_variables_globales(i)
|
|
<< ", n'est pas prise en compte actuellement , on ne peut pas continuer "
|
|
<< "\n Fonction_externe_nD::Valeur_pour_variables_globales(..."
|
|
<<endl;
|
|
// on génère une interruption ce qui permettra de dépiler les appels
|
|
this->Affiche();ErrCalculFct_nD toto;throw (toto);
|
|
Sortie(1);
|
|
};
|
|
}
|
|
|
|
break;
|
|
}
|
|
case TABLEAU_T: // valable uniquement pour les vecteur nommer
|
|
// dans ce cas on n'utilise pour l'instant que la première valeur
|
|
{ switch(gr_quelc->Grandeur_pointee()->Type_enumGrandeurParticuliere())
|
|
{ case PARTICULIER_VECTEUR_NOMMER:
|
|
{Grandeur_Vecteur_Nommer& gr
|
|
= *((Grandeur_Vecteur_Nommer*) gr_quelc->Grandeur_pointee()); // pour simplifier
|
|
tab_fVal(i_fval) = (gr.GrandeurNumOrdre(1));
|
|
#ifdef MISE_AU_POINT
|
|
// on vérifie qu'une seule grandeur est stockée
|
|
if (gr.NbMaxiNumeroOrdre() > 1)
|
|
{ cout << "\n *** pb dans dans l'appel de la fonction "<< nom_ref
|
|
<< " la variable globale "<< nom_variables_globales(i)
|
|
<< ", correspond a un vecteur a plusieur composantes, ce n'est pas pris en "
|
|
<< " compte pour l'intant, on ne peut pas continuer "
|
|
<< "\n grandeur= "<<gr<< " NbMaxiNumeroOrdre()= "<< gr.NbMaxiNumeroOrdre()
|
|
<< "\n Fonction_externe_nD::Valeur_pour_variables_globales_interne(..."
|
|
<<endl;
|
|
// on génère une interruption ce qui permettra de dépiler les appels
|
|
this->Affiche();ErrCalculFct_nD toto;throw (toto);
|
|
Sortie(1);
|
|
};
|
|
#endif
|
|
break;
|
|
}
|
|
default:
|
|
{ cout << "\n *** pb dans dans l'appel de la fonction "<< nom_ref
|
|
<< " la variable globale "<< nom_variables_globales(i)
|
|
<< ", n'est pas prise en compte actuellement , on ne peut pas continuer "
|
|
<< "\n Fonction_externe_nD::Valeur_pour_variables_globales_interne(..."
|
|
<<endl;
|
|
// on génère une interruption ce qui permettra de dépiler les appels
|
|
this->Affiche();ErrCalculFct_nD toto;throw (toto);
|
|
Sortie(1);
|
|
};
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
default:
|
|
{ cout << "\n *** pb dans dans l'appel de la fonction "<< nom_ref
|
|
<< " la variable globale "<< nom_variables_globales(i)
|
|
<< ", n'est pas prise en compte actuellement , on ne peut pas continuer "
|
|
<< "\n Fonction_externe_nD::Valeur_pour_variables_globales_interne(..."
|
|
<<endl;
|
|
// on génère une interruption ce qui permettra de dépiler les appels
|
|
this->Affiche();ErrCalculFct_nD toto;throw (toto);
|
|
Sortie(1);
|
|
};
|
|
};
|
|
};
|
|
};
|
|
*/
|
|
// on récupère les grandeurs globales
|
|
Fonction_nD::Recup_Grandeurs_globales();
|
|
// on affecte les grandeurs
|
|
int taille_x_glob = x_glob.Taille();
|
|
for (int i=1;i<= taille_x_glob;i++)
|
|
tab_fVal(i) = x_glob(i);
|
|
|
|
// maintenant on appelle la fonction et on récupère les grandeurs
|
|
// 1) écriture des données sur le pipe
|
|
EcritureDonneesPipe();
|
|
// 2) lecture des données sur le pipe
|
|
LectureResultatsPipe();
|
|
|
|
#ifdef MISE_AU_POINT
|
|
// vérification d'une norme infinie
|
|
// if (permet_affichage > 0)
|
|
{int nNum = tab_ret.Taille();
|
|
double absret_Fi= 0.;
|
|
for (int i=0; i<nNum; ++i)
|
|
absret_Fi += Dabs(tab_ret(i+1));
|
|
if ((!isfinite(absret_Fi)) || (isnan(absret_Fi)) )
|
|
{ cout << "\n probleme dans le calcul de la fonction "
|
|
<< " on obtient en norme euclidienne: " << absret_Fi
|
|
<< "\n Fonction_externe_nD::Valeur_pour_variables_globales_interne(...";
|
|
cout << "\n parametres d'appel: ";
|
|
int nb_var = tab_fVal.Taille();
|
|
for (int j=1;j<=nb_var;j++)
|
|
{ cout << " para("<<j<<")= "<< tab_fVal(j);}
|
|
cout <<"\n >>> arbre d'appel : fonction this : ";
|
|
this->Affiche(5);
|
|
cout << endl;
|
|
// on génère une interruption ce qui permettra de dépiler les appels
|
|
this->Affiche(5);ErrCalculFct_nD toto;throw (toto);Sortie(1);
|
|
};
|
|
};
|
|
#endif
|
|
}
|
|
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 non determinee dans l'appel de la fonction "
|
|
<< nom_ref
|
|
<< "\n Fonction_externe_nD::Valeur_pour_variables_globales_interne(...";
|
|
// // on génère une interruption ce qui permettra de dépiler les appels
|
|
this->Affiche();ErrCalculFct_nD toto;throw (toto);
|
|
Sortie(1);
|
|
};
|
|
return tab_ret;
|
|
};
|
|
|
|
//----- lecture écriture de restart -----
|
|
// cas donne le niveau de la récupération
|
|
// = 1 : on récupère tout
|
|
// = 2 : on récupère uniquement les données variables (supposées comme telles)
|
|
void Fonction_externe_nD::Lecture_base_info(ifstream& ent,const int cas)
|
|
{ // on n'a que des grandeurs constantes
|
|
if (cas == 1)
|
|
{ string nom;
|
|
// lecture et vérification de l'entête
|
|
ent >> nom;
|
|
if (nom != "Fonction_externe_nD")
|
|
{ cout << "\n erreur dans la vérification du type de courbe lue ";
|
|
cout << "\n Fonction_externe_nD::Lecture_base_info(... ";
|
|
Sortie(1);
|
|
}
|
|
// lecture des infos
|
|
|
|
// les arguments gérés par la classe mère
|
|
Fonction_nD::Lect_base_info(ent,cas);
|
|
|
|
// retour des valeurs
|
|
string toto;
|
|
ent >> toto ;
|
|
if (toto != "taille_vecteur_de_retour:")
|
|
{cout << "\n erreur en lecture sur base info du nombre de grandeur en retour de fonction externe "
|
|
<< " on a lu : " << toto
|
|
<< " alors que l'on attendait: taille_vecteur_de_retour:"
|
|
<< "\n Fonction_externe_nD::Lecture_base_info(..."
|
|
<< endl;
|
|
Sortie(1);
|
|
};
|
|
// cas où c'est ok
|
|
int nb_double_ret;
|
|
ent >> nb_double_ret;
|
|
tab_ret.Change_taille(nb_double_ret);
|
|
|
|
// on définit le paramètre depend_M de la classe maître en fonction des nom_variables
|
|
Fonction_nD::Definition_depend_M();
|
|
// idem pour le temps
|
|
Fonction_nD::Definition_depend_temps();
|
|
// idem pour la cohérence avec les enu
|
|
// Fonction_nD::Construction_enu_etendu_et_quelconque();
|
|
// Contruction des index pour les grandeurs évoluées, ainsi que les conteneurs
|
|
Fonction_nD::Construction_index_conteneurs_evoluees();
|
|
// initialisation des pipes au cas où
|
|
Fonction_externe_nD::InitialisationPipesNommes();
|
|
}
|
|
};
|
|
|
|
// cas donne le niveau de sauvegarde
|
|
// = 1 : on sauvegarde tout
|
|
// = 2 : on sauvegarde uniquement les données variables (supposées comme telles)
|
|
void Fonction_externe_nD::Ecriture_base_info(ofstream& sort,const int cas)
|
|
{ // on n'a que des grandeurs constantes
|
|
if (cas == 1)
|
|
{ sort << "\n <FONCTION_EXTERNE_ND> ";
|
|
sort << " Fonction_externe_nD ";
|
|
// les arguments gérés par la classe mère
|
|
Fonction_nD::Ecrit_base_info(sort,cas);
|
|
// retour des valeurs
|
|
sort << "\n taille_vecteur_de_retour: "<< this->NbComposante()
|
|
<< " ";
|
|
sort << "\n </FONCTION_EXTERNE_ND> \n";
|
|
};
|
|
};
|
|
|
|
// sortie du schemaXML: en fonction de enu
|
|
void Fonction_externe_nD::SchemaXML_Fonctions_nD(ofstream& ,const Enum_IO_XML enu)
|
|
{
|
|
switch (enu)
|
|
{ case XML_TYPE_GLOBAUX :
|
|
{
|
|
break;
|
|
}
|
|
case XML_IO_POINT_INFO :
|
|
{
|
|
break;
|
|
}
|
|
case XML_IO_POINT_BI :
|
|
{
|
|
break;
|
|
}
|
|
case XML_IO_ELEMENT_FINI :
|
|
{
|
|
break;
|
|
}
|
|
};
|
|
};
|
|
|
|
|
|
// initialisation des pipes
|
|
void Fonction_externe_nD::InitialisationPipesNommes()
|
|
{
|
|
try
|
|
{ // pipe de sortie
|
|
// on test l'existence du pipe
|
|
struct stat buf;
|
|
int tub=0; // init
|
|
int etat = stat(envoi.c_str(), &buf);
|
|
|
|
int tube_a_cree = 0;
|
|
if (etat == -1) // cela veut dire que la fonction stat n'a pas fonctionné
|
|
// on part sur le principe que les tubes n'existent pas
|
|
{tube_a_cree=1;}
|
|
else if (!S_ISFIFO(buf.st_mode))
|
|
{tube_a_cree=1;};
|
|
if (tube_a_cree ) // cas où le tube n'existe pas
|
|
{tub = mkfifo (envoi.c_str(), S_IRWXU);
|
|
if (tub == -1 ) // gestion d'erreur éventuelle
|
|
{cout << "\n *** erreur en creation du tube nomme: " << envoi << ", de sortie d'herezh pour la "
|
|
<< " fonction externe "<< nom_ref
|
|
<< "\n Fonction_externe_nD::InitialisationPipesNommes() "<<flush;
|
|
Sortie(1);
|
|
}
|
|
else if ((ParaGlob::NiveauImpression() > 3) || (permet_affichage > 0 ))
|
|
{ cout << "\n creation du pipe nomme: "<< envoi << " pour la "
|
|
<< " fonction externe "<< nom_ref << flush;
|
|
// partie affichage du nom des variables
|
|
if (permet_affichage > 5)
|
|
{ cout << "\n ---- Fonction_externe_nD " << nom_ref ;
|
|
cout << " \n arguments= " << nom_variables
|
|
<< " \n variables_globales_en_enumere= " ;
|
|
int nb_enu = enu_variables_globale.Taille();
|
|
cout << "taille " << nb_enu << " ";
|
|
for (int i=1;i<= nb_enu;i++)
|
|
cout << Nom_GrandeurGlobale(enu_variables_globale(i)) << " ";
|
|
|
|
cout << " \n variables_globales_en_string= " ;
|
|
int nb_str = nom_variables_globales.Taille();
|
|
cout << "taille " << nb_str << " ";
|
|
for (int i=1;i<= nb_str;i++)
|
|
cout << nom_variables_globales(i) << " ";
|
|
};
|
|
} ;
|
|
close (tub); // fermeture du tampon
|
|
}
|
|
else if ((ParaGlob::NiveauImpression() > 3) || (permet_affichage > 0 ))
|
|
{ cout << "\n utilisation du pipe nomme: "<< reception << " pour la "
|
|
<< " fonction externe "<< nom_ref << flush;
|
|
// partie affichage du nom des variables
|
|
if (permet_affichage > 5)
|
|
{ cout << "\n ---- Fonction_externe_nD " << nom_ref ;
|
|
cout << " \n arguments= " << nom_variables
|
|
<< " \n variables_globales_en_enumere= " ;
|
|
int nb_enu = enu_variables_globale.Taille();
|
|
cout << "taille " << nb_enu << " ";
|
|
for (int i=1;i<= nb_enu;i++)
|
|
cout << Nom_GrandeurGlobale(enu_variables_globale(i)) << " ";
|
|
|
|
cout << " \n variables_globales_en_string= " ;
|
|
int nb_str = nom_variables_globales.Taille();
|
|
cout << "taille " << nb_str << " ";
|
|
for (int i=1;i<= nb_str;i++)
|
|
cout << nom_variables_globales(i) << " ";
|
|
};
|
|
} ;
|
|
tub = 0; // réinit
|
|
tube_a_cree = 0; // réinit
|
|
|
|
// ouverture du tube nommé en lecture
|
|
etat = stat(reception.c_str(), &buf);
|
|
if (etat == -1) // cela veut dire que la fonction stat n'a pas fonctionné
|
|
// on part sur le principe que les tubes n'existent pas
|
|
{tube_a_cree=1;}
|
|
else if (!S_ISFIFO(buf.st_mode))
|
|
{tube_a_cree=1;};
|
|
if (tube_a_cree ) // cas où le tube n'existe pas
|
|
{tub = mkfifo (reception.c_str(), S_IRWXU);
|
|
if (tub == -1 ) // gestion d'erreur éventuelle
|
|
{cout << "\n *** erreur en creation du tobe nomme: " << reception << ", de lecture d'herezh pour la "
|
|
<< " fonction externe "<< nom_ref
|
|
<< "\n Fonction_externe_nD::InitialisationPipesNommes() "<<flush;
|
|
Sortie(1);
|
|
}
|
|
else if ((ParaGlob::NiveauImpression() > 3) || (permet_affichage > 0 ))
|
|
{ cout << "\n creation du pipe nomme: "<< reception << " pour la "
|
|
<< " fonction externe "<< nom_ref << flush;
|
|
} ;
|
|
close (tub); // fermeture du tampon
|
|
}
|
|
else if ((ParaGlob::NiveauImpression() > 3) || (permet_affichage > 0 ))
|
|
{ cout << "\n utilisation du pipe nomme: "<< reception << " pour la "
|
|
<< " fonction externe "<< nom_ref << flush;
|
|
} ;
|
|
|
|
|
|
}
|
|
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 lors de l'initialisation des pipes I/O pour la "
|
|
<< " fonction externe "<< nom_ref
|
|
<< "\n Fonction_externe_nD::InitialisationPipesNommes() "<<flush;
|
|
Sortie(1);
|
|
};
|
|
|
|
};
|
|
|
|
|
|
// lecture des données
|
|
void Fonction_externe_nD::LectureResultatsPipe()
|
|
{
|
|
try
|
|
{// Creation d'un processus de reception des données
|
|
// en fait l'objectif est de réceptionner que les variables d'entrées ou
|
|
// d'entrée sortie
|
|
if (permet_affichage > 5)
|
|
cout << "\n hzpp: ouverture du tube en lecture, lecture sur le tube: "
|
|
<< reception << endl;
|
|
|
|
|
|
// union Tab_car_double_int_1
|
|
// { char tampon[928];
|
|
// double x[116];
|
|
// int n[232];
|
|
// } ;
|
|
// Tab_car_double_int_1 t_car_x_n; // tableau de caractères, réels et entiers
|
|
// Tableau <double> tab_fVal; // les variables internes dont le nombre doit être
|
|
// // égal à celui du tableau nom_variables + les enum globaux + les noms globaux
|
|
// Tableau <double> tab_ret; // le tableau de retour
|
|
|
|
// le premier élément est le nombre de grandeurs à écrire (et donc à lire du coté externe)
|
|
// le second élément est le nombre de grandeurs que l'on attend en retour
|
|
t_car_x_n.n[1] = tab_ret.Taille();
|
|
|
|
char* tampon = &(t_car_x_n.tampon[0]);
|
|
int nb_carac_a_lire = t_car_x_n.n[1] * 8 + 2*4 ;
|
|
|
|
int tub = open(reception.c_str(),O_RDONLY);
|
|
read (tub,tampon,nb_carac_a_lire);
|
|
close (tub); // fermeture du tampon
|
|
|
|
// on récupère les informations du tampon
|
|
int nb_doublePlusUn = tab_ret.Taille() +1;
|
|
for (int i=1;i<nb_doublePlusUn;i++)
|
|
// tab_fVal(i) = tab_ret(i) = t_car_x_n.x[i] ;
|
|
tab_ret(i) = t_car_x_n.x[i] ;
|
|
if (permet_affichage >2 )
|
|
{cout << "\n lecture de " << t_car_x_n.n[1] << " reels ";
|
|
if (permet_affichage > 3)
|
|
{for (int i=1;i <= t_car_x_n.n[1]; i++)
|
|
cout << "\n resultat "<< i<< "= " << t_car_x_n.x[i];
|
|
};
|
|
|
|
cout << "\n HZpp: fermeture du tube en lecture: "
|
|
<< reception << endl;
|
|
};
|
|
}
|
|
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 en lecture des resultats de la fonction externe "
|
|
<< nom_ref ;
|
|
Affiche(permet_affichage);
|
|
cout << flush;
|
|
Sortie(1);
|
|
};
|
|
// à chaque lecture on incrémente un compteur
|
|
passage++; // pour des comptes éventuelles
|
|
};
|
|
|
|
// écriture des variables de passage
|
|
void Fonction_externe_nD::EcritureDonneesPipe()
|
|
{try
|
|
{// Creation d'un processus d'ecriture des variables
|
|
// en fait l'objectif est d'ecrire que les variables qui évoluent
|
|
if (permet_affichage > 5)
|
|
cout << "\n hzpp: ouverture du tube en ecriture, ecriture sur le tube: "
|
|
<< envoi << endl;
|
|
|
|
// union Tab_car_double_int_1
|
|
// { char tampon[928];
|
|
// double x[116];
|
|
// int n[232];
|
|
// } ;
|
|
// Tab_car_double_int_1 t_car_x_n; // tableau de caractères, réels et entiers
|
|
// Tableau <double> tab_fVal; // les variables internes dont le nombre doit être
|
|
// // égal à celui du tableau nom_variables + les enum globaux + les noms globaux
|
|
// Tableau <double> tab_ret; // le tableau de retour
|
|
|
|
// le premier élément est le nombre de réel à écrire (et donc à lire du coté externe)
|
|
t_car_x_n.n[0]=tab_fVal.Taille();
|
|
int nb_doublePlusUn = t_car_x_n.n[0]+1;
|
|
// le second élément est le nombre de grandeurs que l'on attend en retour
|
|
t_car_x_n.n[1] = tab_ret.Taille();
|
|
// après on transfert dans le tampon
|
|
for (int i=1;i<nb_doublePlusUn;i++)
|
|
t_car_x_n.x[i] = tab_fVal(i);
|
|
// ouverture du tube nomme en ecriture
|
|
int tub = open(envoi.c_str(),O_WRONLY);
|
|
int nb_carac_a_ecrire = t_car_x_n.n[0] * 8 + 2*4 ;
|
|
write (tub,t_car_x_n.tampon,nb_carac_a_ecrire);
|
|
close (tub); // fermeture du tampon
|
|
|
|
if (permet_affichage > 2)
|
|
{cout << "\n ecriture de " << t_car_x_n.n[0] << " reels ";
|
|
if (permet_affichage > 3)
|
|
{for (int i=1;i <= t_car_x_n.n[0]; i++)
|
|
cout << "\n variable "<< i<< "= " << t_car_x_n.x[i];
|
|
};
|
|
if (permet_affichage > 7)
|
|
cout << "\n HZpp: fermeture du tube en ecriture: "
|
|
<< envoi << endl;
|
|
};
|
|
}
|
|
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 en ecriture des parametre de la fonction externe "
|
|
<< nom_ref ;
|
|
Affiche(permet_affichage);
|
|
cout << flush;
|
|
Sortie(1);
|
|
};
|
|
};
|
|
|