1 // $TOG: FeatureDefDictionary.C /main/4 1998/04/17 11:48:58 mgreess $
4 #include "StyleSheet/FeatureDefDictionary.h"
5 #include "StyleSheet/Debug.h"
6 #include "StyleSheet/StyleSheetExceptions.h"
7 #include "utility/const.h"
8 #include "utility/funcs.h"
11 featureDefDictionary* g_FeatureDefDictionary = 0;
13 extern void report_error_location();
15 extern def_list_t* g_def_list;
16 extern FILE *defParserin;
17 extern int defParserparse();
18 istream* g_defParserin = 0;
20 unsigned g_validation_mode = false;
21 unsigned g_hasSemanticError = false;
24 ostream& out_tabs(ostream& out, int tabs)
26 for (int i=0; i<tabs; i++)
32 TypeValues::TypeValues(char* t, defv_t* dv) :
33 f_type(t), f_default_values(dv)
37 TypeValues::~TypeValues()
39 if ( f_default_values ) {
40 f_default_values -> clearAndDestroy();
41 delete f_default_values;
45 unsigned int TypeValues::operator==(const TypeValues& def)
47 return !f_type.compareTo(def.f_type, CC_String::ignoreCase);
50 ostream& operator <<(ostream& out, TypeValues& tvs)
52 return tvs.print(out, 0);
55 unsigned TypeValues::check(const FeatureValue* fv)
58 MESSAGE(cerr, "TypeValues::check()");
59 debug(cerr, fv -> type());
63 switch ( fv -> type() ) {
64 case FeatureValue::real:
65 case FeatureValue::integer:
66 //debug(cerr, f_type.data());
67 if ( strcasecmp(f_type.data(), "REAL") == 0 ||
68 strcasecmp(f_type.data(), "INTEGER") == 0
74 case FeatureValue::string:
75 //debug(cerr, f_type.data());
76 if ( strcasecmp(f_type.data(), "STRING") == 0 ||
77 strcasecmp(f_type.data(), "STRING_PREFIX") == 0
83 case FeatureValue::symbol:
84 case FeatureValue::expression:
85 case FeatureValue::featureset:
88 //debug(cerr, f_type.data());
89 case FeatureValue::dimension:
90 if ( strcasecmp(f_type.data(), "DIMENSION") == 0 ||
91 strcasecmp(f_type.data(), "DIMENSION_PIXEL") == 0
97 case FeatureValue::array:
98 //debug(cerr, f_type.data());
99 if ( strcasecmp(f_type.data(), "ARRAY") == 0 )
107 if ( f_default_values == 0 ) {
108 //MESSAGE(cerr, "check() Passed");
112 defv_iterator_t next(*f_default_values);
117 /////////////////////////////////////////////////////////////
118 // trap string type as FeatureValueString::operator==() uses
119 // case sensitive comparsion
120 /////////////////////////////////////////////////////////////
121 if ( fv -> type() == FeatureValue::string &&
122 next.key() -> type() == FeatureValue::string )
124 x = *((FeatureValueString*)next.key());
125 y = *(FeatureValueString*)fv;
130 if ( strcasecmp(f_type.data(), "STRING_PREFIX") == 0 ) {
131 if ( strncasecmp(x, y, strlen(x)) == 0 )
134 if ( strcasecmp(x, y) == 0 )
140 if ( next.key() -> operator==(*fv) == true ) {
141 //MESSAGE(cerr, "check() Passed");
149 ostream& TypeValues::print(ostream& out, int tabs) const
151 out_tabs(out, tabs) << f_type << "\n";
153 if ( f_default_values ) {
154 defv_iterator_t NextValue (*f_default_values);
155 while (++NextValue) {
156 out_tabs(out, tabs+1) << *(NextValue.key()) << "\n";
163 unsigned hash(const FeatureDef& key)
165 return key.name() -> hash();
168 FeatureDef::FeatureDef(const char* name) : f_name(name)
172 FeatureDef::~FeatureDef()
176 ostream& operator << (ostream& out, FeatureDef& def)
178 return def.print(out, 0);
181 unsigned int FeatureDef::operator==(const FeatureDef& def)
183 //debug(cerr, f_name);
184 //debug(cerr, def.f_name);
185 // unsigned ok = ! f_name.compareTo(def.f_name, CC_String::ignoreCase);
189 return !f_name.compareTo(def.f_name, CC_String::ignoreCase);
192 FeatureDefComposite::FeatureDefComposite(const char* name, def_list_t* dl) :
193 FeatureDef(name), f_components(dl)
197 FeatureDefComposite::~FeatureDefComposite()
199 if ( f_components ) {
200 f_components -> clearAndDestroy();
205 CC_Boolean compareFunc(FeatureDef* fd, void* nm)
207 if ( strcasecmp( fd -> name() -> data(), (char*)nm ) == 0 )
214 // fv confirms to the spec of a component of this def.
217 unsigned FeatureDefComposite::checkContent(const Feature* fv) const
220 const FeatureDef* def = getComponentDef((fv->name()).name());
225 if ( def -> type() != FeatureDef::PRIMITIVE )
228 return ((FeatureDefPrimitive*)def) -> checkContent(fv);
233 const FeatureDef* FeatureDefComposite::getComponentDef(const char* nm) const
235 if ( f_components == 0 )
238 FeatureDef* def = f_components -> find(compareFunc, (void*)nm);
243 if ( f_components -> first() -> type() == WILDCARD )
244 return f_components -> first();
248 //return f_components -> find(compareFunc, "*");
252 ostream& FeatureDefComposite::print(ostream& out, int tabs) const
254 out_tabs(out, tabs) << f_name << "\n";
256 if ( f_components ) {
257 def_list_iterator_t NextComponent(*f_components);
258 while (++NextComponent) {
259 NextComponent.key() -> print(out, tabs+1) << "\n";
265 FeatureDefPrimitive::FeatureDefPrimitive(const char* name, type_values_list_t* tvl) :
266 FeatureDef(name), f_typeValuesList(tvl)
270 FeatureDefPrimitive::~FeatureDefPrimitive()
272 if ( f_typeValuesList ) {
273 f_typeValuesList -> clearAndDestroy();
274 delete f_typeValuesList;
278 unsigned FeatureDefPrimitive::checkContent(const Feature* f) const
281 MESSAGE(cerr, "FeatureDefPrimitive::checkContent");
284 debug(cerr, *(this -> name()));
288 if ( f_typeValuesList == 0 ) {
289 report_error_location();
290 cerr << "No type definition.\n";
294 FeatureValue * fv = 0;
296 fv = f -> evaluate();
298 catch (undefinedAttributeException&, e) {
302 catch (undefinedVariableException&, e) {
303 report_error_location();
304 cerr << "Undefined variable error.\n";
309 catch (badCastException&, e) {
310 report_error_location();
311 cerr << "Evaluating expression error.\n";
315 catch (badEvaluationException&, e) {
316 report_error_location();
317 cerr << "Evaluating expression error.\n";
323 //report_error_location();
324 //cerr << "There might be an error in the expression.\n";
330 debug(cerr, int(fv));
336 report_error_location();
337 cerr << "Error in evaluating an expression.\n";
341 type_values_list_iterator_t next(*f_typeValuesList);
344 if ( next.key() -> check(fv) == true ) {
351 report_error_location();
352 cerr << form("Unmatched feature type or illegal feature value: %s.\n",
358 ostream& FeatureDefPrimitive::print(ostream& out, int tabs) const
360 out_tabs(out, tabs) << f_name << "\n";
362 if ( f_typeValuesList ) {
363 type_values_list_iterator_t NextValue (*f_typeValuesList);
364 while (++NextValue) {
365 NextValue.key() -> print(out, tabs+1) << "\n";
371 unsigned FeatureDefReference::checkContent(const Feature* fv) const
376 ostream& FeatureDefReference::print(ostream& out, int tabs) const
378 out_tabs(out, tabs) << f_name << "\n";
382 unsigned FeatureDefWildCard::checkContent(const Feature* fv) const
387 ostream& FeatureDefWildCard::print(ostream& out, int tabs) const
389 out_tabs(out, tabs) << f_name << "\n";
393 featureDefDictionary::featureDefDictionary() : f_def_list(0)
397 featureDefDictionary::~featureDefDictionary()
400 f_def_list -> clearAndDestroy();
406 featureDefDictionary::addFeatureDefs(def_list_t* fdefs)
410 if ( f_def_list == 0 )
411 throw(CASTEXCEPT Exception());
415 featureDefDictionary::getDef(const char* nm)
419 FeatureDefReference key((char*)nm);
420 return f_def_list -> find(&key);
424 def = f_def_list -> find(&key);
426 debug(cerr, int(def));
432 featureDefDictionary::getDef(const Feature* f)
434 return getDef((f -> name()).name());
438 featureDefDictionary::checkSemantics(const FeatureSet* fs)
441 MESSAGE(cerr, "check feature set:");
446 const FeatureDef* def = 0;
447 const Feature *f = 0;
449 CC_TPtrSlistIterator<Feature> next(*(CC_TPtrSlist<Feature>*)fs);
455 report_error_location();
456 cerr << form("Unknown feature name %s.\n",
457 ((next.key()) -> name()).name());
461 if ( _checkSemantics(f, def) == false )
468 featureDefDictionary::_checkSemantics(const Feature* f, const FeatureDef* def)
470 const FeatureSet *featureset = 0;
471 const Feature *child_f= 0;
474 MESSAGE(cerr, "_checkSemantics");
477 def -> print(cerr, 0);
482 const FeatureDef* child_def = 0;
484 if ( def -> checkContent(f) == false ) {
488 if (f -> value()->type() == FeatureValue::featureset &&
489 def -> type() == FeatureDef::COMPOSITE )
491 //MESSAGE(cerr, "it is a feature set");
495 ((const FeatureValueFeatureSet *)(f -> value()))->value();
497 CC_TPtrSlistIterator<Feature> next(*(CC_TPtrSlist<Feature>*)featureset);
503 nm = ((next.key()) -> name()).name();
507 report_error_location();
510 child_def = ((FeatureDefComposite*)def) -> getComponentDef(nm);
512 //debug(cerr, int(child_def));
513 if ( child_def == 0 ) {
514 report_error_location();
515 cerr << form("%s is a undefined feature.\n", nm);
519 switch ( child_def -> type() ) {
520 case FeatureDef::REFERENCE:
521 child_def = getDef(child_def -> name() -> data());
523 case FeatureDef::WILDCARD:
524 child_def = getDef(nm);
530 child_f = next.key();
532 if ( _checkSemantics(child_f, child_def) == false )
542 istream& operator >>(istream& in, featureDefDictionary& dict)
546 int ok = defParserparse();
548 MESSAGE(cerr, "bad feature definition file");
549 throw(CASTEXCEPT Exception());
552 dict.addFeatureDefs(g_def_list);
557 ostream& operator <<(ostream& out, featureDefDictionary& dict)
559 def_list_iterator_t Next(*dict.f_def_list);
562 //debug(cerr, int(Next.key()));
563 out << *Next.key() << "\n";