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 // $XConsortium: FeatureSet.cc /main/5 1996/08/05 16:18:55 cde-hal $
27 #include "FeatureValue.h"
28 #include "StyleSheetExceptions.h"
31 unsigned int FeatureSet::f_print_indent_level = 0 ;
33 ostream &operator << (ostream &o, const FeatureSet &f)
38 FeatureSet::~FeatureSet()
40 clearAndDestroy(); // clean up memory
43 FeatureSet::FeatureSet()
47 FeatureSet::FeatureSet(const FeatureSet &orig_set)
50 CC_TPtrSlistIterator<Feature> next(*(CC_TPtrSlist<Feature>*) &orig_set) ;
52 // make a copy of each item and add it to our list
54 append(new Feature(*next.key()));
59 FeatureSet::evaluate() const
61 // I do not yet understand how this evaluate is working well. - TK
63 fprintf(stderr, "(DEBUG) FeatureSet::evaluate() called.\n");
65 return evaluate(new FeatureSet);
69 FeatureSet::evaluate(FeatureSet *result_set) const
72 CC_TPtrSlistIterator<Feature> next(*(FeatureSet*)this);
74 // cause each feature to evaluate itself
80 value = next.key()->evaluate();
81 result_set->append(new Feature(next.key()->name(),
87 mcatch_noarg(badEvaluationException)
90 /* do nothing...we just ignore any that will not evaluate */
98 FeatureSet::FeatureSet(const FeatureSet &base,
99 const FeatureSet &mixin)
101 Feature dummy = Feature(gSymTab->intern("FAMILY"),0);
102 int contains_family = mixin.contains(&dummy);
104 // first duplicate the baseline
105 CC_TPtrSlistIterator<Feature> base_i(*(CC_TPtrSlist<Feature>*)&base) ;
107 // make a copy of each item and add it to our list
109 if (! (contains_family &&
110 base_i.key()->name() == gSymTab->intern("FAMILY")))
111 append(new Feature(*base_i.key()));
114 // now merge in mixin
116 CC_TPtrSlistIterator<Feature> next(*(CC_TPtrSlist<Feature>*)&mixin);
120 if (next.key()->name() == gSymTab->intern("FAMILY"))
121 append(new Feature(*next.key()));
123 Feature* mfeature = 0;
124 mfeature = find(next.key());
126 cout << "Merging: \n" << *next.key() << endl << "into:" << endl;
128 cout << *mfeature << endl;
130 cout << "(nil)" << endl;
133 mfeature->merge(*next.key()); // merge it if already exists
135 append(new Feature(*next.key())); // else add it if not there
141 FeatureSet::print(ostream &o) const
143 // cast to non-const to get iterator
144 CC_TPtrSlistIterator<Feature> next(*(CC_TPtrSlist<Feature>*)this);
147 for (i = 0 ; i < f_print_indent_level; i++)
152 f_print_indent_level++;
156 for (unsigned int i = 0 ; i < f_print_indent_level; i++)
158 o << *next.key() << endl ;
161 --f_print_indent_level;
162 for (i = 0 ; i < f_print_indent_level ; i++)
171 FeatureSet::add(Feature *f)
178 FeatureSet::operator==(const FeatureSet &fs) const
184 FeatureSet::lookup(const Symbol *symbol) const
186 return lookup(*symbol);
190 FeatureSet::lookup(const Symbol &name) const
192 Feature tmp(name, 0);
198 FeatureSet::lookup(const char *name) const
200 Feature tmp(gSymTab->intern(name),0);
205 FeatureSet::deep_lookup(const char *first_name ...) const
207 const Feature *feature = lookup(first_name);
212 const FeatureSet *featureset = 0;
215 va_start(ap, first_name);
220 const char *p = va_arg(ap, char*);
224 if (feature->value()->type() != FeatureValue::featureset)
230 featureset = ((const FeatureValueFeatureSet *)feature->value())->value();
232 feature = featureset->lookup(p);
245 FeatureSet::deep_lookup(const Symbol *first_name ...) const
247 const Feature *feature = lookup(*first_name);
252 const FeatureSet *featureset = 0;
255 va_start(ap, first_name);
260 const Symbol *sym = va_arg(ap, const Symbol *);
264 if (feature->value()->type() != FeatureValue::featureset)
270 featureset = ((const FeatureValueFeatureSet *)feature->value())->value();
272 feature = featureset->lookup(*sym);
285 FeatureSet::deep_lookup(const dlist_array<Symbol> &vec) const
287 unsigned int index = 0;
288 const Feature *feature = lookup(*vec[index++]);
292 const FeatureSet *set = 0;
294 unsigned int entries = vec.entries();
295 for (; index < entries ; index++ )
297 if (feature->value()->type() != FeatureValue::featureset)
300 set = ((const FeatureValueFeatureSet *)feature->value())->value();
301 feature = set->lookup(*vec[index++]);
310 FeatureSet::removeFeature(const char *first_name ...)
312 const Feature *feature = lookup(first_name);
317 FeatureSet *featureset = this;
320 va_start(ap, first_name);
325 const char *p = va_arg(ap, char*);
329 if (feature->value()->type() != FeatureValue::featureset)
335 featureset = (FeatureSet*)
336 (((const FeatureValueFeatureSet *)feature->value())->value());
338 feature = featureset->lookup(p);
348 delete (featureset -> remove((Feature *)feature));