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 librararies 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__) && !defined(__osf__) && !defined(USL) && !defined(linux)
147 FeatureValue *left = 0;
148 #if !defined(SC3) && !defined(_IBMR2) && !defined(__uxp__) && !defined(__osf__) && !defined(USL) && !defined(linux)
151 FeatureValue *right = 0;
152 #if !defined(SC3) && !defined(_IBMR2) && !defined(__uxp__) && !defined(__osf__) && !defined(USL) && !defined(linux)
155 FeatureValue *result = 0;
159 left = f_left->evaluate();
160 right = f_right->evaluate();
165 result = *left + *right ;
168 result = *left - *right ;
171 result = *left * *right ;
174 result = *left / *right ;
195 VariableNode::evaluate() const
197 // this could be a feature or a variable
198 // first look in the parent feature set
200 // NOTE: actual operation should be to look in the local feature set first
201 // before going to the parent unless the inherit operator was used. Not sure
202 // how to do this, because at this point, we are trying to evaluate the
203 // current feature set
205 // see if item exists in parent feature hierarchy, and if not, then we go to
206 // the variable table
208 //MESSAGE(cerr, "VariableNode::evaluate()");
209 //f_name.print(cerr);
211 FeatureValue *variable_value = gVariableTable->lookup(f_name).evaluate();
213 //debug(cerr, int(variable_value));
216 throw(CASTUVEXCEPT undefinedVariableException(f_name));
218 // have to evaluate it in case it contains expressions or other variables
220 FeatureValue *return_variable = 0;
224 return_variable = variable_value->evaluate() ;
228 delete return_variable;
229 delete variable_value ;
234 //MESSAGE(cerr, "VariableNode::evaluate() completes");
236 delete variable_value ;
237 return return_variable;
241 CompositeVariableNode::evaluate() const
244 MESSAGE(cerr, "CompositeVariableNode::evaluate():");
247 f_items[0] -> print(cerr);
251 //debug(cerr, int(gCurrentLocalSet));
252 //debug(cerr, int(gParentCompleteSet));
254 const Feature *f = 0;
256 if ( gCurrentLocalSet )
257 f = gCurrentLocalSet->deep_lookup(f_items) ;
259 //debug(cerr, int(f));
261 if (!f && gParentCompleteSet )
262 f = gParentCompleteSet->deep_lookup(f_items);
264 //debug(cerr, int(f));
266 //if ( f == 0 && gRenderer ) {
268 FeatureValue* fv = gAutoNumberFP.evaluate(f_items[0] -> name());
271 throw(CASTBEEXCEPT badEvaluationException());
278 throw(CASTBEEXCEPT badEvaluationException());
281 return f->evaluate();
288 ConstantNode::evaluate() const
290 //return f_value->clone();
291 return f_value->evaluate();
294 extern unsigned g_validation_mode;
297 SgmlAttributeNode::evaluate() const
299 if ( g_validation_mode == true ) {
300 throw(CASTUAEXCEPT undefinedAttributeException(f_name));
303 const Attribute *attr = gCurrentElement->get_attribute(f_name);
306 return new FeatureValueString(attr->value());
308 throw(CASTUAEXCEPT undefinedAttributeException(f_name));
314 // ////////////////////////////////////////////////////////////////////////
316 // ////////////////////////////////////////////////////////////////////////
318 ostream &operator<<(ostream &o, const Expression &e)
323 ostream &operator<< (ostream &o, const TermNode &t)
329 Expression::print(ostream &o) const
331 return o << *f_root ;
335 VariableNode::print(ostream &o) const
341 BinaryOperatorNode::print(ostream &o) const
343 o << "(" << *f_left << ' ';
360 return o << ' ' << *f_right << ')' ;
364 SgmlAttributeNode::print(ostream &o) const
366 return o << '@' << f_name ;
370 ConstantNode::print(ostream &o) const
372 return o << *f_value ;
377 CompositeVariableNode::print(ostream &o) const
379 int length = f_items.entries();
380 for (int i = 0; i < length; i++)
390 // /////////////////////////////////////////////////////////////////////////
392 // /////////////////////////////////////////////////////////////////////////
395 VariableNode::clone() const
397 return new VariableNode(f_name);
401 CompositeVariableNode::clone() const
403 int nitems = f_items.entries();
404 CompositeVariableNode *node = new CompositeVariableNode(nitems);
406 for (int i = 0; i < nitems; i++)
407 node->appendItem(*f_items(i));
413 BinaryOperatorNode::clone() const
415 return new BinaryOperatorNode(f_operator, f_left->clone(), f_right->clone());
419 SgmlAttributeNode::clone() const
421 return new SgmlAttributeNode(f_name);
425 ConstantNode::clone() const
427 return new ConstantNode(f_value->clone());