aboutsummaryrefslogtreecommitdiff
path: root/xsde
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2010-03-28 16:53:35 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2010-03-28 16:53:35 +0200
commit4332a60585a14ff51bc54d29a4a81d37b3b1df81 (patch)
treefd3b807e3f5b3841371d509505a50498d21a2f99 /xsde
parentc2d201480002a24c05f1f4bc934036555b79cad6 (diff)
Validate enumerations in the xsd:string parser/serializer
Diffstat (limited to 'xsde')
-rw-r--r--xsde/cxx/parser/elements.hxx102
-rw-r--r--xsde/cxx/parser/parser-header.cxx38
-rw-r--r--xsde/cxx/parser/parser-inline.cxx56
-rw-r--r--xsde/cxx/parser/parser-source.cxx31
-rw-r--r--xsde/cxx/serializer/elements.hxx104
-rw-r--r--xsde/cxx/serializer/serializer-header.cxx41
-rw-r--r--xsde/cxx/serializer/serializer-inline.cxx56
-rw-r--r--xsde/cxx/serializer/serializer-source.cxx29
8 files changed, 426 insertions, 31 deletions
diff --git a/xsde/cxx/parser/elements.hxx b/xsde/cxx/parser/elements.hxx
index 954b13b..f603400 100644
--- a/xsde/cxx/parser/elements.hxx
+++ b/xsde/cxx/parser/elements.hxx
@@ -191,6 +191,108 @@ namespace CXX
String parser_map_;
};
+ // Check whether this is a string-based type (including ID, IDFER,
+ // anyURI, and ENTITY).
+ //
+ struct StringBasedType: Traversal::Complex,
+ Traversal::Fundamental::String,
+ Traversal::Fundamental::NormalizedString,
+ Traversal::Fundamental::Token,
+ Traversal::Fundamental::Name,
+ Traversal::Fundamental::NameToken,
+ Traversal::Fundamental::NCName,
+ Traversal::Fundamental::Language,
+ Traversal::Fundamental::Id,
+ Traversal::Fundamental::IdRef,
+ Traversal::Fundamental::AnyURI,
+ Traversal::Fundamental::Entity
+
+ {
+ StringBasedType (Boolean& r)
+ : r_ (r)
+ {
+ *this >> inherits_ >> *this;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Complex& c)
+ {
+ inherits (c, inherits_);
+ }
+
+ // Strings.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::String&)
+ {
+ r_ = true;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NormalizedString&)
+ {
+ r_ = true;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Token&)
+ {
+ r_ = true;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NameToken&)
+ {
+ r_ = true;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Name&)
+ {
+ r_ = true;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NCName&)
+ {
+ r_ = true;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Language&)
+ {
+ r_ = true;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Id&)
+ {
+ r_ = true;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::IdRef&)
+ {
+ r_ = true;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::AnyURI&)
+ {
+ r_ = true;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Entity&)
+ {
+ r_ = true;
+ }
+
+ private:
+ Boolean& r_;
+ Traversal::Inherits inherits_;
+ };
+
//
//
struct RequiredAttributeTest: Traversal::Attribute
diff --git a/xsde/cxx/parser/parser-header.cxx b/xsde/cxx/parser/parser-header.cxx
index 34f2119..5bc9cb7 100644
--- a/xsde/cxx/parser/parser-header.cxx
+++ b/xsde/cxx/parser/parser-header.cxx
@@ -28,6 +28,13 @@ namespace CXX
SemanticGraph::Type& base (e.inherits ().base ());
String fq_base (fq_name (base));
+ Boolean facets (false); // Whether we need to set facets.
+ if (validation)
+ {
+ StringBasedType t (facets);
+ t.dispatch (e);
+ }
+
os << "class " << name << ": public " <<
(mixin ? "virtual " : "") << fq_base
<< "{"
@@ -60,15 +67,22 @@ namespace CXX
<< "_dynamic_type () const;";
}
- if (tiein)
+ if (facets || tiein)
{
os << endl
<< "// Constructor." << endl
- << "//" << endl
- << name << " (" << fq_base << "* tiein);"
- << endl;
+ << "//" << endl;
- os << "// Implementation details." << endl
+ if (tiein)
+ os << name << " (" << fq_base << "* tiein);";
+ else
+ os << name << " ();";
+ }
+
+ if (tiein)
+ {
+ os << endl
+ << "// Implementation details." << endl
<< "//" << endl;
// If our base has pure virtual post, override it here.
@@ -87,6 +101,20 @@ namespace CXX
<< name << " (" << name << "*, void*);";
}
+ if (facets)
+ {
+ UnsignedLong enum_count (0);
+
+ for (Type::NamesIterator i (e.names_begin ()), end (e.names_end ());
+ i != end; ++i)
+ ++enum_count;
+
+ os << endl
+ << "protected:" << endl
+ << "static const char* const _xsde_" << name << "_enums_[" <<
+ enum_count << "UL];";
+ }
+
os << "};";
}
};
diff --git a/xsde/cxx/parser/parser-inline.cxx b/xsde/cxx/parser/parser-inline.cxx
index def8434..528ff86 100644
--- a/xsde/cxx/parser/parser-inline.cxx
+++ b/xsde/cxx/parser/parser-inline.cxx
@@ -24,9 +24,41 @@ namespace CXX
virtual Void
traverse (Type& e)
{
+ String const& name (ename (e));
+
+ Boolean facets (false); // Whether we need to set facets.
+ if (validation)
+ {
+ StringBasedType t (facets);
+ t.dispatch (e);
+ }
+
+ UnsignedLong enum_count (0);
+ if (facets)
+ {
+ for (Type::NamesIterator i (e.names_begin ()), end (e.names_end ());
+ i != end; ++i)
+ ++enum_count;
+ }
+
+ if (facets || tiein)
+ os << "// " << name << endl
+ << "//" << endl
+ << endl;
+
+ if (facets && !tiein)
+ {
+ os << inl
+ << name << "::" << endl
+ << name << " ()" << endl
+ << "{"
+ << "this->_enumeration_facet (_xsde_" << name << "_enums_, " <<
+ enum_count << "UL);"
+ << "}";
+ }
+
if (tiein)
{
- String const& name (ename (e));
String const& impl (etiein (e));
// We have to use "real" (non-typedef) base name in base
@@ -36,25 +68,31 @@ namespace CXX
String fq_base (fq_name (base));
String real_fq_base (real_fq_name (base));
- os << "// " << name << endl
- << "//" << endl
- << endl;
-
os << inl
<< name << "::" << endl
<< name << " (" << fq_base << "* tiein)" << endl
<< ": " << real_fq_base << " (tiein, 0)," << endl
<< " " << impl << " (0)"
- << "{"
- << "}";
+ << "{";
+
+ if (facets)
+ os << "this->_enumeration_facet (_xsde_" << name <<
+ "_enums_, " << enum_count << "UL);";
+
+ os << "}";
os << inl
<< name << "::" << endl
<< name << " (" << name << "* impl, void*)" << endl
<< ": " << real_fq_base << " (impl, 0)," << endl
<< " " << impl << " (impl)"
- << "{"
- << "}";
+ << "{";
+
+ if (facets)
+ os << "this->_enumeration_facet (_xsde_" << name <<
+ "_enums_, " << enum_count << "UL);";
+
+ os << "}";
}
}
};
diff --git a/xsde/cxx/parser/parser-source.cxx b/xsde/cxx/parser/parser-source.cxx
index 83b79f8..f4da879 100644
--- a/xsde/cxx/parser/parser-source.cxx
+++ b/xsde/cxx/parser/parser-source.cxx
@@ -5,6 +5,8 @@
#include <cxx/parser/parser-source.hxx>
+#include <cult/containers/set.hxx>
+
#include <xsd-frontend/semantic-graph.hxx>
#include <xsd-frontend/traversal.hxx>
@@ -34,7 +36,14 @@ namespace CXX
base.inherits_p () &&
base_ret == ret_type (base.inherits ().base ()));
- if (same || ret == L"void" || poly_code ||
+ Boolean facets (false); // Whether we need to set facets.
+ if (validation)
+ {
+ StringBasedType t (facets);
+ t.dispatch (e);
+ }
+
+ if (facets || same || ret == L"void" || poly_code ||
(tiein && !(base_same || base_ret == L"void")))
{
os << "// " << name << endl
@@ -145,6 +154,26 @@ namespace CXX
<< "return this->" << impl << "->" << base_post << " ();"
<< "}";
}
+
+ if (facets)
+ {
+ typedef Cult::Containers::Set<String> Enums;
+ Enums enums;
+
+ for (Type::NamesIterator i (e.names_begin ()),
+ end (e.names_end ()); i != end; ++i)
+ enums.insert (i->name ());
+
+ os << "const char* const " << name << "::" << "_xsde_" << name <<
+ "_enums_[" << enums.size () << "UL] = "
+ << "{";
+
+ for (Enums::Iterator b (enums.begin ()), i (b), end (enums.end ());
+ i != end; ++i)
+ os << (i != b ? ",\n" : "") << strlit (*i);
+
+ os << "};";
+ }
}
};
diff --git a/xsde/cxx/serializer/elements.hxx b/xsde/cxx/serializer/elements.hxx
index 50a54eb..470d6c4 100644
--- a/xsde/cxx/serializer/elements.hxx
+++ b/xsde/cxx/serializer/elements.hxx
@@ -203,6 +203,110 @@ namespace CXX
String serializer_map_;
};
+
+ // Check whether this is a string-based type (including ID, IDFER,
+ // anyURI, and ENTITY).
+ //
+ struct StringBasedType: Traversal::Complex,
+ Traversal::Fundamental::String,
+ Traversal::Fundamental::NormalizedString,
+ Traversal::Fundamental::Token,
+ Traversal::Fundamental::Name,
+ Traversal::Fundamental::NameToken,
+ Traversal::Fundamental::NCName,
+ Traversal::Fundamental::Language,
+ Traversal::Fundamental::Id,
+ Traversal::Fundamental::IdRef,
+ Traversal::Fundamental::AnyURI,
+ Traversal::Fundamental::Entity
+
+ {
+ StringBasedType (Boolean& r)
+ : r_ (r)
+ {
+ *this >> inherits_ >> *this;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Complex& c)
+ {
+ inherits (c, inherits_);
+ }
+
+ // Strings.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::String&)
+ {
+ r_ = true;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NormalizedString&)
+ {
+ r_ = true;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Token&)
+ {
+ r_ = true;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NameToken&)
+ {
+ r_ = true;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Name&)
+ {
+ r_ = true;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NCName&)
+ {
+ r_ = true;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Language&)
+ {
+ r_ = true;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Id&)
+ {
+ r_ = true;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::IdRef&)
+ {
+ r_ = true;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::AnyURI&)
+ {
+ r_ = true;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Entity&)
+ {
+ r_ = true;
+ }
+
+ private:
+ Boolean& r_;
+ Traversal::Inherits inherits_;
+ };
+
+
//
//
struct RequiredAttributeTest: Traversal::Attribute
diff --git a/xsde/cxx/serializer/serializer-header.cxx b/xsde/cxx/serializer/serializer-header.cxx
index 5459b51..b432f15 100644
--- a/xsde/cxx/serializer/serializer-header.cxx
+++ b/xsde/cxx/serializer/serializer-header.cxx
@@ -275,6 +275,13 @@ namespace CXX
SemanticGraph::Type& base (e.inherits ().base ());
String fq_base (fq_name (base));
+ Boolean facets (false); // Whether we need to set facets.
+ if (validation)
+ {
+ StringBasedType t (facets);
+ t.dispatch (e);
+ }
+
os << "class " << name << ": public " <<
(mixin ? "virtual " : "") << fq_base
<< "{"
@@ -328,15 +335,22 @@ namespace CXX
<< "_dynamic_type () const;";
}
- if (tiein)
+ if (facets || tiein)
{
os << endl
<< "// Constructor." << endl
- << "//" << endl
- << name << " (" << fq_base << "* tiein);"
- << endl;
+ << "//" << endl;
- os << "// Implementation details." << endl
+ if (tiein)
+ os << name << " (" << fq_base << "* tiein);";
+ else
+ os << name << " ();";
+ }
+
+ if (tiein)
+ {
+ os << endl
+ << "// Implementation details." << endl
<< "//" << endl;
// If our base has pure virtual functions, override them here.
@@ -345,8 +359,21 @@ namespace CXX
os << "protected:" << endl
<< name << "* " << etiein (e) << ";"
- << name << " (" << name << "*, void*);"
- << endl;
+ << name << " (" << name << "*, void*);";
+ }
+
+ if (facets)
+ {
+ UnsignedLong enum_count (0);
+
+ for (Type::NamesIterator i (e.names_begin ()), end (e.names_end ());
+ i != end; ++i)
+ ++enum_count;
+
+ os << endl
+ << "protected:" << endl
+ << "static const char* const _xsde_" << name << "_enums_[" <<
+ enum_count << "UL];";
}
os << "};";
diff --git a/xsde/cxx/serializer/serializer-inline.cxx b/xsde/cxx/serializer/serializer-inline.cxx
index 3ff9bab..e14680e 100644
--- a/xsde/cxx/serializer/serializer-inline.cxx
+++ b/xsde/cxx/serializer/serializer-inline.cxx
@@ -24,9 +24,41 @@ namespace CXX
virtual Void
traverse (Type& e)
{
+ String const& name (ename (e));
+
+ Boolean facets (false); // Whether we need to set facets.
+ if (validation)
+ {
+ StringBasedType t (facets);
+ t.dispatch (e);
+ }
+
+ UnsignedLong enum_count (0);
+ if (facets)
+ {
+ for (Type::NamesIterator i (e.names_begin ()), end (e.names_end ());
+ i != end; ++i)
+ ++enum_count;
+ }
+
+ if (facets || tiein)
+ os << "// " << name << endl
+ << "//" << endl
+ << endl;
+
+ if (facets && !tiein)
+ {
+ os << inl
+ << name << "::" << endl
+ << name << " ()" << endl
+ << "{"
+ << "this->_enumeration_facet (_xsde_" << name << "_enums_, " <<
+ enum_count << "UL);"
+ << "}";
+ }
+
if (tiein)
{
- String const& name (ename (e));
String const& impl (etiein (e));
// We have to use "real" (non-typedef) base name in base
@@ -36,25 +68,31 @@ namespace CXX
String fq_base (fq_name (base));
String real_fq_base (real_fq_name (base));
- os << "// " << name << endl
- << "//" << endl
- << endl;
-
os << inl
<< name << "::" << endl
<< name << " (" << fq_base << "* tiein)" << endl
<< ": " << real_fq_base << " (tiein, 0)," << endl
<< " " << impl << " (0)"
- << "{"
- << "}";
+ << "{";
+
+ if (facets)
+ os << "this->_enumeration_facet (_xsde_" << name <<
+ "_enums_, " << enum_count << "UL);";
+
+ os << "}";
os << inl
<< name << "::" << endl
<< name << " (" << name << "* impl, void*)" << endl
<< ": " << real_fq_base << " (impl, 0)," << endl
<< " " << impl << " (impl)"
- << "{"
- << "}";
+ << "{";
+
+ if (facets)
+ os << "this->_enumeration_facet (_xsde_" << name <<
+ "_enums_, " << enum_count << "UL);";
+
+ os << "}";
}
}
};
diff --git a/xsde/cxx/serializer/serializer-source.cxx b/xsde/cxx/serializer/serializer-source.cxx
index 509acf4..e4fd239 100644
--- a/xsde/cxx/serializer/serializer-source.cxx
+++ b/xsde/cxx/serializer/serializer-source.cxx
@@ -5,6 +5,8 @@
#include <cxx/serializer/serializer-source.hxx>
+#include <cult/containers/set.hxx>
+
#include <xsd-frontend/semantic-graph.hxx>
#include <xsd-frontend/traversal.hxx>
@@ -382,6 +384,13 @@ namespace CXX
String const& arg (arg_type (e));
SemanticGraph::Type& base (e.inherits ().base ());
+ Boolean facets (false); // Whether we need to set facets.
+ if (validation)
+ {
+ StringBasedType t (facets);
+ t.dispatch (e);
+ }
+
os << "// " << name << endl
<< "//" << endl
<< endl;
@@ -470,6 +479,26 @@ namespace CXX
BaseOverride t (*this, name);
t.dispatch (base);
}
+
+ if (facets)
+ {
+ typedef Cult::Containers::Set<String> Enums;
+ Enums enums;
+
+ for (Type::NamesIterator i (e.names_begin ()),
+ end (e.names_end ()); i != end; ++i)
+ enums.insert (i->name ());
+
+ os << "const char* const " << name << "::" << "_xsde_" << name <<
+ "_enums_[" << enums.size () << "UL] = "
+ << "{";
+
+ for (Enums::Iterator b (enums.begin ()), i (b), end (enums.end ());
+ i != end; ++i)
+ os << (i != b ? ",\n" : "") << strlit (*i);
+
+ os << "};";
+ }
}
};