Disable all code related to libXp
[oweals/cde.git] / cde / programs / dtinfo / DtMmdb / StyleSheet / FeatureDefDictionary.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 // $TOG: FeatureDefDictionary.C /main/4 1998/04/17 11:48:58 mgreess $
24
25
26 #include "StyleSheet/FeatureDefDictionary.h"
27 #include "StyleSheet/Debug.h"
28 #include "StyleSheet/StyleSheetExceptions.h"
29 #include "utility/const.h"
30 #include "utility/funcs.h"
31 #include <iostream>
32 using namespace std;
33
34 featureDefDictionary* g_FeatureDefDictionary = 0;
35
36 extern void report_error_location();
37
38 extern def_list_t* g_def_list;
39 extern FILE *defParserin;
40 extern int defParserparse();
41 istream* g_defParserin = 0;
42
43 unsigned g_validation_mode = false;
44 unsigned g_hasSemanticError = false;
45
46
47 ostream& out_tabs(ostream& out, int tabs) 
48 {
49    for (int i=0; i<tabs; i++)
50       out << "\t";
51
52    return out;
53 }
54
55 TypeValues::TypeValues(char* t, defv_t* dv) : 
56         f_type(t), f_default_values(dv)
57 {
58 }
59
60 TypeValues::~TypeValues()
61 {
62    if ( f_default_values ) {
63       f_default_values -> clearAndDestroy();
64       delete f_default_values;
65    }
66 }
67
68 unsigned int TypeValues::operator==(const TypeValues& def)
69 {
70    return !f_type.compareTo(def.f_type, CC_String::ignoreCase);
71 }
72
73 ostream& operator <<(ostream& out, TypeValues& tvs) 
74 {
75    return tvs.print(out, 0);
76 }
77
78 unsigned TypeValues::check(const FeatureValue* fv)
79 {
80 /*
81 MESSAGE(cerr, "TypeValues::check()");
82 debug(cerr, fv -> type());
83 */
84
85 // type check
86    switch ( fv -> type() ) {
87      case FeatureValue::real:
88      case FeatureValue::integer:
89 //debug(cerr, f_type.data());
90        if ( strcasecmp(f_type.data(), "REAL") == 0 ||
91             strcasecmp(f_type.data(), "INTEGER") == 0 
92        )
93           break;
94        else
95           return false;
96
97      case FeatureValue::string:
98 //debug(cerr, f_type.data());
99        if ( strcasecmp(f_type.data(), "STRING") == 0 ||
100             strcasecmp(f_type.data(), "STRING_PREFIX") == 0 
101        )
102           break;
103        else
104           return false;
105
106      case FeatureValue::symbol:
107      case FeatureValue::expression:
108      case FeatureValue::featureset:
109           return false;
110
111 //debug(cerr, f_type.data());
112      case FeatureValue::dimension:
113        if ( strcasecmp(f_type.data(), "DIMENSION") == 0 ||
114             strcasecmp(f_type.data(), "DIMENSION_PIXEL") == 0 
115        )
116           break;
117        else
118           return false;
119
120      case FeatureValue::array:
121 //debug(cerr, f_type.data());
122        if ( strcasecmp(f_type.data(), "ARRAY") == 0 )
123           break;
124        else
125           return false;
126
127    }
128
129 // value check
130    if ( f_default_values == 0 ) {
131 //MESSAGE(cerr, "check() Passed");
132      return true;
133    }
134
135    defv_iterator_t next(*f_default_values);
136    const char* x, *y; 
137
138    while (++next) {
139
140 /////////////////////////////////////////////////////////////
141 // trap string type as FeatureValueString::operator==() uses
142 // case sensitive comparsion
143 /////////////////////////////////////////////////////////////
144      if ( fv -> type() == FeatureValue::string &&
145           next.key() -> type() == FeatureValue::string ) 
146      {
147         x = *((FeatureValueString*)next.key());
148         y = *(FeatureValueString*)fv;
149
150 //debug(cerr, x);
151 //debug(cerr, y);
152
153         if ( strcasecmp(f_type.data(), "STRING_PREFIX") == 0 ) {
154           if ( strncasecmp(x, y, strlen(x)) == 0 )
155              return true;
156         } else {
157           if ( strcasecmp(x, y) == 0 )
158              return true;
159         }
160
161      } else
162
163      if ( next.key() -> operator==(*fv) == true ) {
164 //MESSAGE(cerr, "check() Passed");
165        return true ;
166      }
167    }
168
169    return false;
170 }
171
172 ostream& TypeValues::print(ostream& out, int tabs) const
173 {
174    out_tabs(out, tabs) << f_type << "\n";
175
176    if ( f_default_values ) {
177       defv_iterator_t NextValue (*f_default_values);
178       while (++NextValue) {
179              out_tabs(out, tabs+1) << *(NextValue.key()) << "\n";
180       }
181    }
182
183    return out;
184 }
185
186 unsigned fhash(const FeatureDef& key)
187 {
188    return key.name() -> hash();
189 }
190
191 FeatureDef::FeatureDef(const char* name) : f_name(name)
192 {
193 }
194
195 FeatureDef::~FeatureDef()
196 {
197 }
198
199 ostream& operator << (ostream& out, FeatureDef& def)
200 {
201    return def.print(out, 0);
202 }
203
204 unsigned int FeatureDef::operator==(const FeatureDef& def)
205 {
206 //debug(cerr, f_name);
207 //debug(cerr, def.f_name);
208 //   unsigned ok = ! f_name.compareTo(def.f_name, CC_String::ignoreCase);
209 //debug(cerr, ok);
210 //return ok;
211
212    return !f_name.compareTo(def.f_name, CC_String::ignoreCase);
213 }
214
215 FeatureDefComposite::FeatureDefComposite(const char* name, def_list_t* dl) :
216    FeatureDef(name), f_components(dl)
217 {
218 }
219
220 FeatureDefComposite::~FeatureDefComposite()
221 {
222    if ( f_components ) {
223       f_components -> clearAndDestroy();
224       delete f_components;
225    }
226 }
227
228 CC_Boolean compareFunc(FeatureDef* fd, void* nm)
229 {
230    if ( strcasecmp( fd -> name() -> data(), (char*)nm ) == 0 )
231       return TRUE;
232    else
233       return FALSE;
234 }
235
236 // return true:
237 //    fv confirms to the spec of a component of this def.
238 // return false:
239 //    otherwise
240 unsigned FeatureDefComposite::checkContent(const Feature* fv) const
241 {
242 /*
243    const FeatureDef* def = getComponentDef((fv->name()).name());
244
245    if ( def == 0 )
246      return false;
247
248    if ( def -> type() != FeatureDef::PRIMITIVE )
249      return false;
250
251    return ((FeatureDefPrimitive*)def) -> checkContent(fv);
252 */
253    return true;
254 }
255
256 const FeatureDef* FeatureDefComposite::getComponentDef(const char* nm) const
257 {
258    if ( f_components == 0 )
259       return 0;
260    else {
261       FeatureDef* def = f_components -> find(compareFunc, (void*)nm);
262     
263       if ( def )
264          return def;
265       else {
266          if ( f_components -> first() -> type() == WILDCARD )
267             return f_components -> first();
268          else
269             return 0;
270       }
271 //return f_components -> find(compareFunc, "*");
272    }
273 }
274
275 ostream& FeatureDefComposite::print(ostream& out, int tabs) const
276 {
277     out_tabs(out, tabs) << f_name << "\n";
278
279     if ( f_components ) {
280        def_list_iterator_t NextComponent(*f_components);
281        while (++NextComponent) {
282                NextComponent.key() -> print(out, tabs+1) << "\n";
283        }
284     }
285    return out;
286 }
287
288 FeatureDefPrimitive::FeatureDefPrimitive(const char* name, type_values_list_t* tvl) :
289    FeatureDef(name), f_typeValuesList(tvl)
290 {
291 }
292
293 FeatureDefPrimitive::~FeatureDefPrimitive()
294 {
295    if ( f_typeValuesList ) {
296       f_typeValuesList -> clearAndDestroy();
297       delete f_typeValuesList;
298    }
299 }
300
301 unsigned FeatureDefPrimitive::checkContent(const Feature* f) const
302 {
303 /*
304 MESSAGE(cerr, "FeatureDefPrimitive::checkContent");
305 f -> print(cerr);
306 MESSAGE(cerr, "");
307 debug(cerr, *(this -> name()));
308 MESSAGE(cerr, "");
309 */
310
311    if ( f_typeValuesList == 0 ) {
312      report_error_location();
313      cerr << "No type definition.\n";
314      return false;
315    }
316
317    FeatureValue * fv = 0;
318    mtry {
319      fv = f -> evaluate();
320    }
321    mcatch (undefinedAttributeException&, e) {
322       return true;
323    }
324
325    mcatch (undefinedVariableException&, e) {
326       report_error_location();
327       cerr << "Undefined variable error.\n";
328       return false;
329    }
330
331 /*
332    mcatch (badCastException&, e) {
333       report_error_location();
334       cerr << "Evaluating expression error.\n";
335       return false;
336    }
337
338    mcatch (badEvaluationException&, e) {
339       report_error_location();
340       cerr << "Evaluating expression error.\n";
341       return false;
342    }
343 */
344
345    mcatch_any() {
346       //report_error_location();
347       //cerr << "There might be an error in the expression.\n";
348       return true;
349    }
350    end_try;
351    
352 /*
353 debug(cerr, int(fv));
354 fv -> print(cerr);
355 MESSAGE(cerr, "");
356 */
357
358    if ( fv == 0 ) {
359       report_error_location();
360       cerr << "Error in evaluating an expression.\n";
361       return false;
362    }
363
364    type_values_list_iterator_t next(*f_typeValuesList);
365
366    while ( ++ next ) {
367       if ( next.key() -> check(fv) == true ) {
368         delete fv;
369         return true ;
370       }
371    }
372
373    delete fv;
374    report_error_location();
375    cerr << form("Unmatched feature type or illegal feature value: %s.\n", 
376                 (f -> name()).name()
377                );
378    return false;
379 }
380
381 ostream& FeatureDefPrimitive::print(ostream& out, int tabs) const
382 {
383     out_tabs(out, tabs) << f_name << "\n";
384
385     if ( f_typeValuesList ) {
386        type_values_list_iterator_t NextValue (*f_typeValuesList);
387        while (++NextValue) {
388                NextValue.key() -> print(out, tabs+1) << "\n";
389        }
390     }
391     return out;
392 }
393
394 unsigned FeatureDefReference::checkContent(const Feature* fv) const
395 {
396    return false;
397 }
398
399 ostream& FeatureDefReference::print(ostream& out, int tabs) const
400 {
401     out_tabs(out, tabs) << f_name << "\n";
402     return out;
403 }
404
405 unsigned FeatureDefWildCard::checkContent(const Feature* fv) const
406 {
407    return true;
408 }
409
410 ostream& FeatureDefWildCard::print(ostream& out, int tabs) const
411 {
412     out_tabs(out, tabs) << f_name << "\n";
413     return out;
414 }
415
416 featureDefDictionary::featureDefDictionary() : f_def_list(0)
417 {
418 }
419
420 featureDefDictionary::~featureDefDictionary()
421 {
422    if ( f_def_list ) {
423      f_def_list -> clearAndDestroy();
424      delete f_def_list;
425    }
426 }
427         
428 void 
429 featureDefDictionary::addFeatureDefs(def_list_t* fdefs)
430 {
431    f_def_list = fdefs;
432
433    if ( f_def_list == 0 )
434       throw(CASTEXCEPT Exception());
435 }
436     
437 const FeatureDef* 
438 featureDefDictionary::getDef(const char* nm)
439 {
440 //debug(cerr, nm);
441
442    FeatureDefReference key((char*)nm);
443    return f_def_list -> find(&key);
444
445 /*
446  FeatureDef* def = 0;
447  def = f_def_list -> find(&key);
448
449 debug(cerr, int(def));
450    return def;
451 */
452 }
453
454 const FeatureDef* 
455 featureDefDictionary::getDef(const Feature* f)
456 {
457    return getDef((f -> name()).name());
458 }
459
460 unsigned
461 featureDefDictionary::checkSemantics(const FeatureSet* fs)
462 {
463 /*
464 MESSAGE(cerr, "check feature set:");
465 fs -> print(cerr);
466 MESSAGE(cerr, "");
467 */
468
469   const FeatureDef* def = 0;
470   const Feature *f = 0;
471
472   CC_TPtrSlistIterator<Feature> next(*(CC_TPtrSlist<Feature>*)fs);
473   while (++next) {
474      f = next.key();
475      def = getDef(f);
476
477      if ( def == 0 ) {
478         report_error_location();
479         cerr << form("Unknown feature name %s.\n", 
480                      ((next.key()) -> name()).name());
481         return false;
482      }
483
484      if ( _checkSemantics(f, def) == false )
485        return false;
486   }
487   return true;
488 }
489
490 unsigned
491 featureDefDictionary::_checkSemantics(const Feature* f, const FeatureDef* def)
492 {
493    const FeatureSet *featureset = 0;
494    const Feature *child_f= 0;
495
496 /*
497 MESSAGE(cerr, "_checkSemantics");
498 f -> print(cerr);
499 MESSAGE(cerr, "");
500 def -> print(cerr, 0);
501 MESSAGE(cerr, "");
502 */
503
504         
505    const FeatureDef* child_def = 0;
506
507    if ( def -> checkContent(f) == false ) {
508       return false;
509    }
510
511    if (f -> value()->type() == FeatureValue::featureset &&
512        def -> type() == FeatureDef::COMPOSITE )
513    {
514 //MESSAGE(cerr, "it is a feature set");
515
516
517       featureset = 
518         ((const FeatureValueFeatureSet *)(f -> value()))->value();
519
520       CC_TPtrSlistIterator<Feature> next(*(CC_TPtrSlist<Feature>*)featureset);
521
522       const char* nm;
523
524       while ( ++ next ) {
525
526         nm = ((next.key()) -> name()).name();
527
528 /*
529 debug(cerr, nm);
530 report_error_location();
531 */
532
533         child_def = ((FeatureDefComposite*)def) -> getComponentDef(nm);
534
535 //debug(cerr, int(child_def));
536         if ( child_def == 0 ) {
537           report_error_location();
538           cerr << form("%s is a undefined feature.\n", nm);
539           return false;
540         }
541
542         switch ( child_def -> type() ) {
543           case FeatureDef::REFERENCE:
544            child_def = getDef(child_def -> name() -> data());
545            break;
546           case FeatureDef::WILDCARD:
547            child_def = getDef(nm);
548            break;
549           default:
550            break;
551         }
552
553         child_f = next.key();
554
555         if ( _checkSemantics(child_f, child_def) == false )
556            return false;
557
558       }
559
560       return true;
561    } 
562    return true;
563 }
564
565 istream& operator >>(istream& in, featureDefDictionary& dict)
566 {
567    g_defParserin = &in;
568
569    int ok = defParserparse();
570    if ( ok != 0 ) {
571       MESSAGE(cerr, "bad feature definition file");
572       throw(CASTEXCEPT Exception());
573    }
574
575    dict.addFeatureDefs(g_def_list);
576
577    return in;
578 }
579
580 ostream& operator <<(ostream& out, featureDefDictionary& dict)
581 {
582    def_list_iterator_t Next(*dict.f_def_list);
583
584    while (++Next) {
585 //debug(cerr, int(Next.key()));
586       out << *Next.key() << "\n"; 
587    }
588    return out;
589 }