Disable all code related to libXp
[oweals/cde.git] / cde / programs / dtinfo / DtMmdb / StyleSheet / FeatureSet.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 // $XConsortium: FeatureSet.cc /main/5 1996/08/05 16:18:55 cde-hal $
24 #include <stdarg.h>
25 #include <assert.h>
26 #include "Feature.h"
27 #include "FeatureValue.h"
28 #include "StyleSheetExceptions.h"
29 #include "Debug.h"
30
31 unsigned int FeatureSet::f_print_indent_level = 0 ;
32
33 ostream &operator << (ostream &o, const FeatureSet &f)
34 {
35   return f.print(o);
36 }
37
38 FeatureSet::~FeatureSet()
39 {
40   clearAndDestroy();            // clean up memory 
41 }
42
43 FeatureSet::FeatureSet()
44 {
45 }
46
47 FeatureSet::FeatureSet(const FeatureSet &orig_set)
48 {
49   // cast to non const 
50   CC_TPtrSlistIterator<Feature> next(*(CC_TPtrSlist<Feature>*) &orig_set) ;
51
52   // make a copy of each item and add it to our list 
53   while (++next)
54     append(new Feature(*next.key()));
55
56 }
57
58 FeatureSet *
59 FeatureSet::evaluate() const
60 {
61   // I do not yet understand how this evaluate is working well. - TK
62 #ifdef FS_EVAL_DEBUG
63   fprintf(stderr, "(DEBUG) FeatureSet::evaluate() called.\n");
64 #endif
65   return evaluate(new FeatureSet);
66 }
67
68 FeatureSet *
69 FeatureSet::evaluate(FeatureSet *result_set) const
70 {
71   
72   CC_TPtrSlistIterator<Feature> next(*(FeatureSet*)this);
73   
74   // cause each feature to evaluate itself 
75   while(++next)
76     {
77       FeatureValue *value ;
78       mtry
79         {
80           value = next.key()->evaluate();
81           result_set->append(new Feature(next.key()->name(),
82                                          value));
83         }
84 #ifdef UXPDS
85       mcatch_any()
86 #else
87       mcatch_noarg(badEvaluationException)
88 #endif
89         {
90           /* do nothing...we just ignore any that will not evaluate */
91         }
92       end_try;
93     }
94
95   return result_set ;
96 }
97
98 FeatureSet::FeatureSet(const FeatureSet &base,
99                        const FeatureSet &mixin)
100 {
101   Feature dummy = Feature(gSymTab->intern("FAMILY"),0);
102   int contains_family = mixin.contains(&dummy);
103
104   // first duplicate the baseline
105   CC_TPtrSlistIterator<Feature> base_i(*(CC_TPtrSlist<Feature>*)&base) ;
106
107   // make a copy of each item and add it to our list 
108   while (++base_i) {
109       if (! (contains_family &&
110                 base_i.key()->name() == gSymTab->intern("FAMILY")))
111         append(new Feature(*base_i.key()));
112   }
113
114   // now merge in mixin
115
116   CC_TPtrSlistIterator<Feature> next(*(CC_TPtrSlist<Feature>*)&mixin);
117   
118   while (++next)
119     {
120       if (next.key()->name() == gSymTab->intern("FAMILY"))
121         append(new Feature(*next.key()));
122       else {
123         Feature* mfeature = 0;
124         mfeature = find(next.key());
125 #if 0
126         cout << "Merging: \n" <<  *next.key() << endl << "into:" << endl;
127         if (mfeature)
128           cout << *mfeature << endl;
129         else
130           cout << "(nil)" << endl;
131 #endif
132         if (mfeature)
133           mfeature->merge(*next.key()); // merge it if already exists
134         else
135           append(new Feature(*next.key())); // else add it if not there
136       }
137     }
138 }
139
140 ostream &
141 FeatureSet::print(ostream &o) const
142 {
143   // cast to non-const to get iterator 
144   CC_TPtrSlistIterator<Feature> next(*(CC_TPtrSlist<Feature>*)this);
145   
146   unsigned int i;
147   for (i = 0 ; i < f_print_indent_level; i++)
148     o << "  " ;
149
150   o << "{" << endl;
151   
152   f_print_indent_level++;
153
154   while (++next)
155     {
156       for (unsigned int i = 0 ; i < f_print_indent_level; i++)
157         o << "  " ;
158       o << *next.key() << endl ;
159     }
160   
161   --f_print_indent_level;
162   for (i = 0 ; i < f_print_indent_level ; i++)
163     o << "  " ;
164
165   o << "}" << endl;
166
167   return o;
168 }
169
170 void
171 FeatureSet::add(Feature *f)
172 {
173   append(f);
174 }
175
176
177 unsigned int
178 FeatureSet::operator==(const FeatureSet &fs) const
179 {
180   return &fs == this ;
181 }
182
183 const Feature*
184 FeatureSet::lookup(const Symbol *symbol) const
185 {
186   return lookup(*symbol);
187 }
188
189 const Feature *
190 FeatureSet::lookup(const Symbol &name) const
191 {
192   Feature tmp(name, 0);
193   return find(&tmp);
194 }
195
196
197 const Feature *
198 FeatureSet::lookup(const char *name) const
199 {
200   Feature tmp(gSymTab->intern(name),0);
201   return find(&tmp);
202 }
203
204 const Feature *
205 FeatureSet::deep_lookup(const char *first_name ...) const
206 {
207   const Feature *feature = lookup(first_name);
208
209   if (!feature)
210     return 0; 
211
212   const FeatureSet *featureset = 0;
213   
214   va_list ap;
215   va_start(ap, first_name);
216
217
218   for (;;)
219     {
220       const char *p = va_arg(ap, char*);
221       if (p == 0)
222         break;
223
224       if (feature->value()->type() != FeatureValue::featureset)
225         {
226           va_end(ap);
227           return 0 ;
228         }
229
230       featureset = ((const FeatureValueFeatureSet *)feature->value())->value();
231
232       feature = featureset->lookup(p);
233
234       if (!feature)
235         {
236           va_end(ap);
237           return 0;
238         }
239     }
240   va_end(ap);
241   return feature ;
242 }
243
244 const Feature *
245 FeatureSet::deep_lookup(const Symbol *first_name ...) const
246 {
247   const Feature *feature = lookup(*first_name);
248
249   if (!feature)
250     return 0; 
251
252   const FeatureSet *featureset = 0;
253   
254   va_list ap;
255   va_start(ap, first_name);
256
257
258   for (;;)
259     {
260       const Symbol *sym = va_arg(ap, const Symbol *);
261       if (sym == 0)
262         break;
263
264       if (feature->value()->type() != FeatureValue::featureset)
265         {
266           va_end(ap);
267           return 0 ;
268         }
269
270       featureset = ((const FeatureValueFeatureSet *)feature->value())->value();
271
272       feature = featureset->lookup(*sym);
273
274       if (!feature)
275         {
276           va_end(ap);
277           return 0;
278         }
279     }
280   va_end(ap);
281   return feature ;
282 }
283
284 const Feature *
285 FeatureSet::deep_lookup(const dlist_array<Symbol> &vec) const
286 {
287   unsigned int index = 0;
288   const Feature *feature = lookup(*vec[index++]);
289   if (!feature)
290     return 0;
291
292   const FeatureSet *set = 0;
293
294   unsigned int entries = vec.entries();
295   for (; index < entries ; index++ )
296     {
297       if (feature->value()->type() != FeatureValue::featureset)
298         return 0 ;
299       
300       set = ((const FeatureValueFeatureSet *)feature->value())->value();
301       feature = set->lookup(*vec[index++]);
302       if (!feature)
303         return 0 ;
304     }
305   return feature ;
306 }
307
308
309 void
310 FeatureSet::removeFeature(const char *first_name ...) 
311 {
312   const Feature *feature = lookup(first_name);
313
314   if (!feature)
315     return ; 
316
317   FeatureSet *featureset = this;
318   
319   va_list ap;
320   va_start(ap, first_name);
321
322
323   for (;;)
324     {
325       const char *p = va_arg(ap, char*);
326       if (p == 0)
327         break;
328
329       if (feature->value()->type() != FeatureValue::featureset)
330         {
331           va_end(ap);
332           return ;
333         }
334
335       featureset = (FeatureSet*)
336         (((const FeatureValueFeatureSet *)feature->value())->value());
337
338       feature = featureset->lookup(p);
339
340       if (!feature)
341         {
342           va_end(ap);
343           return ;
344         }
345     }
346   va_end(ap);
347
348   delete (featureset -> remove((Feature *)feature));
349 }