0023498: Comparison always true in Units_Lexicon::Creates()
[occt.git] / src / Units / Units_UnitsDictionary.cxx
CommitLineData
b311480e 1// Created on: 1992-06-24
2// Created by: Gilles DEBARBOUILLE
3// Copyright (c) 1992-1999 Matra Datavision
4// Copyright (c) 1999-2012 OPEN CASCADE SAS
5//
6// The content of this file is subject to the Open CASCADE Technology Public
7// License Version 6.5 (the "License"). You may not use the content of this file
8// except in compliance with the License. Please obtain a copy of the License
9// at http://www.opencascade.org and read it completely before using this file.
10//
11// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13//
14// The Original Code and all software distributed under the License is
15// distributed on an "AS IS" basis, without warranty of any kind, and the
16// Initial Developer hereby disclaims all such warranties, including without
17// limitation, any warranties of merchantability, fitness for a particular
18// purpose or non-infringement. Please see the License for the specific terms
19// and conditions governing the rights and limitations under the License.
20
7fd59977 21#include <Units_UnitsDictionary.ixx>
22#include <Units.hxx>
23
24#include <Standard_Stream.hxx>
25
26#ifdef HAVE_CONFIG_H
27# include <config.h>
28#endif
29#include <stdio.h>
30#ifdef HAVE_STDLIB_H
31# include <stdlib.h>
32#endif
33#ifdef HAVE_SYS_TYPES_H
34# include <sys/types.h>
35#endif
36#if defined (HAVE_SYS_STAT_H) || defined(WNT)
37# include <sys/stat.h>
38#endif
39
40#include <Units_Token.hxx>
41#include <Units_TokensSequence.hxx>
42#include <Units_UnitsSequence.hxx>
43#include <Units_Unit.hxx>
44#include <Units_ShiftedUnit.hxx>
45#include <Units_Dimensions.hxx>
46#include <Units_QuantitiesSequence.hxx>
47#include <Units_Quantity.hxx>
48#include <Units_MathSentence.hxx>
49#include <Units_UnitSentence.hxx>
50#include <Units_UnitsLexicon.hxx>
51#include <TCollection_HAsciiString.hxx>
52#include <TCollection_AsciiString.hxx>
53#include <TColStd_HSequenceOfHAsciiString.hxx>
54#include <Units_Operators.hxx>
55#include <OSD.hxx>
56
7fd59977 57
529b95df 58// GG 09.04.98 PRO13136
59// Ne pas utiliser la fonction systeme atof() qui
60// depend de la localisation
61static char DecimalPoint = '\0';
7fd59977 62static void GetDecimalPoint() {
63 Standard_Real f = 1.1 ;
64 char str[5] ;
65
66 sprintf(str,"%.1f",f) ;
67//#ifdef DEB
68// printf("Local System is %s\n",str) ;
69//#endif
70 DecimalPoint = str[1] ;
71}
7fd59977 72
73//=======================================================================
74//function : Units_UnitsDictionary
75//purpose :
76//=======================================================================
77
78Units_UnitsDictionary::Units_UnitsDictionary()
79{ }
80
81//=======================================================================
82//function : Creates
83//purpose :
84//=======================================================================
85
529b95df 86static inline bool strrightadjust (char *str)
87{
88 for (size_t len = strlen(str); len > 0 && IsSpace (str[len-1]); len--)
89 str[len-1] = '\0';
90 return str[0] != '\0';
91}
92
7fd59977 93void Units_UnitsDictionary::Creates(const Standard_CString afilename)
94{
529b95df 95 Standard_Boolean ismove;
96 Standard_Integer i, j, k, charnumber, unitscomputed;
7fd59977 97 Standard_Real matrix[50][50], coeff=0, move=0;
98 Handle(Units_Token) token;
99 Handle(Units_UnitsSequence) theunitssequence;
100 Handle(Units_Unit) unit;
101 Handle(Units_ShiftedUnit) shiftedunit;
7fd59977 102 Handle(Units_Quantity) quantity;
103
7fd59977 104 ifstream file(afilename, ios::in);
7fd59977 105 if(!file) {
106 cout<<"unable to open "<<afilename<<" for input"<<endl;
107 return;
108 }
109
110 thefilename = new TCollection_HAsciiString(afilename);
111
529b95df 112 struct stat buf;
7fd59977 113 if(!stat(afilename,&buf)) thetime = (Standard_Integer)buf.st_ctime;
114
115 thequantitiessequence = new Units_QuantitiesSequence();
116
529b95df 117 // read file line by line
7fd59977 118 Standard_Integer numberofunits = 0;
7fd59977 119 for(;;) {
529b95df 120 char line[256];
121 memset (line, 0, sizeof(line));
122 file.getline (line,255);
7fd59977 123 if (!file)
124 break;
529b95df 125
126 // trim trailing spaces
127 if (! strrightadjust (line))
128 continue; // empty line
129
130 // lines starting with dot separate sections of the file
7fd59977 131 if(line[0]=='.') {
529b95df 132
133 // if some units are collected in previous section, store them
7fd59977 134 if(numberofunits) {
135 unitscomputed = 0;
136 for(i=0; i<=numberofunits; i++)
137 matrix[i][i] = 1.;
138 for(i=0; i<=numberofunits; i++) {
139 if(matrix[i][0])
140 unitscomputed++;
141 }
142 while(unitscomputed != numberofunits+1) {
143 for(j=1; j<=numberofunits; j++) {
144 if(!matrix[j][0]) {
145 for(i=1; i<j; i++) {
146 if(matrix[j][i] && matrix[i][0]) {
147 matrix[j][0] = matrix[i][0]*matrix[j][i];
148 unitscomputed++;
149 if(unitscomputed == numberofunits+1)
150 break;
151 }
152 }
153 for(k=j+1; k<=numberofunits; k++) {
154 if(matrix[k][j] && matrix[k][0]) {
155 matrix[j][0] = matrix[k][0]/matrix[k][j];
156 unitscomputed++;
157 if(unitscomputed == numberofunits+1)
158 break;
159 }
160 }
161 }
162 if(unitscomputed == numberofunits+1)
163 break;
164 }
165 }
166 for(i=1;i<=theunitssequence->Length();i++) {
167 unit = theunitssequence->Value(i);
168 unit->Value(matrix[i][0]);
169 }
170 }
171
529b95df 172 // skip help string and read header
7fd59977 173 file.getline(line,255);
174 file.getline(line,255);
7fd59977 175
529b95df 176 // header consists of dimension name (40 symbols) and factors
177 // for basic SI dimensions (mass, length, time, ...)
178 char name[41];
179 char MM[11], LL[11], TT[11], II[11], tt[11], NN[11], JJ[11], PP[11], SS[11];
180 for (i=0; i < 41; i++) name[i] = '\0';
181 for (i=0; i < 11; i++) MM[i] = '\0';
182 for (i=0; i < 11; i++) LL[i] = '\0';
183 for (i=0; i < 11; i++) TT[i] = '\0';
184 for (i=0; i < 11; i++) II[i] = '\0';
185 for (i=0; i < 11; i++) tt[i] = '\0';
186 for (i=0; i < 11; i++) NN[i] = '\0';
187 for (i=0; i < 11; i++) JJ[i] = '\0';
188 for (i=0; i < 11; i++) PP[i] = '\0';
189 for (i=0; i < 11; i++) SS[i] = '\0';
190
191 sscanf (line, "%40c%10c%10c%10c%10c%10c%10c%10c%10c%10c",
192 name, MM, LL, TT, II, tt, NN, JJ, PP, SS);
193 strrightadjust (name);
194
195 Standard_Real M=0., L=0., T=0., I=0., t=0., N=0., J=0., P=0., S=0.;
7fd59977 196 OSD::CStringToReal(MM, M);
197 OSD::CStringToReal(LL, L);
198 OSD::CStringToReal(TT, T);
199 OSD::CStringToReal(II, I);
200 OSD::CStringToReal(tt, t);
201 OSD::CStringToReal(NN, N);
202 OSD::CStringToReal(JJ, J);
203 OSD::CStringToReal(PP, P);
204 OSD::CStringToReal(SS, S);
529b95df 205
206 Handle(Units_Dimensions) dimensions =
207 new Units_Dimensions (M, L, T, I, t, N, J, P, S);
7fd59977 208
209#ifdef DEB
210 /*cout << " Name of Dimension : " << name << endl ;
211 cout << MM << " " << LL << " " << TT << " "
212 << II << " " << tt << " " << NN << " "
213 << JJ << " " << PP << " " << SS << endl;
214 cout << M << " " << L << " " << T << " "
215 << I << " " << t << " " << N << " "
216 << J << " " << P << " " << S << endl;*/
217#endif
218
7fd59977 219 numberofunits = 0;
220 theunitssequence = new Units_UnitsSequence();
221 quantity = new Units_Quantity(name,dimensions,theunitssequence);
222 thequantitiessequence->Append(quantity);
529b95df 223
224 // clean matrix of units
7fd59977 225 for(i=0; i<50; i++) {
226 for(j=0; j<50; j++)
227 matrix[i][j] = 0.;
228 }
529b95df 229
230 // skip next line (dotted)
7fd59977 231 file.getline(line,255);
232 }
233
529b95df 234 else {
235 // normal line defining a unit should contain:
236 // - unit name (51 symbol)
237 // - unit notation (27 symbols)
238 // - factor (27 symbols)
239 // - base unit (27 symbols)
240 char unite[52], symbol[28], convert[28], unit2[28];
241 for (i=0; i < 52; i++) unite [i] = '\0';
242 for (i=0; i < 28; i++) symbol [i] = '\0';
243 for (i=0; i < 28; i++) convert[i] = '\0';
244 for (i=0; i < 28; i++) unit2 [i] = '\0';
245
246 sscanf (line, "%51c%27c%27c%27c", unite, symbol, convert, unit2);
247
248 strrightadjust (unite);
249 strrightadjust (symbol);
250 strrightadjust (convert);
251 strrightadjust (unit2);
252 if (! unite[0] && ! symbol[0] && ! convert[0] && ! unit2[0])
253 continue; // empty line
7fd59977 254
255 if(convert[0] == '[') {
256 coeff = 1.;
60be1f9b 257 i = (Standard_Integer) strlen(convert);
7fd59977 258 convert[i-1] = 0;
259 ismove = Standard_True;
260 charnumber = 1;
261 if(unite[0]) {
262 numberofunits++;
263 shiftedunit = new Units_ShiftedUnit(unite);
264 shiftedunit->Quantity(quantity);
265 theunitssequence->Append(shiftedunit);
266 }
267 }
268 else {
269 ismove = Standard_False;
270 charnumber = 0;
271 if(unite[0]) {
272 numberofunits++;
273 unit = new Units_Unit(unite);
274 unit->Quantity(quantity);
275 theunitssequence->Append(unit);
276 }
277 }
278
279 if(symbol[0]) {
280 Units::LexiconUnits(Standard_False)->AddToken(symbol,"U",0.);
281 Standard_Integer last = theunitssequence->Length();
282 theunitssequence->Value(last)->Symbol(symbol);
283 }
284
285 if(convert[charnumber] == '(') {
60be1f9b 286 i = (Standard_Integer) strlen(convert);
7fd59977 287 convert[i-1] = 0;
288 Units_MathSentence mathsentence(&convert[charnumber+1]);
289 if(ismove)
290 move = (mathsentence.Evaluate())->Value();
291 else
292 coeff = (mathsentence.Evaluate())->Value();
293 }
294 else if(convert[0]) {
7fd59977 295 if(ismove) {
296 OSD::CStringToReal(&convert[charnumber], move);
297 }
298 else
299 OSD::CStringToReal(convert, coeff);
7fd59977 300 }
301 else {
302 coeff = 1.;
303 }
304
305 if(ismove) {
306 if(move) {
307 Standard_Integer last = theunitssequence->Length();
308 unit = theunitssequence->Value(last);
309 shiftedunit = *(Handle_Units_ShiftedUnit*)&unit;
310 shiftedunit->Move(move);
311 }
312 }
313
314 if(unit2[0]) {
315 j = 0;
316 for(j=1;j<=theunitssequence->Length();j++)
317 if(theunitssequence->Value(j) == unit2)break;
318
319 if(j < numberofunits) {
320 matrix[numberofunits][j] = coeff;
321 }
322 else {
323 Units_UnitSentence unitsentence(unit2,thequantitiessequence);
324 matrix[numberofunits][0] = coeff*(unitsentence.Evaluate())->Value();
325 }
326 }
327 else {
328 if(numberofunits == 1) {
329 matrix[1][0] = coeff;
330 unit = theunitssequence->Value(numberofunits);
331 unit->Value(coeff);
332 }
333 }
334 }
335 }
336 file.close();
337/*
338 Handle(Units_TokensSequence) tmpSeq = Units::LexiconUnits(Standard_False)->Sequence();
339 for(int ii=1; ii<=tmpSeq->Length(); ii++) {
340 token = tmpSeq->Value(ii);
341 cout<<"i="<<ii<<" token: "<<token->Word().ToCString()<<" "
342 <<token->Mean().ToCString()<<" "<<token->Value()<<endl;
343 }
344 cout<<endl;
345*/
346}
347
348
349//=======================================================================
350//function : UpToDate
351//purpose :
352//=======================================================================
353
354Standard_Boolean Units_UnitsDictionary::UpToDate() const
355{
356 struct stat buf;
357 TCollection_AsciiString string = thefilename->String();
358 if(!stat(string.ToCString(),&buf)) {
359 if(thetime == buf.st_ctime) return Standard_True;
360 }
361
362 return Standard_False;
363}
364
365
366//=======================================================================
367//function : ActiveUnit
368//purpose :
369//=======================================================================
370
371TCollection_AsciiString Units_UnitsDictionary::ActiveUnit(const Standard_CString aquantity) const
372{
373 Standard_Integer index1;
374 Handle(Units_Unit) unit;
375 Handle(Units_UnitsSequence) unitssequence;
376 Handle(Units_Quantity) quantity;
377
378 for(index1=1;index1<=thequantitiessequence->Length();index1++) {
379 quantity = thequantitiessequence->Value(index1);
380 if(quantity == aquantity) {
381 unitssequence = quantity->Sequence();
382 if(unitssequence->Length())
383 return unitssequence->Value(1)->SymbolsSequence()->Value(1)->String();
384 else {
385 cout<<" Pas d'unite active pour "<<aquantity<<endl;
386 return "";
387 }
388 }
389 }
390
391 cout<<" La grandeur physique "<<aquantity<<" n'existe pas."<<endl;
392 return "";
393}