2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
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)
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
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these libraries and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
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"
35 #include "HardCopy/autoNumberFP.h"
38 extern const Element *gCurrentElement;
39 extern const FeatureSet *gCurrentLocalSet;
40 extern const FeatureSet *gParentCompleteSet;
42 Expression::Expression(TermNode *root)
47 Expression::Expression(const Expression &e)
48 : f_root(e.f_root->clone())
52 ConstantNode::ConstantNode(FeatureValue *v)
57 VariableNode::VariableNode(const Symbol &name)
62 CompositeVariableNode::CompositeVariableNode()
67 CompositeVariableNode::CompositeVariableNode(size_t capac)
72 CompositeVariableNode::~CompositeVariableNode()
74 f_items.clearAndDestroy();
78 CompositeVariableNode::prependItem(const Symbol& item)
80 f_items.prepend(new Symbol(item));
84 CompositeVariableNode::appendItem(const Symbol& item)
86 f_items.append(new Symbol(item));
90 CompositeVariableNode::convertableToVariable()
93 if ( f_items.entries() == 1 ) {
95 if ( gVariableTable -> exists(*x) )
102 BinaryOperatorNode::BinaryOperatorNode(operatorType t,
103 TermNode *left, TermNode *right)
104 : f_operator(t), f_left(left), f_right(right)
108 BinaryOperatorNode::~BinaryOperatorNode()
114 SgmlAttributeNode::SgmlAttributeNode(const Symbol &name)
120 Expression::evaluate() const
122 return f_root->evaluate();
125 Expression::~Expression()
130 TermNode::~TermNode()
134 ConstantNode::~ConstantNode()
140 BinaryOperatorNode::evaluate() const
142 // calculate children trees and then have feature value do the operation
144 #if !defined(SC3) && !defined(_IBMR2) && !defined(linux) && \
145 !defined(CSRG_BASED) && !defined(sun)
148 FeatureValue *left = 0;
149 #if !defined(SC3) && !defined(_IBMR2) && !defined(linux) && \
150 !defined(CSRG_BASED) && !defined(sun)
153 FeatureValue *right = 0;
154 #if !defined(SC3) && !defined(_IBMR2) && !defined(linux) && \
155 !defined(CSRG_BASED) && !defined(sun)
158 FeatureValue *result = 0;
162 left = f_left->evaluate();
163 right = f_right->evaluate();
168 result = *left + *right ;
171 result = *left - *right ;
174 result = *left * *right ;
177 result = *left / *right ;
198 VariableNode::evaluate() const
200 // this could be a feature or a variable
201 // first look in the parent feature set
203 // NOTE: actual operation should be to look in the local feature set first
204 // before going to the parent unless the inherit operator was used. Not sure
205 // how to do this, because at this point, we are trying to evaluate the
206 // current feature set
208 // see if item exists in parent feature hierarchy, and if not, then we go to
209 // the variable table
211 //MESSAGE(cerr, "VariableNode::evaluate()");
212 //f_name.print(cerr);
214 FeatureValue *variable_value = gVariableTable->lookup(f_name).evaluate();
216 //debug(cerr, int(variable_value));
219 throw(CASTUVEXCEPT undefinedVariableException(f_name));
221 // have to evaluate it in case it contains expressions or other variables
223 FeatureValue *return_variable = 0;
227 return_variable = variable_value->evaluate() ;
231 delete return_variable;
232 delete variable_value ;
237 //MESSAGE(cerr, "VariableNode::evaluate() completes");
239 delete variable_value ;
240 return return_variable;
244 CompositeVariableNode::evaluate() const
247 MESSAGE(cerr, "CompositeVariableNode::evaluate():");
250 f_items[0] -> print(cerr);
254 //debug(cerr, int(gCurrentLocalSet));
255 //debug(cerr, int(gParentCompleteSet));
257 const Feature *f = 0;
259 if ( gCurrentLocalSet )
260 f = gCurrentLocalSet->deep_lookup(f_items) ;
262 //debug(cerr, int(f));
264 if (!f && gParentCompleteSet )
265 f = gParentCompleteSet->deep_lookup(f_items);
267 //debug(cerr, int(f));
269 //if ( f == 0 && gRenderer ) {
271 FeatureValue* fv = gAutoNumberFP.evaluate(f_items[0] -> name());
274 throw(CASTBEEXCEPT badEvaluationException());
281 throw(CASTBEEXCEPT badEvaluationException());
284 return f->evaluate();
291 ConstantNode::evaluate() const
293 //return f_value->clone();
294 return f_value->evaluate();
297 extern unsigned g_validation_mode;
299 #if defined(__FreeBSD__) && (__FreeBSD__ >= 10) && !defined(__llvm__)
300 __attribute__((optimize(0)))
303 SgmlAttributeNode::evaluate() const
305 if ( g_validation_mode == true ) {
306 throw(CASTUAEXCEPT undefinedAttributeException(f_name));
309 const Attribute *attr = gCurrentElement->get_attribute(f_name);
312 return new FeatureValueString(attr->value());
314 throw(CASTUAEXCEPT undefinedAttributeException(f_name));
320 // ////////////////////////////////////////////////////////////////////////
322 // ////////////////////////////////////////////////////////////////////////
324 ostream &operator<<(ostream &o, const Expression &e)
329 ostream &operator<< (ostream &o, const TermNode &t)
335 Expression::print(ostream &o) const
337 return o << *f_root ;
341 VariableNode::print(ostream &o) const
347 BinaryOperatorNode::print(ostream &o) const
349 o << "(" << *f_left << ' ';
366 return o << ' ' << *f_right << ')' ;
370 SgmlAttributeNode::print(ostream &o) const
372 return o << '@' << f_name ;
376 ConstantNode::print(ostream &o) const
378 return o << *f_value ;
383 CompositeVariableNode::print(ostream &o) const
385 int length = f_items.entries();
386 for (int i = 0; i < length; i++)
396 // /////////////////////////////////////////////////////////////////////////
398 // /////////////////////////////////////////////////////////////////////////
401 VariableNode::clone() const
403 return new VariableNode(f_name);
407 CompositeVariableNode::clone() const
409 int nitems = f_items.entries();
410 CompositeVariableNode *node = new CompositeVariableNode(nitems);
412 for (int i = 0; i < nitems; i++)
413 node->appendItem(*f_items(i));
419 BinaryOperatorNode::clone() const
421 return new BinaryOperatorNode(f_operator, f_left->clone(), f_right->clone());
425 SgmlAttributeNode::clone() const
427 return new SgmlAttributeNode(f_name);
431 ConstantNode::clone() const
433 return new ConstantNode(f_value->clone());