0023274: MSVC++ warnings issued during compilation for 64bits
[occt.git] / src / Units / Units_Sentence.cxx
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
21
22 #include <Units_NoSuchType.hxx>
23 #include <Units_Sentence.ixx>
24 #include <Units_Token.hxx>
25 #include <Units_ShiftedToken.hxx>
26 #include <Units_TokensSequence.hxx>
27 #include <Units_Operators.hxx>
28
29
30 static Handle(Units_Token) CreateTokenForNumber(const Standard_CString str)
31 {
32   TCollection_AsciiString tstr = str[0];
33   Standard_Boolean IsPoint = Standard_False;
34   Standard_Size len = strlen(str);
35   for(Standard_Size in=1; in < len; in++) {
36     if( str[in]=='0' || str[in]=='1' || str[in]=='2' || str[in]=='3' || 
37         str[in]=='4' || str[in]=='5' || str[in]=='6' || str[in]=='7' || 
38         str[in]=='8' || str[in]=='9' ) {
39       tstr.AssignCat(str[in]);
40     }
41     else if( str[in]=='.' && !IsPoint ) {
42       tstr.AssignCat(str[in]);
43       IsPoint = Standard_True;
44     }
45     else
46       break;
47   }
48   return new Units_Token(tstr.ToCString(), "0");
49 }
50
51
52 //=======================================================================
53 //function : Units_Sentence
54 //purpose  : 
55 //=======================================================================
56
57 Units_Sentence::Units_Sentence(const Handle(Units_Lexicon)& alexicon,
58                                const Standard_CString astring)
59 {
60   Standard_Integer index;
61   Standard_Integer k,l;
62   Standard_Size i,limchain;
63   char chain[255];
64   Handle(Units_Token) token;
65   Handle(Units_Token) referencetoken;
66   
67   thesequenceoftokens = new Units_TokensSequence();
68   Handle(Units_TokensSequence) lstlexicon=alexicon->Sequence();
69   Units_NoSuchType_Raise_if(lstlexicon.IsNull(),"BAD LEXICON descriptor");
70   limchain=strlen(astring);
71   k=0;
72   for(l=0; l<255; l++) {
73     chain[l]=0;
74   }
75   i=0;
76
77   TCollection_AsciiString tmpstr = astring;
78   //Handle(Units_Token) tmptoken;
79   TCollection_AsciiString PrevMean;
80   TCollection_AsciiString PrevWord;
81   while(i < limchain) {
82     Standard_Boolean IsFound = Standard_False;
83     TCollection_AsciiString LastWord = "";
84     for(index=1; index<=lstlexicon->Length(); index++) {
85       referencetoken = lstlexicon->Value(index);
86       TCollection_AsciiString aword = referencetoken->Word();
87       int num = tmpstr.Search(aword);
88       if( num==1 && aword.Length()>=LastWord.Length() ) {
89         token = referencetoken->Creates();
90         LastWord = aword;
91         IsFound = Standard_True;
92       }
93     }
94     if(!IsFound) {
95       // may be it is a number(degree)?
96       LastWord = tmpstr.SubString(1,1);
97       if(!LastWord.IsIntegerValue()) {
98         // unknown expression - not create sentene
99         thesequenceoftokens->Clear();
100 #ifdef DEB
101         cout<<"Warning: can not create correct sentence from string: "<<astring<<endl;
102 #endif
103         return;
104       }
105       else {
106         // create token for number
107         token = CreateTokenForNumber(tmpstr.ToCString());
108         LastWord = token->Word();
109       }
110     }
111     if(i>0) {
112       // make additional checking
113       if( ( token->Mean()=="M" && ( PrevMean=="M" || PrevMean=="MU" || PrevMean=="0" ) ) ||
114           ( token->Mean()=="U" && ( PrevMean=="U" || PrevMean=="0" )                   ) ||
115           ( token->Mean()=="O" && ( PrevMean=="M" || PrevMean=="O" )                   ) ||
116           ( ( token->Word()=="+" || token->Word()=="-" ) && PrevWord!="("              ) ||
117           ( token->Mean()=="S" && ( PrevMean=="M" )                                    ) ||
118           ( token->Mean()=="0" && ( PrevMean=="M" || PrevMean=="U" || PrevMean=="MU" ) ) )  {
119         // incorrect situation
120         thesequenceoftokens->Clear();
121 #ifdef DEB
122         cout<<"Warning: can not create correct sentence from string: "<<astring<<endl;
123 #endif
124         return;
125       }
126     }
127     thesequenceoftokens->Append(token);
128     PrevMean = token->Mean();
129     PrevWord = token->Word();
130     i = i + LastWord.Length();
131     tmpstr.Remove(1,LastWord.Length());
132   }
133
134 //  for(i=1; i<=thesequenceoftokens->Length(); i++) {
135 //    token = thesequenceoftokens->Value(i);
136 //    cout<<"i="<<i<<"  token:  "<<token->Word().ToCString()<<"   "<<token->Mean().ToCString()
137 //      <<"   "<<token->Value()<<endl;
138 //  }
139
140 /*
141   while(i < limchain) {
142     Standard_Integer itrouv=0;
143     for(index=1; index<=lstlexicon->Length(); index++) {
144       referencetoken = lstlexicon->Value(index);
145       if(i+referencetoken->Length() <= limchain) {
146         if(referencetoken <= &astring[i]) {
147           if(k) {
148             token = new Units_Token(chain,"0");
149             thesequenceoftokens->Append(token);
150             k=0;
151             for(l=0; l<255; l++) {
152               chain[l]=0;
153             }
154           }
155           token = referencetoken->Creates();
156           thesequenceoftokens->Append(token);
157           i = i + token->Length();
158           itrouv=1;
159           break;
160         }
161       }
162     }
163     if(!itrouv) {
164       chain[k++]=astring[i++];
165     }
166   }
167   if(k) {
168     token = new Units_Token(chain, "0");
169     thesequenceoftokens->Append(token);
170   }
171 */
172 }
173
174
175 //=======================================================================
176 //function : SetConstants
177 //purpose  : 
178 //=======================================================================
179
180 void Units_Sentence::SetConstants()
181 {
182   Standard_Integer index;
183   Standard_Real value;
184   Handle(Units_Token) token;
185   TCollection_AsciiString string;
186
187   for(index=1;index<=thesequenceoftokens->Length();index++) {
188     token = thesequenceoftokens->Value(index);
189     if(token->Value()==0.) {
190       string = token->Word();
191       if(string.IsRealValue()) {
192         value = string.RealValue();
193         token->Mean("K");
194         token->Value(value);
195       }
196     }
197   }
198 }
199
200
201 //=======================================================================
202 //function : CalculateLocal
203 //purpose  : auxilary
204 //=======================================================================
205 static Handle(Units_Token) CalculateLocal(const Handle(Units_TokensSequence)& aSeq)
206 {
207   //cout<<endl;
208   //for(int index=1; index<=aSeq->Length(); index++) {
209   //  Handle(Units_Token) tok = aSeq->Value(index);
210   //  cout<<tok->Word()<<" ";
211   //}
212   //cout<<endl;
213   Handle(Units_Token) tok1,tok2;
214   Standard_Integer i,j;
215
216   if(aSeq->Length()==1) {
217     return aSeq->Value(1);
218   }
219
220   // case of unar sign
221   if(aSeq->Length()==2) {
222     if(aSeq->Value(1)->Word()=="+")
223       aSeq->Remove(1);
224     if(aSeq->Value(1)->Word()=="-") {
225       tok2 = aSeq->Value(2);
226       TCollection_AsciiString aword = "-";
227       aword.AssignCat(tok2->Word());
228       tok1 = new Units_Token(aword.ToCString(), tok2->Mean().ToCString(),
229                              tok2->Value()*(-1.0), tok2->Dimensions());
230       aSeq->Remove(1);
231       aSeq->SetValue(1,tok1);
232     }
233     return aSeq->Value(1);
234   }
235
236   Standard_Boolean IsBracket = Standard_True;
237   while(IsBracket) {
238     for(i=1; i<=aSeq->Length(); i++) {
239       if(aSeq->Value(i)->Word()=="(") {
240         Handle(Units_TokensSequence) TmpSeq = new Units_TokensSequence;
241         Standard_Integer NbBrackets = 1;
242         for(j=i+1; j<=aSeq->Length(); j++) {
243           if(aSeq->Value(j)->Word()==")")
244             NbBrackets--;
245           if(aSeq->Value(j)->Word()=="(")
246             NbBrackets++;
247           if(NbBrackets>0)
248             TmpSeq->Append(aSeq->Value(j));
249           else
250             break;
251         }
252         tok1 = CalculateLocal(TmpSeq);
253         aSeq->Remove(i+1,j);
254         aSeq->SetValue(i,tok1);
255         break;
256       }
257     }
258     if(i>aSeq->Length()) {
259       IsBracket = Standard_False;
260       // there are not brackets => make calculations
261       // step 1: operation '**'
262       for(i=1; i<=aSeq->Length(); i++) {
263         if(aSeq->Value(i)->Word()=="**") {
264           tok1 = aSeq->Value(i-1);
265           tok2 = aSeq->Value(i+1);
266           tok1 = pow(tok1,tok2);
267           aSeq->Remove(i);
268           aSeq->Remove(i);
269           aSeq->SetValue(i-1,tok1);
270           i--;
271         }
272       }
273       // step 2: operation '*', '.' and '/'
274       for(i=1; i<=aSeq->Length(); i++) {
275         if(aSeq->Value(i)->Mean()=="O") {
276           tok1 = aSeq->Value(i-1);
277           tok2 = aSeq->Value(i+1);
278           if(aSeq->Value(i)->Word()=="/")
279             tok1 = tok1 / tok2;
280           else
281             tok1 = tok1 * tok2;
282           aSeq->Remove(i);
283           aSeq->Remove(i);
284           aSeq->SetValue(i-1,tok1);
285           i--;
286         }
287       }
288       // now aSeq have to include only one result token
289     }
290   }
291   return tok1;
292 }
293
294
295 //=======================================================================
296 //function : Evaluate
297 //purpose  : 
298 //=======================================================================
299
300 Handle(Units_Token) Units_Sentence::Evaluate()
301 {
302   Handle(Units_Token) rtoken,ktoken;
303   if(thesequenceoftokens->Length()==0)
304     return rtoken;
305
306 /* old variant
307   Standard_Integer index;
308   static char *ooper[6] = { "+", "-", "*", ".", "/", "**" };
309   Standard_Integer numterm,i,j,k,maxlevel,curlevel,level[255];
310   Handle(Units_Token) currenttoken;
311   TCollection_AsciiString string;
312   TCollection_AsciiString mean;
313   TCollection_AsciiString oper;
314   
315   numterm=curlevel=i=0;
316   for(index=1;index<=thesequenceoftokens->Length();index++) {
317     string = thesequenceoftokens->Value(index)->Word();
318
319     if( string=="(" ) {
320       level[numterm]=curlevel;
321       curlevel++;
322     }
323     else if( string==")" ) {
324       curlevel--;
325       level[numterm]=curlevel;
326     }
327     else {
328       level[numterm]=curlevel;
329     }
330     numterm++;
331   }
332
333   //if(IPrint==1) {
334   //  cout<<endl;
335   //  for(index=1; index<=thesequenceoftokens->Length(); index++) {
336   //    Handle(Units_Token) tok = thesequenceoftokens->Value(index);
337   //    cout<<tok->Word()<<" ";
338   //  }
339   //  cout<<endl;
340   //  for(index=1; index<=thesequenceoftokens->Length(); index++) {
341   //    cout<<level[index-1]<<" ";
342   //  }
343   //  cout<<endl;
344   //}
345
346   if(curlevel) {
347     cout<<" Incorrect number of brackets"<<endl;
348     return new Units_Token();
349   }
350
351   for(k=0; k<6; k++) {
352     for(index=1,i=0; index<=thesequenceoftokens->Length(); index++,i++) {
353       if( thesequenceoftokens->Value(index)->Word() == ooper[k] ) {
354         j=i+1;
355         curlevel=level[j];
356         while(j < numterm && level[j] >= curlevel)
357           level[j++]++;
358         j=i-1;
359         curlevel=level[j];
360         while(j >= 0 && level[j] >= curlevel)
361           level[j--]++;
362       }
363     }
364   }
365
366   Handle(Units_Dimensions) aDim;
367
368   numterm--;
369   while(numterm>0) {
370
371     maxlevel=0;
372     for(i=0; i<=numterm; i++)if(level[i] > maxlevel)
373       maxlevel=level[i];
374
375     i=0;
376     while(level[i] != maxlevel)
377       i++;
378
379     oper.Clear();
380
381     k=i;
382     while( k<=numterm && level[k]==maxlevel ) {
383       ktoken=thesequenceoftokens->Value(k+1);
384       mean=ktoken->Mean();
385       if(mean=="O") {
386         oper = ktoken->Word();
387       }
388       else if(mean!="S") {
389         if     (oper == "/")  rtoken = rtoken / ktoken;
390         else if(oper == "+")  rtoken = rtoken + ktoken;
391         else if(oper == "-")  rtoken = rtoken - ktoken;
392         else if(oper == "*")  rtoken = rtoken * ktoken;
393         else if(oper == "**") rtoken = pow(rtoken,ktoken);
394         else if(oper == ".")  rtoken = rtoken * ktoken;
395         else                  rtoken = ktoken->Creates();
396       }
397       k++;
398     }
399     thesequenceoftokens->SetValue(i+1,rtoken);
400     level[i]=maxlevel-1;
401
402     if( (i+1) != k ) {
403       thesequenceoftokens->Remove(i+2,k);
404       j=i;
405       while(k <= numterm)
406         level[++j]=level[k++];
407       numterm=j;
408     }
409   }
410
411   rtoken = thesequenceoftokens->Value(1)->Creates();
412
413   if( rtoken->Value()==0. ) {
414     cout << "*BAD token value from unit '" << rtoken->Word() << "'" << endl;
415     rtoken->Value(1.);
416   }
417 */ // end old variant
418
419   // variant skl 15.09.2005
420   rtoken = CalculateLocal(thesequenceoftokens);
421
422   //rtoken->Dump(0,1);
423
424   return rtoken;
425 }