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: FeatureDefDictionary.C /main/4 1998/04/17 11:48:58 mgreess $
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"
34 featureDefDictionary* g_FeatureDefDictionary = 0;
36 extern void report_error_location();
38 extern def_list_t* g_def_list;
39 extern FILE *defParserin;
40 extern int defParserparse();
41 istream* g_defParserin = 0;
43 unsigned g_validation_mode = false;
44 unsigned g_hasSemanticError = false;
47 ostream& out_tabs(ostream& out, int tabs)
49 for (int i=0; i<tabs; i++)
55 TypeValues::TypeValues(char* t, defv_t* dv) :
56 f_type(t), f_default_values(dv)
60 TypeValues::~TypeValues()
62 if ( f_default_values ) {
63 f_default_values -> clearAndDestroy();
64 delete f_default_values;
68 unsigned int TypeValues::operator==(const TypeValues& def)
70 return !f_type.compareTo(def.f_type, CC_String::ignoreCase);
73 ostream& operator <<(ostream& out, TypeValues& tvs)
75 return tvs.print(out, 0);
78 unsigned TypeValues::check(const FeatureValue* fv)
81 MESSAGE(cerr, "TypeValues::check()");
82 debug(cerr, fv -> type());
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
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
106 case FeatureValue::symbol:
107 case FeatureValue::expression:
108 case FeatureValue::featureset:
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
120 case FeatureValue::array:
121 //debug(cerr, f_type.data());
122 if ( strcasecmp(f_type.data(), "ARRAY") == 0 )
130 if ( f_default_values == 0 ) {
131 //MESSAGE(cerr, "check() Passed");
135 defv_iterator_t next(*f_default_values);
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 )
147 x = *((FeatureValueString*)next.key());
148 y = *(FeatureValueString*)fv;
153 if ( strcasecmp(f_type.data(), "STRING_PREFIX") == 0 ) {
154 if ( strncasecmp(x, y, strlen(x)) == 0 )
157 if ( strcasecmp(x, y) == 0 )
163 if ( next.key() -> operator==(*fv) == true ) {
164 //MESSAGE(cerr, "check() Passed");
172 ostream& TypeValues::print(ostream& out, int tabs) const
174 out_tabs(out, tabs) << f_type << "\n";
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";
186 unsigned fhash(const FeatureDef& key)
188 return key.name() -> hash();
191 FeatureDef::FeatureDef(const char* name) : f_name(name)
195 FeatureDef::~FeatureDef()
199 ostream& operator << (ostream& out, FeatureDef& def)
201 return def.print(out, 0);
204 unsigned int FeatureDef::operator==(const FeatureDef& def)
206 //debug(cerr, f_name);
207 //debug(cerr, def.f_name);
208 // unsigned ok = ! f_name.compareTo(def.f_name, CC_String::ignoreCase);
212 return !f_name.compareTo(def.f_name, CC_String::ignoreCase);
215 FeatureDefComposite::FeatureDefComposite(const char* name, def_list_t* dl) :
216 FeatureDef(name), f_components(dl)
220 FeatureDefComposite::~FeatureDefComposite()
222 if ( f_components ) {
223 f_components -> clearAndDestroy();
228 CC_Boolean compareFunc(FeatureDef* fd, void* nm)
230 if ( strcasecmp( fd -> name() -> data(), (char*)nm ) == 0 )
237 // fv confirms to the spec of a component of this def.
240 unsigned FeatureDefComposite::checkContent(const Feature* fv) const
243 const FeatureDef* def = getComponentDef((fv->name()).name());
248 if ( def -> type() != FeatureDef::PRIMITIVE )
251 return ((FeatureDefPrimitive*)def) -> checkContent(fv);
256 const FeatureDef* FeatureDefComposite::getComponentDef(const char* nm) const
258 if ( f_components == 0 )
261 FeatureDef* def = f_components -> find(compareFunc, (void*)nm);
266 if ( f_components -> first() -> type() == WILDCARD )
267 return f_components -> first();
271 //return f_components -> find(compareFunc, "*");
275 ostream& FeatureDefComposite::print(ostream& out, int tabs) const
277 out_tabs(out, tabs) << f_name << "\n";
279 if ( f_components ) {
280 def_list_iterator_t NextComponent(*f_components);
281 while (++NextComponent) {
282 NextComponent.key() -> print(out, tabs+1) << "\n";
288 FeatureDefPrimitive::FeatureDefPrimitive(const char* name, type_values_list_t* tvl) :
289 FeatureDef(name), f_typeValuesList(tvl)
293 FeatureDefPrimitive::~FeatureDefPrimitive()
295 if ( f_typeValuesList ) {
296 f_typeValuesList -> clearAndDestroy();
297 delete f_typeValuesList;
301 unsigned FeatureDefPrimitive::checkContent(const Feature* f) const
304 MESSAGE(cerr, "FeatureDefPrimitive::checkContent");
307 debug(cerr, *(this -> name()));
311 if ( f_typeValuesList == 0 ) {
312 report_error_location();
313 cerr << "No type definition.\n";
317 FeatureValue * fv = 0;
319 fv = f -> evaluate();
321 mcatch (undefinedAttributeException&, e) {
325 mcatch (undefinedVariableException&, e) {
326 report_error_location();
327 cerr << "Undefined variable error.\n";
332 mcatch (badCastException&, e) {
333 report_error_location();
334 cerr << "Evaluating expression error.\n";
338 mcatch (badEvaluationException&, e) {
339 report_error_location();
340 cerr << "Evaluating expression error.\n";
346 //report_error_location();
347 //cerr << "There might be an error in the expression.\n";
353 debug(cerr, int(fv));
359 report_error_location();
360 cerr << "Error in evaluating an expression.\n";
364 type_values_list_iterator_t next(*f_typeValuesList);
367 if ( next.key() -> check(fv) == true ) {
374 report_error_location();
375 cerr << form("Unmatched feature type or illegal feature value: %s.\n",
381 ostream& FeatureDefPrimitive::print(ostream& out, int tabs) const
383 out_tabs(out, tabs) << f_name << "\n";
385 if ( f_typeValuesList ) {
386 type_values_list_iterator_t NextValue (*f_typeValuesList);
387 while (++NextValue) {
388 NextValue.key() -> print(out, tabs+1) << "\n";
394 unsigned FeatureDefReference::checkContent(const Feature* fv) const
399 ostream& FeatureDefReference::print(ostream& out, int tabs) const
401 out_tabs(out, tabs) << f_name << "\n";
405 unsigned FeatureDefWildCard::checkContent(const Feature* fv) const
410 ostream& FeatureDefWildCard::print(ostream& out, int tabs) const
412 out_tabs(out, tabs) << f_name << "\n";
416 featureDefDictionary::featureDefDictionary() : f_def_list(0)
420 featureDefDictionary::~featureDefDictionary()
423 f_def_list -> clearAndDestroy();
429 featureDefDictionary::addFeatureDefs(def_list_t* fdefs)
433 if ( f_def_list == 0 )
434 throw(CASTEXCEPT Exception());
438 featureDefDictionary::getDef(const char* nm)
442 FeatureDefReference key((char*)nm);
443 return f_def_list -> find(&key);
447 def = f_def_list -> find(&key);
449 debug(cerr, int(def));
455 featureDefDictionary::getDef(const Feature* f)
457 return getDef((f -> name()).name());
461 featureDefDictionary::checkSemantics(const FeatureSet* fs)
464 MESSAGE(cerr, "check feature set:");
469 const FeatureDef* def = 0;
470 const Feature *f = 0;
472 CC_TPtrSlistIterator<Feature> next(*(CC_TPtrSlist<Feature>*)fs);
478 report_error_location();
479 cerr << form("Unknown feature name %s.\n",
480 ((next.key()) -> name()).name());
484 if ( _checkSemantics(f, def) == false )
491 featureDefDictionary::_checkSemantics(const Feature* f, const FeatureDef* def)
493 const FeatureSet *featureset = 0;
494 const Feature *child_f= 0;
497 MESSAGE(cerr, "_checkSemantics");
500 def -> print(cerr, 0);
505 const FeatureDef* child_def = 0;
507 if ( def -> checkContent(f) == false ) {
511 if (f -> value()->type() == FeatureValue::featureset &&
512 def -> type() == FeatureDef::COMPOSITE )
514 //MESSAGE(cerr, "it is a feature set");
518 ((const FeatureValueFeatureSet *)(f -> value()))->value();
520 CC_TPtrSlistIterator<Feature> next(*(CC_TPtrSlist<Feature>*)featureset);
526 nm = ((next.key()) -> name()).name();
530 report_error_location();
533 child_def = ((FeatureDefComposite*)def) -> getComponentDef(nm);
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);
542 switch ( child_def -> type() ) {
543 case FeatureDef::REFERENCE:
544 child_def = getDef(child_def -> name() -> data());
546 case FeatureDef::WILDCARD:
547 child_def = getDef(nm);
553 child_f = next.key();
555 if ( _checkSemantics(child_f, child_def) == false )
565 istream& operator >>(istream& in, featureDefDictionary& dict)
569 int ok = defParserparse();
571 MESSAGE(cerr, "bad feature definition file");
572 throw(CASTEXCEPT Exception());
575 dict.addFeatureDefs(g_def_list);
580 ostream& operator <<(ostream& out, featureDefDictionary& dict)
582 def_list_iterator_t Next(*dict.f_def_list);
585 //debug(cerr, int(Next.key()));
586 out << *Next.key() << "\n";