TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
Synonyme_info.cpp
1/****************************************************************************
2* Copyright (c) 2023, CEA
3* All rights reserved.
4*
5* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
9*
10* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
11* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
12* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13*
14*****************************************************************************/
15
16#include <Synonyme_info.h>
17#include <Noms.h>
18
19// B.Mathieu, 08/2004
20// Le processus d'initialisation de ces membres statiques est tres
21// important : il faut absolument qu'ils soient initialises AVANT
22// le premier appel au constructeur Synonyme_info::Synonyme_info(...).
23// Or ce constructeur est appele pour initialiser le membre statique info_obj
24// de tous les Objet_U.
25// Risque de "static initialization order fiasco"
26// (voir http://www.parashift.com/c++-faq-lite/ctors.html [10.11])
27// Pour l'instant c'est ok parce qu'on initialise avec une constante...
28
29// Tableau de pointeurs sur les synonymes enregistres lors de la construction
30// des Synonyme_info. Si plusieurs synonymes on le meme nom (Synonyme_info::n), alors
31// on n'en enregistre qu'un seul dans Synonyme_info::les_synonymes.
32const Synonyme_info** Synonyme_info::les_synonymes=0;
33// Pour chaque elements du tableau "les_synonymes", ce nombre vaut 1 si le
34// nom du synonyme est commun a plusieurs synonymes, 0 sinon.
35// Voir "ajouter_synonyme"
36
37int Synonyme_info::nb_classes=0;
38int Synonyme_info::les_synonymes_memsize=0;
39
40
41// [ABN] I don't dare replacing this with STL for efficiency purpose - here we convert only what's needed for comparison
42static inline int strcmp_uppercase(const char *n1, const char *n2)
43{
44 int i = 0;
45 unsigned char c1, c2;
46 int delta;
47 do
48 {
49 c1 = (unsigned char) ::toupper(n1[i]);
50 c2 = (unsigned char) ::toupper(n2[i]);
51 delta = c1 - c2;
52 i++;
53 }
54 while ((delta == 0) && (c1 != 0) && (c2 != 0));
55 return delta;
56}
57
58// GF pour liberer correctement la memoire il faut au moins detruire le nom
60{
61 retirer_synonyme(nom());
62 if ((nb_classes==0) && (les_synonymes_memsize!=0))
63 {
64 delete [] les_synonymes;
65 les_synonymes_memsize=0;
66 }
67}
68
69/*! @brief Recherche le synonyme de nom "nom" dans la liste de synonymes enregistres par une recherche binaire.
70 *
71 * On compare les chaines converties en majuscules.
72 * On range dans "index" l'indice du synonyme, s'il a ete trouve
73 * et sinon l'indice du synonyme juste apres (dans ce cas, on a
74 * les_synonymes[index-1]->n < nom < les_synonymes[index]->n )
75 * Si le synonyme a ete trouve on renvoie 1, sinon 0.
76 *
77 */
78int Synonyme_info::search_synonyme_info_name(const char *nom, int& index)
79{
80 assert(nom != 0);
81 // [imin..imax] est l'intervalle ou se trouve l'index recherche
82 int imin = 0;
83 int imax = nb_classes;
84 while (imax > imin)
85 {
86 // On a toujours milieu < imax
87 int milieu = (imin + imax) / 2;
88 int comparaison = strcmp_uppercase(nom, les_synonymes[milieu]->n);
89 if (comparaison == 0)
90 {
91 index = milieu;
92 return 1;
93 }
94 if (comparaison < 0)
95 {
96 // nom < les_synonymes[milieu]
97 // l'index recherche est donc inferieur ou egal a "milieu"
98 imax = milieu;
99 }
100 else
101 {
102 // nom > les_synonymes[milieu]
103 // l'index recherche est donc strictement superieur a "milieu"
104 imin = milieu + 1;
105 }
106 }
107 index = imax;
108 return 0;
109}
110/*! @brief Constructeur par un nom, un tableau de meres.
111 *
112 * @param (const char* nom) le nom du synonyme a creer
113 * @param (int nb_base) le nombre de meres dans le tableau bases[]
114 * @param (const Synonyme_info* bases[]) le tableau specifiant les synonymes de bases (meres) du synonyme a creer
115 * @throws Sort en erreur si le nom n'est pas defini (null)
116 */
117Synonyme_info::Synonyme_info(const char* un_nom, const char* org_name) :
118 n(un_nom),org(org_name)
119{
120 if((un_nom == 0)||(org_name==0))
121 {
122 Cerr << "Synonyme_info::Synonyme_info(const char* nom,Objet_U* (*f)()...)\n";
123 Cerr << " Error : nom==0" << finl;
124 assert(0);
126 }
127 ajouter_synonyme(*this);
128}
129
130/*! @brief Methode statique appelee par les constructeurs de Synonyme_info pour ajouter un nouveau synonyme a la liste des synonymes enregistres.
131 *
132 * Verifie que le nom du synonyme n'existe pas encore.
133 *
134 */
135void Synonyme_info::retirer_synonyme(const char* nom)
136{
137 // On cherche ou mettre le synonyme dans le tableau :
138 int index;
139 int existe_deja = search_synonyme_info_name(nom, index);
140 if (!existe_deja)
141 {
142 Cerr<<"A synonym is suppressed whereas it doesn't exist !!!!!"<<finl;
144 }
145 else
146 {
147 // Ajout du synonyme dans le tableau a l'indice "index":
148 for (int i = index; i < nb_classes-1; i++)
149 les_synonymes[i] = les_synonymes[i+1];
150 nb_classes--;
151 }
152}
153
154/*! @brief Methode statique appelee par les constructeurs de Synonyme_info pour ajouter un nouveau synonyme a la liste des synonymes enregistres.
155 *
156 * Verifie que le nom du synonyme n'existe pas encore.
157 *
158 */
160{
161 // Verifie qu'il y a assez de place dans le tableau :
162 if (les_synonymes_memsize <= nb_classes + 1)
163 {
164 static const int INCREMENT = 512;
165 // Plus assez de place dans le tableau: on redimensionne.
166 les_synonymes_memsize += INCREMENT;
167 const Synonyme_info** nouveau = new const Synonyme_info*[les_synonymes_memsize];
168 for (int i = 0; i < nb_classes; i++)
169 nouveau[i] = les_synonymes[i];
170 delete[] les_synonymes;
171 les_synonymes = nouveau;
172 }
173
174 // On cherche ou mettre le synonyme dans le tableau :
175 int index;
176 int existe_deja=Type_info::est_un_type(synonyme_info.n);
177 if (existe_deja)
178 {
179 Cerr<<" The synonym "<<synonyme_info.n<<" exists as a class which is forbidden !!!!"<<finl;
181 }
182 existe_deja = search_synonyme_info_name(synonyme_info.n, index);
183 if (existe_deja)
184 {
185 Cerr<<" Synonym "<<synonyme_info.n<<" already exists, which is forbidden!!!!"<<finl;
187 }
188 else
189 {
190 // Ajout du synonyme dans le tableau a l'indice "index":
191 for (int i = nb_classes; i > index; i--)
192 les_synonymes[i] = les_synonymes[i-1];
193 les_synonymes[index] = &synonyme_info;
194
195 nb_classes++;
196 }
197}
198
199/*! @brief Ecriture de toute la hierarchie du synonyme considere sur un flux de sortie
200 *
201 * @param (Sortie& os) flot de sortie
202 * @return (Sortie&) le flot de sortie modifie
203 */
205{
206 os << "There is " << nb_classes << " synomyms:" << finl;
207 int i= nb_classes;
208 while(i--)
209 os << les_synonymes[i]->nom() << " <=> "<< les_synonymes[i]->org_name_()<<finl;
210 return os << finl<<flush;
211}
212
213/*! @brief Test d'existence d'une classe du synonyme indique si il existe une classe T dont le Synonyme_info a
214 *
215 * le nom nom, alors est_un_synonyme renvoie 1
216 * renvoie le pointeur nul sinon.
217 *
218 * @param (const char* nom) chaine de caractere associee a un synonyme
219 * @return (int) code de retour (0 ou 1)
220 */
222{
223 const Synonyme_info * synonyme = synonyme_info_from_name(nom);
224 return (synonyme != 0);
225}
226
227/*! @brief Methode statique qui renvoie un pointeur vers le Synonyme_info dont le nom est "synonyme_name".
228 *
229 * Si synonyme_name n'est pas un synonyme,
230 * renvoie un pointeur nul.
231 *
232 */
233const Synonyme_info * Synonyme_info::synonyme_info_from_name(const char * synonyme_name)
234{
235 const Synonyme_info * synonyme_info = 0;
236 if (synonyme_name != 0)
237 {
238 int index;
239 if (search_synonyme_info_name(synonyme_name, index))
240 synonyme_info = les_synonymes[index];
241 }
242 return synonyme_info;
243}
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
Classe de base des flux de sortie.
Definition Sortie.h:52
modelise une information de synonyme pour les Objet_U
const char * nom() const
static const Synonyme_info * synonyme_info_from_name(const char *synonyme_name)
Methode statique qui renvoie un pointeur vers le Synonyme_info dont le nom est "synonyme_name".
static void ajouter_synonyme(const Synonyme_info &synonyme_info)
Methode statique appelee par les constructeurs de Synonyme_info pour ajouter un nouveau synonyme a la...
static int est_un_synonyme(const char *)
Test d'existence d'une classe du synonyme indique si il existe une classe T dont le Synonyme_info a.
static Sortie & hierarchie(Sortie &)
Ecriture de toute la hierarchie du synonyme considere sur un flux de sortie.
static int est_un_type(const char *)
Test d'existence d'une classe du type indique si il existe une classe T dont le Type_info a.