0020716: Eliminate usage of "config.h" header file
[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
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 8// This library is free software; you can redistribute it and/or modify it under
9// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 10// by the Free Software Foundation, with special exception defined in the file
11// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12// distribution for complete text of the license and disclaimer of any warranty.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
b311480e 16
7fd59977 17#include <Units_UnitsDictionary.ixx>
18#include <Units.hxx>
19
20#include <Standard_Stream.hxx>
21
7fd59977 22#include <stdio.h>
03155c18 23#include <sys/stat.h>
7fd59977 24
25#include <Units_Token.hxx>
26#include <Units_TokensSequence.hxx>
27#include <Units_UnitsSequence.hxx>
28#include <Units_Unit.hxx>
29#include <Units_ShiftedUnit.hxx>
30#include <Units_Dimensions.hxx>
31#include <Units_QuantitiesSequence.hxx>
32#include <Units_Quantity.hxx>
33#include <Units_MathSentence.hxx>
34#include <Units_UnitSentence.hxx>
35#include <Units_UnitsLexicon.hxx>
36#include <TCollection_HAsciiString.hxx>
37#include <TCollection_AsciiString.hxx>
38#include <TColStd_HSequenceOfHAsciiString.hxx>
39#include <Units_Operators.hxx>
40#include <OSD.hxx>
41
7fd59977 42//=======================================================================
43//function : Units_UnitsDictionary
44//purpose :
45//=======================================================================
46
47Units_UnitsDictionary::Units_UnitsDictionary()
48{ }
49
50//=======================================================================
51//function : Creates
52//purpose :
53//=======================================================================
54
529b95df 55static inline bool strrightadjust (char *str)
56{
57 for (size_t len = strlen(str); len > 0 && IsSpace (str[len-1]); len--)
58 str[len-1] = '\0';
59 return str[0] != '\0';
60}
61
7fd59977 62void Units_UnitsDictionary::Creates(const Standard_CString afilename)
63{
529b95df 64 Standard_Boolean ismove;
65 Standard_Integer i, j, k, charnumber, unitscomputed;
7fd59977 66 Standard_Real matrix[50][50], coeff=0, move=0;
67 Handle(Units_Token) token;
68 Handle(Units_UnitsSequence) theunitssequence;
69 Handle(Units_Unit) unit;
70 Handle(Units_ShiftedUnit) shiftedunit;
7fd59977 71 Handle(Units_Quantity) quantity;
72
7fd59977 73 ifstream file(afilename, ios::in);
7fd59977 74 if(!file) {
75 cout<<"unable to open "<<afilename<<" for input"<<endl;
76 return;
77 }
78
79 thefilename = new TCollection_HAsciiString(afilename);
80
529b95df 81 struct stat buf;
6c3e4c29 82 if(!stat(afilename,&buf)) thetime = buf.st_ctime;
7fd59977 83
84 thequantitiessequence = new Units_QuantitiesSequence();
85
529b95df 86 // read file line by line
7fd59977 87 Standard_Integer numberofunits = 0;
7fd59977 88 for(;;) {
529b95df 89 char line[256];
90 memset (line, 0, sizeof(line));
91 file.getline (line,255);
7fd59977 92 if (!file)
93 break;
529b95df 94
95 // trim trailing spaces
96 if (! strrightadjust (line))
97 continue; // empty line
98
99 // lines starting with dot separate sections of the file
7fd59977 100 if(line[0]=='.') {
529b95df 101
102 // if some units are collected in previous section, store them
7fd59977 103 if(numberofunits) {
104 unitscomputed = 0;
105 for(i=0; i<=numberofunits; i++)
106 matrix[i][i] = 1.;
107 for(i=0; i<=numberofunits; i++) {
108 if(matrix[i][0])
109 unitscomputed++;
110 }
111 while(unitscomputed != numberofunits+1) {
112 for(j=1; j<=numberofunits; j++) {
113 if(!matrix[j][0]) {
114 for(i=1; i<j; i++) {
115 if(matrix[j][i] && matrix[i][0]) {
116 matrix[j][0] = matrix[i][0]*matrix[j][i];
117 unitscomputed++;
118 if(unitscomputed == numberofunits+1)
119 break;
120 }
121 }
122 for(k=j+1; k<=numberofunits; k++) {
123 if(matrix[k][j] && matrix[k][0]) {
124 matrix[j][0] = matrix[k][0]/matrix[k][j];
125 unitscomputed++;
126 if(unitscomputed == numberofunits+1)
127 break;
128 }
129 }
130 }
131 if(unitscomputed == numberofunits+1)
132 break;
133 }
134 }
135 for(i=1;i<=theunitssequence->Length();i++) {
136 unit = theunitssequence->Value(i);
137 unit->Value(matrix[i][0]);
138 }
139 }
140
529b95df 141 // skip help string and read header
7fd59977 142 file.getline(line,255);
143 file.getline(line,255);
7fd59977 144
529b95df 145 // header consists of dimension name (40 symbols) and factors
146 // for basic SI dimensions (mass, length, time, ...)
147 char name[41];
148 char MM[11], LL[11], TT[11], II[11], tt[11], NN[11], JJ[11], PP[11], SS[11];
d0e4e578 149 memset(name,0x00,sizeof(name));
150 memset(MM,0x00,sizeof(MM));
151 memset(LL,0x00,sizeof(LL));
152 memset(TT,0x00,sizeof(TT));
153 memset(II,0x00,sizeof(II));
154 memset(tt,0x00,sizeof(tt));
155 memset(NN,0x00,sizeof(NN));
156 memset(JJ,0x00,sizeof(JJ));
157 memset(PP,0x00,sizeof(PP));
158 memset(SS,0x00,sizeof(SS));
529b95df 159
160 sscanf (line, "%40c%10c%10c%10c%10c%10c%10c%10c%10c%10c",
161 name, MM, LL, TT, II, tt, NN, JJ, PP, SS);
162 strrightadjust (name);
163
164 Standard_Real M=0., L=0., T=0., I=0., t=0., N=0., J=0., P=0., S=0.;
7fd59977 165 OSD::CStringToReal(MM, M);
166 OSD::CStringToReal(LL, L);
167 OSD::CStringToReal(TT, T);
168 OSD::CStringToReal(II, I);
169 OSD::CStringToReal(tt, t);
170 OSD::CStringToReal(NN, N);
171 OSD::CStringToReal(JJ, J);
172 OSD::CStringToReal(PP, P);
173 OSD::CStringToReal(SS, S);
529b95df 174
175 Handle(Units_Dimensions) dimensions =
176 new Units_Dimensions (M, L, T, I, t, N, J, P, S);
7fd59977 177
178#ifdef DEB
179 /*cout << " Name of Dimension : " << name << endl ;
180 cout << MM << " " << LL << " " << TT << " "
181 << II << " " << tt << " " << NN << " "
182 << JJ << " " << PP << " " << SS << endl;
183 cout << M << " " << L << " " << T << " "
184 << I << " " << t << " " << N << " "
185 << J << " " << P << " " << S << endl;*/
186#endif
187
7fd59977 188 numberofunits = 0;
189 theunitssequence = new Units_UnitsSequence();
190 quantity = new Units_Quantity(name,dimensions,theunitssequence);
191 thequantitiessequence->Append(quantity);
529b95df 192
193 // clean matrix of units
7fd59977 194 for(i=0; i<50; i++) {
195 for(j=0; j<50; j++)
196 matrix[i][j] = 0.;
197 }
529b95df 198
199 // skip next line (dotted)
7fd59977 200 file.getline(line,255);
201 }
202
529b95df 203 else {
204 // normal line defining a unit should contain:
205 // - unit name (51 symbol)
206 // - unit notation (27 symbols)
207 // - factor (27 symbols)
208 // - base unit (27 symbols)
209 char unite[52], symbol[28], convert[28], unit2[28];
d0e4e578 210 memset(unite, 0x00,sizeof(unite));
211 memset(symbol, 0x00,sizeof(symbol));
212 memset(convert,0x00,sizeof(convert));
213 memset(unit2, 0x00,sizeof(unit2));
529b95df 214
215 sscanf (line, "%51c%27c%27c%27c", unite, symbol, convert, unit2);
216
217 strrightadjust (unite);
218 strrightadjust (symbol);
219 strrightadjust (convert);
220 strrightadjust (unit2);
221 if (! unite[0] && ! symbol[0] && ! convert[0] && ! unit2[0])
222 continue; // empty line
7fd59977 223
224 if(convert[0] == '[') {
225 coeff = 1.;
60be1f9b 226 i = (Standard_Integer) strlen(convert);
7fd59977 227 convert[i-1] = 0;
228 ismove = Standard_True;
229 charnumber = 1;
230 if(unite[0]) {
231 numberofunits++;
232 shiftedunit = new Units_ShiftedUnit(unite);
233 shiftedunit->Quantity(quantity);
234 theunitssequence->Append(shiftedunit);
235 }
236 }
237 else {
238 ismove = Standard_False;
239 charnumber = 0;
240 if(unite[0]) {
241 numberofunits++;
242 unit = new Units_Unit(unite);
243 unit->Quantity(quantity);
244 theunitssequence->Append(unit);
245 }
246 }
247
248 if(symbol[0]) {
249 Units::LexiconUnits(Standard_False)->AddToken(symbol,"U",0.);
250 Standard_Integer last = theunitssequence->Length();
251 theunitssequence->Value(last)->Symbol(symbol);
252 }
253
254 if(convert[charnumber] == '(') {
60be1f9b 255 i = (Standard_Integer) strlen(convert);
7fd59977 256 convert[i-1] = 0;
257 Units_MathSentence mathsentence(&convert[charnumber+1]);
258 if(ismove)
259 move = (mathsentence.Evaluate())->Value();
260 else
261 coeff = (mathsentence.Evaluate())->Value();
262 }
263 else if(convert[0]) {
7fd59977 264 if(ismove) {
265 OSD::CStringToReal(&convert[charnumber], move);
266 }
267 else
268 OSD::CStringToReal(convert, coeff);
7fd59977 269 }
270 else {
271 coeff = 1.;
272 }
273
274 if(ismove) {
275 if(move) {
276 Standard_Integer last = theunitssequence->Length();
277 unit = theunitssequence->Value(last);
857ffd5e 278 shiftedunit = *(Handle(Units_ShiftedUnit)*)&unit;
7fd59977 279 shiftedunit->Move(move);
280 }
281 }
282
283 if(unit2[0]) {
284 j = 0;
285 for(j=1;j<=theunitssequence->Length();j++)
286 if(theunitssequence->Value(j) == unit2)break;
287
288 if(j < numberofunits) {
289 matrix[numberofunits][j] = coeff;
290 }
291 else {
292 Units_UnitSentence unitsentence(unit2,thequantitiessequence);
293 matrix[numberofunits][0] = coeff*(unitsentence.Evaluate())->Value();
294 }
295 }
296 else {
297 if(numberofunits == 1) {
298 matrix[1][0] = coeff;
299 unit = theunitssequence->Value(numberofunits);
300 unit->Value(coeff);
301 }
302 }
303 }
304 }
305 file.close();
306/*
307 Handle(Units_TokensSequence) tmpSeq = Units::LexiconUnits(Standard_False)->Sequence();
308 for(int ii=1; ii<=tmpSeq->Length(); ii++) {
309 token = tmpSeq->Value(ii);
310 cout<<"i="<<ii<<" token: "<<token->Word().ToCString()<<" "
311 <<token->Mean().ToCString()<<" "<<token->Value()<<endl;
312 }
313 cout<<endl;
314*/
315}
316
317
318//=======================================================================
319//function : UpToDate
320//purpose :
321//=======================================================================
322
323Standard_Boolean Units_UnitsDictionary::UpToDate() const
324{
325 struct stat buf;
326 TCollection_AsciiString string = thefilename->String();
327 if(!stat(string.ToCString(),&buf)) {
328 if(thetime == buf.st_ctime) return Standard_True;
329 }
330
331 return Standard_False;
332}
333
334
335//=======================================================================
336//function : ActiveUnit
337//purpose :
338//=======================================================================
339
340TCollection_AsciiString Units_UnitsDictionary::ActiveUnit(const Standard_CString aquantity) const
341{
342 Standard_Integer index1;
343 Handle(Units_Unit) unit;
344 Handle(Units_UnitsSequence) unitssequence;
345 Handle(Units_Quantity) quantity;
346
347 for(index1=1;index1<=thequantitiessequence->Length();index1++) {
348 quantity = thequantitiessequence->Value(index1);
349 if(quantity == aquantity) {
350 unitssequence = quantity->Sequence();
351 if(unitssequence->Length())
352 return unitssequence->Value(1)->SymbolsSequence()->Value(1)->String();
353 else {
354 cout<<" Pas d'unite active pour "<<aquantity<<endl;
355 return "";
356 }
357 }
358 }
359
360 cout<<" La grandeur physique "<<aquantity<<" n'existe pas."<<endl;
361 return "";
362}