TrioCFD 1.9.9_beta
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// The initialization process of these static members is very
21// important: they absolutely must be initialized BEFORE
22// the first call to the constructor Synonyme_info::Synonyme_info(...).
23// This constructor is called to initialize the static member info_obj
24// of all Objet_U objects.
25// Risk of "static initialization order fiasco"
26// (see http://www.parashift.com/c++-faq-lite/ctors.html [10.11])
27// For now it is ok because we initialize with a constant...
28
29// Array of pointers to synonyms registered during the construction
30// of Synonyme_info objects. If multiple synonyms share the same name (Synonyme_info::n), then
31// only one is registered in Synonyme_info::les_synonymes.
32const Synonyme_info** Synonyme_info::les_synonymes=0;
33// For each element of the array "les_synonymes", this number is 1 if the
34// synonym name is shared with multiple synonyms, 0 otherwise.
35// See "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 to correctly free the memory we need to at least destroy the name
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 Searches for the synonym named "nom" in the list of registered synonyms using binary search.
70 *
71 * Strings are compared converted to uppercase.
72 * Stores in "index" the index of the synonym if found,
73 * otherwise the index of the next synonym after it (in that case,
74 * les_synonymes[index-1]->n < nom < les_synonymes[index]->n )
75 * Returns 1 if the synonym was found, 0 otherwise.
76 *
77 */
78int Synonyme_info::search_synonyme_info_name(const char *nom, int& index)
79{
80 assert(nom != 0);
81 // [imin..imax] is the interval where the searched index lies
82 int imin = 0;
83 int imax = nb_classes;
84 while (imax > imin)
85 {
86 // We always have 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 // the searched index is therefore less than or equal to "milieu"
98 imax = milieu;
99 }
100 else
101 {
102 // nom > les_synonymes[milieu]
103 // the searched index is therefore strictly greater than "milieu"
104 imin = milieu + 1;
105 }
106 }
107 index = imax;
108 return 0;
109}
110/*! @brief Constructor from a name and an array of parent classes.
111 *
112 * @param (const char* nom) the name of the synonym to create
113 * @param (int nb_base) the number of parent classes in the bases[] array
114 * @param (const Synonyme_info* bases[]) the array specifying the base synonyms (parents) of the synonym to create
115 * @throws Exits on error if the name is not defined (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 Static method called by Synonyme_info constructors to remove a synonym from the list of registered synonyms.
131 *
132 * Verifies that the synonym name exists.
133 *
134 */
135void Synonyme_info::retirer_synonyme(const char* nom)
136{
137 // Search where to find the synonym in the array:
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 // Remove the synonym from the array at index "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 Static method called by Synonyme_info constructors to add a new synonym to the list of registered synonyms.
155 *
156 * Verifies that the synonym name does not already exist.
157 *
158 */
160{
161 // Check that there is enough room in the array:
162 if (les_synonymes_memsize <= nb_classes + 1)
163 {
164 static const int INCREMENT = 512;
165 // Not enough room in the array: resize it.
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 // Search where to insert the synonym in the array:
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 // Add the synonym to the array at index "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 Writes the entire hierarchy of the considered synonym to an output stream.
200 *
201 * @param (Sortie& os) output stream
202 * @return (Sortie&) the modified output stream
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 Tests whether a class synonym exists: if there is a class T whose Synonyme_info has
214 *
215 * the name "nom", then est_un_synonyme returns 1,
216 * returns null pointer otherwise.
217 *
218 * @param (const char* nom) character string associated with a synonym
219 * @return (int) return code (0 or 1)
220 */
222{
223 const Synonyme_info * synonyme = synonyme_info_from_name(nom);
224 return (synonyme != 0);
225}
226
227/*! @brief Static method that returns a pointer to the Synonyme_info whose name is "synonyme_name".
228 *
229 * If synonyme_name is not a synonym,
230 * returns a null pointer.
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)
Exit routine for TRUST within a Kokkos region.
Definition Process.cpp:466
Base class for output streams.
Definition Sortie.h:52
Models synonym information for Objet_U objects.
const char * nom() const
static const Synonyme_info * synonyme_info_from_name(const char *synonyme_name)
Static method that returns a pointer to the Synonyme_info whose name is "synonyme_name".
static void ajouter_synonyme(const Synonyme_info &synonyme_info)
Static method called by Synonyme_info constructors to add a new synonym to the list of registered syn...
static int est_un_synonyme(const char *)
Tests whether a class synonym exists: if there is a class T whose Synonyme_info has.
static Sortie & hierarchie(Sortie &)
Writes the entire hierarchy of the considered synonym to an output stream.
static int est_un_type(const char *)
Tests whether a class of the given type exists. If a class T whose Type_info has the name nom exists,...