Disable all code related to libXp
[oweals/cde.git] / cde / programs / dtinfo / DtMmdb / StyleSheet / Expression.C
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 // $TOG: Expression.C /main/9 1998/04/17 11:48:40 mgreess $
24 #include "Attribute.h"
25 #include "AttributeList.h"
26 #include "Expression.h"
27 #include "FeatureValue.h"
28 #include "ResolverStack.h"
29 #include "StyleSheetExceptions.h"
30 #include "VariableTable.h"
31 #include "Renderer.h"
32 #include "Debug.h"
33 #include <sstream>
34
35 #include "HardCopy/autoNumberFP.h"
36
37
38 extern const Element            *gCurrentElement;
39 extern const FeatureSet         *gCurrentLocalSet;
40 extern const FeatureSet         *gParentCompleteSet;
41
42 Expression::Expression(TermNode *root)
43 : f_root(root)
44 {
45 }
46
47 Expression::Expression(const Expression &e)
48 : f_root(e.f_root->clone())
49 {
50 }
51
52 ConstantNode::ConstantNode(FeatureValue *v)
53 : f_value(v)
54 {
55 }
56
57 VariableNode::VariableNode(const Symbol &name)
58 : f_name(name)
59 {
60 }
61
62 CompositeVariableNode::CompositeVariableNode()
63 : f_items(4)
64 {
65 }
66
67 CompositeVariableNode::CompositeVariableNode(size_t capac)
68 : f_items(capac)
69 {
70 }
71
72 CompositeVariableNode::~CompositeVariableNode()
73 {
74   f_items.clearAndDestroy();
75 }
76
77 void
78 CompositeVariableNode::prependItem(const Symbol& item)
79 {
80   f_items.prepend(new Symbol(item));
81 }
82
83 void
84 CompositeVariableNode::appendItem(const Symbol& item)
85 {
86   f_items.append(new Symbol(item));
87 }
88
89 const Symbol* 
90 CompositeVariableNode::convertableToVariable()
91 {
92    const Symbol* x = 0;
93    if ( f_items.entries() == 1 ) {
94       x = f_items.first();
95       if ( gVariableTable -> exists(*x) ) 
96          return x; 
97    }
98  
99    return 0;
100 }
101
102 BinaryOperatorNode::BinaryOperatorNode(operatorType t,
103                                        TermNode *left, TermNode *right)
104 : f_operator(t), f_left(left), f_right(right)
105 {
106 }
107
108 BinaryOperatorNode::~BinaryOperatorNode()
109 {
110   delete f_left ;
111   delete f_right;
112 }
113
114 SgmlAttributeNode::SgmlAttributeNode(const Symbol &name)
115 : f_name(name)
116 {
117 }
118
119 FeatureValue *
120 Expression::evaluate() const
121 {
122   return f_root->evaluate();
123 }
124
125 Expression::~Expression()
126 {
127   delete  f_root ;
128 }
129
130 TermNode::~TermNode()
131 {
132 }
133
134 ConstantNode::~ConstantNode()
135 {
136   delete f_value ;
137 }
138
139 FeatureValue *
140 BinaryOperatorNode::evaluate() const
141 {
142   // calculate children trees and then have feature value do the operation 
143
144 #if !defined(SC3) && !defined(_IBMR2) && !defined(__uxp__) && \
145     !defined(__osf__) && !defined(USL) && !defined(linux) && \
146     !defined(CSRG_BASED) && !defined(sun)
147   volatile
148 #endif
149   FeatureValue *left =  0;
150 #if !defined(SC3) && !defined(_IBMR2) && !defined(__uxp__) && \
151     !defined(__osf__) && !defined(USL) && !defined(linux) && \
152     !defined(CSRG_BASED) && !defined(sun)
153   volatile
154 #endif
155   FeatureValue *right = 0;
156 #if !defined(SC3) && !defined(_IBMR2) && !defined(__uxp__) && \
157     !defined(__osf__) && !defined(USL) && !defined(linux) && \
158     !defined(CSRG_BASED) && !defined(sun)
159   volatile
160 #endif
161   FeatureValue *result = 0;
162
163   mtry
164     {
165       left  = f_left->evaluate();
166       right = f_right->evaluate();
167
168       switch (f_operator)
169         {
170         case PLUS:
171           result = *left + *right ;
172           break;
173         case MINUS:
174           result = *left - *right ;
175           break;
176         case TIMES:
177           result = *left * *right ;
178           break;
179         case DIVIDE:
180           result = *left / *right ;
181           break;
182         }
183
184     }
185   mcatch_any()
186     {
187       delete left ;
188       delete right ;
189       delete result ;
190       rethrow;
191     }
192   end_try ;
193   delete left ;
194   delete right ;
195   return result ;
196
197 }
198
199
200 FeatureValue *
201 VariableNode::evaluate() const
202 {
203   // this could be a feature or a variable 
204   // first look in the parent feature set 
205
206   // NOTE: actual operation should be to look in the local feature set first
207   // before going to the parent unless the inherit operator was used. Not sure
208   // how to do this, because at this point, we are trying to evaluate the
209   // current feature set
210
211   // see if item exists in parent feature hierarchy, and if not, then we go to
212   // the variable table
213
214 //MESSAGE(cerr, "VariableNode::evaluate()");
215 //f_name.print(cerr);
216   
217   FeatureValue *variable_value = gVariableTable->lookup(f_name).evaluate();
218
219 //debug(cerr, int(variable_value));
220
221   if (!variable_value)
222     throw(CASTUVEXCEPT undefinedVariableException(f_name));
223
224   // have to evaluate it in case it contains expressions or other variables
225   // etc.  
226   FeatureValue *return_variable = 0;
227
228   mtry
229     {
230       return_variable = variable_value->evaluate() ;
231     }
232   mcatch_any()
233     {
234       delete return_variable; 
235       delete variable_value ;
236       rethrow;
237     }
238   end_try;
239
240 //MESSAGE(cerr, "VariableNode::evaluate() completes");
241
242   delete variable_value ;
243   return return_variable;
244 }
245
246 FeatureValue *
247 CompositeVariableNode::evaluate() const
248 {
249 /*
250 MESSAGE(cerr, "CompositeVariableNode::evaluate():");
251 print(cerr);
252 cerr << "\n";
253 f_items[0] -> print(cerr);
254 MESSAGE(cerr, "");
255 */
256
257 //debug(cerr, int(gCurrentLocalSet));
258 //debug(cerr, int(gParentCompleteSet));
259
260   const Feature *f = 0;
261
262   if ( gCurrentLocalSet )
263      f = gCurrentLocalSet->deep_lookup(f_items) ;
264
265 //debug(cerr, int(f));
266
267   if (!f && gParentCompleteSet )
268     f = gParentCompleteSet->deep_lookup(f_items);
269
270 //debug(cerr, int(f));
271
272   //if ( f == 0 && gRenderer ) {
273   if ( f == 0 ) {
274     FeatureValue* fv = gAutoNumberFP.evaluate(f_items[0] -> name());
275     if ( fv == 0 ) {
276        //print(cerr);
277        throw(CASTBEEXCEPT badEvaluationException());
278     } else
279        return fv;
280   }
281
282   if (!f) {
283     //print(cerr);
284     throw(CASTBEEXCEPT badEvaluationException());
285   }
286
287   return f->evaluate();
288 }
289
290
291
292
293 FeatureValue *
294 ConstantNode::evaluate() const
295 {
296   //return f_value->clone();
297   return f_value->evaluate();
298 }
299
300 extern unsigned g_validation_mode;
301
302 #if defined(__FreeBSD__) && (__FreeBSD__ >= 10) && !defined(__llvm__)
303 __attribute__((optimize(0)))
304 #endif
305 FeatureValue *
306 SgmlAttributeNode::evaluate() const
307 {
308   if ( g_validation_mode == true ) {
309     throw(CASTUAEXCEPT undefinedAttributeException(f_name));
310   }
311
312   const Attribute *attr = gCurrentElement->get_attribute(f_name);
313
314   if (attr)
315     return new FeatureValueString(attr->value());
316   
317   throw(CASTUAEXCEPT undefinedAttributeException(f_name));
318
319   return 0 ;
320 }
321
322
323  // ////////////////////////////////////////////////////////////////////////
324  // Printing
325  // ////////////////////////////////////////////////////////////////////////
326
327 ostream &operator<<(ostream &o, const Expression &e)
328 {
329   return e.print(o);
330 }
331
332 ostream &operator<< (ostream &o, const TermNode &t)
333 {
334   return t.print(o);
335 }
336
337 ostream &
338 Expression::print(ostream &o) const
339 {
340   return o << *f_root ; 
341 }
342
343 ostream &
344 VariableNode::print(ostream &o) const
345 {
346   return o << f_name ;
347 }
348
349 ostream &
350 BinaryOperatorNode::print(ostream &o) const
351 {
352   o << "(" << *f_left << ' ';
353   switch (f_operator)
354     {
355     case PLUS:
356       o << '+' ;
357       break;
358     case MINUS:
359       o << '-';
360       break;
361     case TIMES:
362       o << '*' ;
363       break;
364     case DIVIDE:
365       o << '/';
366       break;
367     }
368
369   return o << ' ' << *f_right << ')' ;
370 }
371
372 ostream &
373 SgmlAttributeNode::print(ostream &o) const
374 {
375   return o << '@' << f_name ;
376 }
377
378 ostream &
379 ConstantNode::print(ostream &o) const
380 {
381   return o << *f_value ;
382 }
383
384
385 ostream &
386 CompositeVariableNode::print(ostream &o) const
387 {
388   int length = f_items.entries();
389   for (int i = 0; i < length; i++)
390     {
391       o << *f_items[i] ;
392       if (i < length - 1)
393         o << "." ;
394     }
395
396   return o ;
397 }
398
399 // /////////////////////////////////////////////////////////////////////////
400 // cloning
401 // /////////////////////////////////////////////////////////////////////////
402
403 TermNode *
404 VariableNode::clone() const
405 {
406   return new VariableNode(f_name);
407 }
408
409 TermNode *
410 CompositeVariableNode::clone() const
411 {
412   int nitems = f_items.entries();
413   CompositeVariableNode *node = new CompositeVariableNode(nitems);
414
415   for (int i = 0; i < nitems; i++)
416     node->appendItem(*f_items(i));
417
418   return node ;
419 }
420
421 TermNode *
422 BinaryOperatorNode::clone() const
423 {
424   return new BinaryOperatorNode(f_operator, f_left->clone(), f_right->clone());
425 }
426
427 TermNode *
428 SgmlAttributeNode::clone() const
429 {
430   return new SgmlAttributeNode(f_name);
431 }
432
433 TermNode *
434 ConstantNode::clone() const
435 {
436   return new ConstantNode(f_value->clone());
437 }
438