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(__uxp__) && \
145 !defined(__osf__) && !defined(USL) && !defined(linux) && \
146 !defined(CSRG_BASED) && !defined(sun)
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)
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)
161 FeatureValue *result = 0;
165 left = f_left->evaluate();
166 right = f_right->evaluate();
171 result = *left + *right ;
174 result = *left - *right ;
177 result = *left * *right ;
180 result = *left / *right ;
201 VariableNode::evaluate() const
203 // this could be a feature or a variable
204 // first look in the parent feature set
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
211 // see if item exists in parent feature hierarchy, and if not, then we go to
212 // the variable table
214 //MESSAGE(cerr, "VariableNode::evaluate()");
215 //f_name.print(cerr);
217 FeatureValue *variable_value = gVariableTable->lookup(f_name).evaluate();
219 //debug(cerr, int(variable_value));
222 throw(CASTUVEXCEPT undefinedVariableException(f_name));
224 // have to evaluate it in case it contains expressions or other variables
226 FeatureValue *return_variable = 0;
230 return_variable = variable_value->evaluate() ;
234 delete return_variable;
235 delete variable_value ;
240 //MESSAGE(cerr, "VariableNode::evaluate() completes");
242 delete variable_value ;
243 return return_variable;
247 CompositeVariableNode::evaluate() const
250 MESSAGE(cerr, "CompositeVariableNode::evaluate():");
253 f_items[0] -> print(cerr);
257 //debug(cerr, int(gCurrentLocalSet));
258 //debug(cerr, int(gParentCompleteSet));
260 const Feature *f = 0;
262 if ( gCurrentLocalSet )
263 f = gCurrentLocalSet->deep_lookup(f_items) ;
265 //debug(cerr, int(f));
267 if (!f && gParentCompleteSet )
268 f = gParentCompleteSet->deep_lookup(f_items);
270 //debug(cerr, int(f));
272 //if ( f == 0 && gRenderer ) {
274 FeatureValue* fv = gAutoNumberFP.evaluate(f_items[0] -> name());
277 throw(CASTBEEXCEPT badEvaluationException());
284 throw(CASTBEEXCEPT badEvaluationException());
287 return f->evaluate();
294 ConstantNode::evaluate() const
296 //return f_value->clone();
297 return f_value->evaluate();
300 extern unsigned g_validation_mode;
302 #if defined(__FreeBSD__) && (__FreeBSD__ >= 10) && !defined(__llvm__)
303 __attribute__((optimize(0)))
306 SgmlAttributeNode::evaluate() const
308 if ( g_validation_mode == true ) {
309 throw(CASTUAEXCEPT undefinedAttributeException(f_name));
312 const Attribute *attr = gCurrentElement->get_attribute(f_name);
315 return new FeatureValueString(attr->value());
317 throw(CASTUAEXCEPT undefinedAttributeException(f_name));
323 // ////////////////////////////////////////////////////////////////////////
325 // ////////////////////////////////////////////////////////////////////////
327 ostream &operator<<(ostream &o, const Expression &e)
332 ostream &operator<< (ostream &o, const TermNode &t)
338 Expression::print(ostream &o) const
340 return o << *f_root ;
344 VariableNode::print(ostream &o) const
350 BinaryOperatorNode::print(ostream &o) const
352 o << "(" << *f_left << ' ';
369 return o << ' ' << *f_right << ')' ;
373 SgmlAttributeNode::print(ostream &o) const
375 return o << '@' << f_name ;
379 ConstantNode::print(ostream &o) const
381 return o << *f_value ;
386 CompositeVariableNode::print(ostream &o) const
388 int length = f_items.entries();
389 for (int i = 0; i < length; i++)
399 // /////////////////////////////////////////////////////////////////////////
401 // /////////////////////////////////////////////////////////////////////////
404 VariableNode::clone() const
406 return new VariableNode(f_name);
410 CompositeVariableNode::clone() const
412 int nitems = f_items.entries();
413 CompositeVariableNode *node = new CompositeVariableNode(nitems);
415 for (int i = 0; i < nitems; i++)
416 node->appendItem(*f_items(i));
422 BinaryOperatorNode::clone() const
424 return new BinaryOperatorNode(f_operator, f_left->clone(), f_right->clone());
428 SgmlAttributeNode::clone() const
430 return new SgmlAttributeNode(f_name);
434 ConstantNode::clone() const
436 return new ConstantNode(f_value->clone());