aboutsummaryrefslogtreecommitdiff
path: root/xsde/cxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2009-04-02 12:22:38 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2009-04-02 12:22:38 +0200
commit8336dd4c16d4885989a6d8f0c83a4b401f5cb63b (patch)
tree26ca613e7f3a3fe9fb75bf5bb3b65503661e0ebf /xsde/cxx
parente4c22d3686da0e973e21eae0561c1169c0eeff36 (diff)
Add support for attributes with default and fixed values.
tests/cxx/hybrid/default: new test tests/cxx/hybrid/binary: update to test default and fixed values
Diffstat (limited to 'xsde/cxx')
-rw-r--r--xsde/cxx/hybrid/cli.hxx2
-rw-r--r--xsde/cxx/hybrid/default-value.cxx1210
-rw-r--r--xsde/cxx/hybrid/default-value.hxx366
-rw-r--r--xsde/cxx/hybrid/elements.hxx19
-rw-r--r--xsde/cxx/hybrid/extraction-source.cxx62
-rw-r--r--xsde/cxx/hybrid/generator.cxx6
-rw-r--r--xsde/cxx/hybrid/insertion-source.cxx38
-rw-r--r--xsde/cxx/hybrid/parser-header.cxx3
-rw-r--r--xsde/cxx/hybrid/parser-source.cxx3
-rw-r--r--xsde/cxx/hybrid/serializer-source.cxx23
-rw-r--r--xsde/cxx/hybrid/tree-forward.cxx5
-rw-r--r--xsde/cxx/hybrid/tree-header.cxx115
-rw-r--r--xsde/cxx/hybrid/tree-inline.cxx216
-rw-r--r--xsde/cxx/hybrid/tree-name-processor.cxx43
-rw-r--r--xsde/cxx/hybrid/tree-source.cxx153
15 files changed, 2104 insertions, 160 deletions
diff --git a/xsde/cxx/hybrid/cli.hxx b/xsde/cxx/hybrid/cli.hxx
index 80b91bc..509005a 100644
--- a/xsde/cxx/hybrid/cli.hxx
+++ b/xsde/cxx/hybrid/cli.hxx
@@ -33,6 +33,7 @@ namespace CXX
extern Key suppress_validation;
extern Key suppress_parser_val;
extern Key suppress_serializer_val;
+ extern Key omit_default_attributes;
extern Key generate_detach;
extern Key generate_insertion;
extern Key generate_extraction;
@@ -120,6 +121,7 @@ namespace CXX
suppress_validation, Boolean,
suppress_parser_val, Boolean,
suppress_serializer_val, Boolean,
+ omit_default_attributes, Boolean,
generate_detach, Boolean,
generate_insertion, Cult::Containers::Vector<NarrowString>,
generate_extraction, Cult::Containers::Vector<NarrowString>,
diff --git a/xsde/cxx/hybrid/default-value.cxx b/xsde/cxx/hybrid/default-value.cxx
new file mode 100644
index 0000000..895c764
--- /dev/null
+++ b/xsde/cxx/hybrid/default-value.cxx
@@ -0,0 +1,1210 @@
+// file : xsde/cxx/hybrid/default-value.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <cxx/hybrid/default-value.hxx>
+
+namespace CXX
+{
+ namespace Hybrid
+ {
+ namespace
+ {
+ Void
+ normalize (String& s)
+ {
+ Size n (s.size ());
+
+ for (Size i (0); i < n; ++i)
+ {
+ WideChar& c (s[i]);
+
+ if (c == 0x0D || // carriage return
+ c == 0x09 || // tab
+ c == 0x0A)
+ c = 0x20;
+ }
+ }
+
+ Void
+ collapse (String& s)
+ {
+ Size n (s.size ()), j (0);
+ Boolean subs (false), trim (true);
+
+ for (Size i (0); i < n; ++i)
+ {
+ WideChar c (s[i]);
+
+ if (c == 0x20 || c == 0x09 || c == 0x0A)
+ subs = true;
+ else
+ {
+ if (subs)
+ {
+ subs = false;
+
+ if (!trim)
+ s[j++] = 0x20;
+ }
+
+ if (trim)
+ trim = false;
+
+ s[j++] = c;
+ }
+ }
+
+ s.resize (j);
+ }
+
+ Void
+ strip_zeros (String& s)
+ {
+ Size n (s.size ()), i (0);
+
+ if (n > 0 && s[i] == '-' || s[i] == '+')
+ i++;
+
+ Size j (i);
+
+ Boolean strip (true);
+
+ for (; i < n; ++i)
+ {
+ WideChar c (s[i]);
+
+ if (c == '0')
+ {
+ if (!strip)
+ s[j++] = c;
+ }
+ else
+ {
+ s[j++] = c;
+
+ if (strip)
+ strip = false;
+ }
+ }
+
+ if (strip && j < n)
+ s[j++] = '0'; // There was nothing except zeros so add one back.
+
+ s.resize (j);
+ }
+ }
+
+ //
+ // LiteralValue
+ //
+ LiteralValue::
+ LiteralValue (Context& c)
+ : Context (c), str_ (!stl)
+ {
+ }
+
+ LiteralValue::
+ LiteralValue (Context& c, Boolean str)
+ : Context (c), str_ (str)
+ {
+ }
+
+ String LiteralValue::
+ dispatch (SemanticGraph::Node& type, String const& value)
+ {
+ literal_.clear ();
+ value_ = value;
+ Traversal::NodeBase::dispatch (type);
+ return literal_;
+ }
+
+ // Boolean.
+ //
+ Void LiteralValue::
+ traverse (SemanticGraph::Fundamental::Boolean&)
+ {
+ collapse (value_);
+ literal_ = (value_ == L"true" || value_ == L"1") ? "true" : "false";
+ }
+
+ // Integral types.
+ //
+ Void LiteralValue::
+ traverse (SemanticGraph::Fundamental::Byte&)
+ {
+ collapse (value_);
+ strip_zeros (value_);
+ literal_ = value_;
+ }
+
+ Void LiteralValue::
+ traverse (SemanticGraph::Fundamental::UnsignedByte&)
+ {
+ collapse (value_);
+ strip_zeros (value_);
+ literal_ = value_;
+ }
+
+ Void LiteralValue::
+ traverse (SemanticGraph::Fundamental::Short&)
+ {
+ collapse (value_);
+ strip_zeros (value_);
+ literal_ = value_;
+ }
+
+ Void LiteralValue::
+ traverse (SemanticGraph::Fundamental::UnsignedShort&)
+ {
+ collapse (value_);
+ strip_zeros (value_);
+ literal_ = value_;
+ }
+
+ Void LiteralValue::
+ traverse (SemanticGraph::Fundamental::Int&)
+ {
+ collapse (value_);
+ strip_zeros (value_);
+ literal_ = value_;
+ }
+
+ Void LiteralValue::
+ traverse (SemanticGraph::Fundamental::UnsignedInt&)
+ {
+ collapse (value_);
+ strip_zeros (value_);
+ literal_ = value_;
+ }
+
+ Void LiteralValue::
+ traverse (SemanticGraph::Fundamental::Long&)
+ {
+ collapse (value_);
+ strip_zeros (value_);
+ literal_ = value_;
+ literal_ += options.value<CLI::no_long_long> () ? L"L" : L"LL";
+ }
+
+ Void LiteralValue::
+ traverse (SemanticGraph::Fundamental::UnsignedLong&)
+ {
+ collapse (value_);
+ strip_zeros (value_);
+ literal_ = value_;
+ literal_ += options.value<CLI::no_long_long> () ? L"UL" : L"ULL";
+ }
+
+ Void LiteralValue::
+ traverse (SemanticGraph::Fundamental::Integer&)
+ {
+ collapse (value_);
+ strip_zeros (value_);
+ literal_ = value_ + L"L";
+ }
+
+ Void LiteralValue::
+ traverse (SemanticGraph::Fundamental::NonPositiveInteger&)
+ {
+ collapse (value_);
+ strip_zeros (value_);
+ literal_ = value_ + L"L";
+ }
+
+ Void LiteralValue::
+ traverse (SemanticGraph::Fundamental::NonNegativeInteger&)
+ {
+ collapse (value_);
+ strip_zeros (value_);
+ literal_ = value_ + L"UL";
+ }
+
+ Void LiteralValue::
+ traverse (SemanticGraph::Fundamental::PositiveInteger&)
+ {
+ collapse (value_);
+ strip_zeros (value_);
+ literal_ = value_ + L"UL";
+ }
+
+ Void LiteralValue::
+ traverse (SemanticGraph::Fundamental::NegativeInteger&)
+ {
+ collapse (value_);
+ strip_zeros (value_);
+ literal_ = value_ + L"L";
+ }
+
+ // Floats.
+ //
+ Void LiteralValue::
+ traverse (SemanticGraph::Fundamental::Float&)
+ {
+ collapse (value_);
+
+ if (value_ == L"NaN")
+ {
+ literal_ = "static_cast< float > (strtod (\"NAN\", 0))";
+ }
+ else if (value_ == L"INF")
+ {
+ literal_ = "static_cast< float > (strtod (\"INF\", 0))";
+ }
+ else if (value_ == L"-INF")
+ {
+ literal_ = "static_cast< float > (strtod (\"-INF\", 0))";
+ }
+ else
+ {
+ strip_zeros (value_);
+ literal_ = value_ + L"F";
+ }
+ }
+
+ Void LiteralValue::
+ traverse (SemanticGraph::Fundamental::Double&)
+ {
+ collapse (value_);
+
+ if (value_ == L"NaN")
+ {
+ literal_ = "strtod (\"NAN\", 0)";
+ }
+ else if (value_ == L"INF")
+ {
+ literal_ = "strtod (\"INF\", 0)";
+ }
+ else if (value_ == L"-INF")
+ {
+ literal_ = "strtod (\"-INF\", 0)";
+ }
+ else
+ {
+ strip_zeros (value_);
+ literal_ = value_;
+ }
+ }
+
+ Void LiteralValue::
+ traverse (SemanticGraph::Fundamental::Decimal&)
+ {
+ collapse (value_);
+ strip_zeros (value_);
+ literal_ = value_;
+ }
+
+ // Strings.
+ //
+ Void LiteralValue::
+ traverse (SemanticGraph::Fundamental::String&)
+ {
+ if (str_)
+ literal_ = strlit (value_);
+ }
+
+ Void LiteralValue::
+ traverse (SemanticGraph::Fundamental::NormalizedString&)
+ {
+ if (str_)
+ {
+ normalize (value_);
+ literal_ = strlit (value_);
+ }
+ }
+
+ Void LiteralValue::
+ traverse (SemanticGraph::Fundamental::Token&)
+ {
+ if (str_)
+ {
+ collapse (value_);
+ literal_ = strlit (value_);
+ }
+ }
+
+ Void LiteralValue::
+ traverse (SemanticGraph::Fundamental::NameToken&)
+ {
+ if (str_)
+ {
+ collapse (value_);
+ literal_ = strlit (value_);
+ }
+ }
+
+ Void LiteralValue::
+ traverse (SemanticGraph::Fundamental::Name&)
+ {
+ if (str_)
+ {
+ collapse (value_);
+ literal_ = strlit (value_);
+ }
+ }
+
+ Void LiteralValue::
+ traverse (SemanticGraph::Fundamental::NCName&)
+ {
+ if (str_)
+ {
+ collapse (value_);
+ literal_ = strlit (value_);
+ }
+ }
+
+ Void LiteralValue::
+ traverse (SemanticGraph::Fundamental::Language&)
+ {
+ if (str_)
+ {
+ collapse (value_);
+ literal_ = strlit (value_);
+ }
+ }
+
+
+ // ID/IDREF.
+ //
+ Void LiteralValue::
+ traverse (SemanticGraph::Fundamental::Id&)
+ {
+ if (str_)
+ {
+ collapse (value_);
+ literal_ = strlit (value_);
+ }
+ }
+
+ Void LiteralValue::
+ traverse (SemanticGraph::Fundamental::IdRef&)
+ {
+ if (str_)
+ {
+ collapse (value_);
+ literal_ = strlit (value_);
+ }
+ }
+
+ // URI.
+ //
+ Void LiteralValue::
+ traverse (SemanticGraph::Fundamental::AnyURI&)
+ {
+ if (str_)
+ {
+ collapse (value_);
+ literal_ = strlit (value_);
+ }
+ }
+
+ // Entity.
+ //
+ Void LiteralValue::
+ traverse (SemanticGraph::Fundamental::Entity&)
+ {
+ if (str_)
+ {
+ collapse (value_);
+ literal_ = strlit (value_);
+ }
+ }
+
+ //
+ // InitValue
+ //
+
+ InitValue::
+ InitValue (Context& c)
+ : Context (c),
+ member_ ("this->value_."),
+ var_ (c, TypeName::var),
+ var_value_ (c, TypeName::var_value),
+ literal_value_ (c, true),
+ literal_value_list_ (c)
+ {
+ }
+
+ Void InitValue::
+ dispatch (SemanticGraph::Node& type, String const& value)
+ {
+ value_ = value;
+ Traversal::NodeBase::dispatch (type);
+ }
+
+ Void InitValue::
+ traverse (SemanticGraph::List& l)
+ {
+ SemanticGraph::Type& t (l.argumented ().type ());
+ Boolean fl (fixed_length (t));
+
+ collapse (value_);
+
+ if (!value_)
+ return;
+
+ String ov (value_);
+ String om (member_);
+
+ Size b (0);
+
+ for (Size e (ov.find (' ')); ; e = ov.find (' ', b))
+ {
+ String v (ov, b, e != String::npos ? e - b : e);
+
+ os << "{";
+ var_.dispatch (t);
+ os << " tmp;";
+
+ String literal (literal_value_list_.dispatch (t, v));
+
+ if (literal)
+ {
+ // Variable-length literal is a string.
+ //
+ if (fl)
+ os << "tmp = " << literal << ";";
+ else
+ {
+ os << "tmp = ::xsde::cxx::strdupx (" << literal << ");";
+
+ if (!exceptions)
+ {
+ os << endl
+ << "if (!tmp)"
+ << "{"
+ << "assert (false);"
+ << "exit (1);"
+ << "}";
+ }
+ }
+ }
+ else
+ {
+ if (fl)
+ member_ = "tmp.";
+ else
+ {
+ os << "tmp = new " << fq_name (t) << ";";
+
+ if (!exceptions)
+ {
+ os << endl
+ << "if (!tmp)"
+ << "{"
+ << "assert (false);"
+ << "exit (1);"
+ << "}";
+ }
+
+ member_ = "tmp->";
+ }
+
+ value_ = v;
+ Traversal::NodeBase::dispatch (t);
+ }
+
+ if (exceptions)
+ os << om << "push_back (tmp);";
+ else
+ os << "if (" << om << "push_back (tmp))"
+ << "{"
+ << "assert (false);"
+ << "exit (1);"
+ << "}";
+
+ os << "}";
+
+ if (e == String::npos)
+ break;
+
+ b = e + 1;
+ }
+
+ member_ = om;
+ value_ = ov;
+ }
+
+ Void InitValue::
+ traverse (SemanticGraph::Union& u)
+ {
+ String const& value (u.context ().get<String> ("value"));
+
+ if (stl)
+ os << member_ << value << " (" << strlit (value_) << ");";
+ else
+ {
+ if (exceptions)
+ os << member_ << value << " (";
+ else
+ os << "char* v = ";
+
+ os << "::xsde::cxx::strdupx (" << strlit (value_) << ")";
+
+ if (exceptions)
+ os << ");";
+ else
+ {
+ os << ";"
+ << endl
+ << "if (!v)"
+ << "{"
+ << "assert (false);"
+ << "exit (1);"
+ << "}"
+ << member_ << value << " (v);";
+ }
+ }
+ }
+
+ Void InitValue::
+ traverse (SemanticGraph::Complex& c)
+ {
+ Traversal::NodeBase::dispatch (ultimate_base (c));
+ }
+
+ Void InitValue::
+ traverse (SemanticGraph::Type& t)
+ {
+ // This is a fall-back case where we handle all other (literal)
+ // types.
+ //
+ os << member_ << "base_value (" <<
+ literal_value_.dispatch (t, value_) << ");";
+ }
+
+ // anySimpleType.
+ //
+ Void InitValue::
+ traverse (SemanticGraph::AnySimpleType&)
+ {
+ }
+
+ // Strings.
+ //
+ Void InitValue::
+ traverse (SemanticGraph::Fundamental::String& t)
+ {
+ string_type (t);
+ }
+
+ Void InitValue::
+ traverse (SemanticGraph::Fundamental::NormalizedString& t)
+ {
+ string_type (t);
+ }
+
+ Void InitValue::
+ traverse (SemanticGraph::Fundamental::Token& t)
+ {
+ string_type (t);
+ }
+
+ Void InitValue::
+ traverse (SemanticGraph::Fundamental::NameToken& t)
+ {
+ string_type (t);
+ }
+
+ Void InitValue::
+ traverse (SemanticGraph::Fundamental::NameTokens&)
+ {
+ string_sequence_type ();
+ }
+
+ Void InitValue::
+ traverse (SemanticGraph::Fundamental::Name& t)
+ {
+ string_type (t);
+ }
+
+ Void InitValue::
+ traverse (SemanticGraph::Fundamental::NCName& t)
+ {
+ string_type (t);
+ }
+
+ Void InitValue::
+ traverse (SemanticGraph::Fundamental::Language& t)
+ {
+ string_type (t);
+ }
+
+ // Qualified name.
+ //
+ Void InitValue::
+ traverse (SemanticGraph::Fundamental::QName&)
+ {
+ collapse (value_);
+
+ String prefix, name;
+ Size p (value_.find (':'));
+
+ if (p != String::npos)
+ {
+ prefix.assign (value_, 0, p);
+ name.assign (value_, p + 1, String::npos);
+ }
+ else
+ name = value_;
+
+ if (stl)
+ {
+ os << member_ << "prefix (" << strlit (prefix) << ");"
+ << member_ << "name (" << strlit (name) << ");";
+ }
+ else
+ {
+ if (exceptions)
+ os << member_ << "prefix_copy (" << strlit (prefix) << ");"
+ << member_ << "name_copy (" << strlit (name) << ");";
+ else
+ os << "if (" << member_ << "prefix_copy (" << strlit (prefix) <<
+ ") || " << member_ << "name_copy (" << strlit (name) << "))"
+ << "{"
+ << "assert (false);"
+ << "exit (1);"
+ << "}";
+ }
+ }
+
+ // ID/IDREF.
+ //
+ Void InitValue::
+ traverse (SemanticGraph::Fundamental::Id& t)
+ {
+ string_type (t);
+ }
+
+ Void InitValue::
+ traverse (SemanticGraph::Fundamental::IdRef& t)
+ {
+ string_type (t);
+ }
+
+ Void InitValue::
+ traverse (SemanticGraph::Fundamental::IdRefs&)
+ {
+ string_sequence_type ();
+ }
+
+ // URI.
+ //
+ Void InitValue::
+ traverse (SemanticGraph::Fundamental::AnyURI& t)
+ {
+ string_type (t);
+ }
+
+ // Binary.
+ //
+ Void InitValue::
+ traverse (SemanticGraph::Fundamental::Base64Binary&)
+ {
+ collapse (value_);
+
+ if (value_)
+ os << "#error base64Binary default values are not yet supported"
+ << endl;
+ }
+
+ Void InitValue::
+ traverse (SemanticGraph::Fundamental::HexBinary&)
+ {
+ collapse (value_);
+
+ if (value_)
+ os << "#error hexBinary default values are not yet supported"
+ << endl;
+ }
+
+
+ // Date/time.
+ //
+ Void InitValue::
+ traverse (SemanticGraph::Fundamental::Date&)
+ {
+ // date := [-]CCYY[N]*-MM-DD[Z|(+|-)HH:MM]
+ //
+ collapse (value_);
+
+ Size b (0);
+ Size e (value_.find ('-', value_[0] == '-' ? 5 : 4));
+ String year (value_, 0, e);
+
+ b = e + 1;
+ String month (value_, b, 2);
+
+ b += 3;
+ String day (value_, b, 2);
+
+ strip_zeros (year);
+ strip_zeros (month);
+ strip_zeros (day);
+
+ os << member_ << "year (" << year << ");"
+ << member_ << "month (" << month << ");"
+ << member_ << "day (" << day << ");";
+
+ time_zone (b + 2);
+ }
+
+ Void InitValue::
+ traverse (SemanticGraph::Fundamental::DateTime&)
+ {
+ // date_time := [-]CCYY[N]*-MM-DDTHH:MM:SS[.S+][Z|(+|-)HH:MM]
+ //
+ collapse (value_);
+
+ Size b (0);
+ Size e (value_.find ('-', value_[0] == '-' ? 5 : 4));
+ String year (value_, 0, e);
+ b = e + 1;
+
+ String month (value_, b, 2);
+ b += 3;
+
+ String day (value_, b, 2);
+ b += 3;
+
+ String hours (value_, b, 2);
+ b += 3;
+
+ String minutes (value_, b, 2);
+ b += 3;
+
+ e = b + 2;
+ for (; e < value_.size (); ++e)
+ {
+ WideChar c (value_[e]);
+
+ if (c == 'Z' || c == '+' || c == '-')
+ break;
+ }
+
+ String seconds (value_, b, e - b);
+
+ strip_zeros (year);
+ strip_zeros (month);
+ strip_zeros (day);
+ strip_zeros (hours);
+ strip_zeros (minutes);
+ strip_zeros (seconds);
+
+ os << member_ << "year (" << year << ");"
+ << member_ << "month (" << month << ");"
+ << member_ << "day (" << day << ");"
+ << member_ << "hours (" << hours << ");"
+ << member_ << "minutes (" << minutes << ");"
+ << member_ << "seconds (" << seconds << ");";
+
+ time_zone (e);
+ }
+
+ namespace
+ {
+ Size
+ find_delim (String const& s, Size pos)
+ {
+ for (; pos < s.size (); ++pos)
+ {
+ WideChar c (s[pos]);
+
+ if (c == 'Y' || c == 'D' || c == 'M' || c == 'H' ||
+ c == 'M' || c == 'S' || c == 'T')
+ break;
+ }
+
+ return pos;
+ }
+ }
+
+ Void InitValue::
+ traverse (SemanticGraph::Fundamental::Duration&)
+ {
+ // duration := [-]P[nY][nM][nD][TnHnMn[.n+]S]
+ //
+ collapse (value_);
+
+ Size b (1), e, n (value_.size ());
+
+ if (value_[0] == '-')
+ {
+ os << member_ << "negative (true);";
+ b++;
+ }
+
+ e = find_delim (value_, b);
+
+ if (e < n && value_[e] == 'Y')
+ {
+ String v (value_, b, e - b);
+ strip_zeros (v);
+ os << member_ << "years (" << v << ");";
+
+ b = e + 1;
+ e = find_delim (value_, b);
+ }
+
+ if (e < n && value_[e] == 'M')
+ {
+ String v (value_, b, e - b);
+ strip_zeros (v);
+ os << member_ << "months (" << v << ");";
+
+ b = e + 1;
+ e = find_delim (value_, b);
+ }
+
+ if (e < n && value_[e] == 'D')
+ {
+ String v (value_, b, e - b);
+ strip_zeros (v);
+ os << member_ << "days (" << v << ");";
+
+ b = e + 1;
+ e = find_delim (value_, b);
+ }
+
+ if (e < n && value_[e] == 'T')
+ {
+ b = e + 1;
+ e = find_delim (value_, b);
+ }
+
+ if (e < n && value_[e] == 'H')
+ {
+ String v (value_, b, e - b);
+ strip_zeros (v);
+ os << member_ << "hours (" << v << ");";
+
+ b = e + 1;
+ e = find_delim (value_, b);
+ }
+
+ if (e < n && value_[e] == 'M')
+ {
+ String v (value_, b, e - b);
+ strip_zeros (v);
+ os << member_ << "minutes (" << v << ");";
+
+ b = e + 1;
+ e = find_delim (value_, b);
+ }
+
+ if (e < n && value_[e] == 'S')
+ {
+ String v (value_, b, e - b);
+ strip_zeros (v);
+ os << member_ << "seconds (" << v << ");";
+
+ b = e + 1;
+ e = find_delim (value_, b);
+ }
+ }
+
+ Void InitValue::
+ traverse (SemanticGraph::Fundamental::Day&)
+ {
+ // gday := ---DD[Z|(+|-)HH:MM]
+ //
+ collapse (value_);
+
+ String day (value_, 3, 2);
+ strip_zeros (day);
+
+ os << member_ << "day (" << day << ");";
+
+ time_zone (5);
+ }
+
+ Void InitValue::
+ traverse (SemanticGraph::Fundamental::Month&)
+ {
+ // gmonth := --MM[Z|(+|-)HH:MM]
+ //
+ collapse (value_);
+
+ String month (value_, 2, 2);
+ strip_zeros (month);
+
+ os << member_ << "month (" << month << ");";
+
+ time_zone (4);
+ }
+
+ Void InitValue::
+ traverse (SemanticGraph::Fundamental::MonthDay&)
+ {
+ // gmonth_day := --MM-DD[Z|(+|-)HH:MM]
+ //
+ collapse (value_);
+
+ String month (value_, 2, 2);
+ String day (value_, 5, 2);
+
+ strip_zeros (month);
+ strip_zeros (day);
+
+ os << member_ << "month (" << month << ");";
+ os << member_ << "day (" << day << ");";
+
+ time_zone (7);
+ }
+
+ Void InitValue::
+ traverse (SemanticGraph::Fundamental::Year&)
+ {
+ // gyear := [-]CCYY[N]*[Z|(+|-)HH:MM]
+ //
+ collapse (value_);
+
+ Size pos (value_[0] == '-' ? 5 : 4);
+ for (; pos < value_.size (); ++pos)
+ {
+ WideChar c (value_[pos]);
+
+ if (c == 'Z' || c == '+' || c == '-')
+ break;
+ }
+
+ String year (value_, 0, pos);
+ strip_zeros (year);
+
+ os << member_ << "year (" << year << ");";
+
+ time_zone (pos);
+ }
+
+ Void InitValue::
+ traverse (SemanticGraph::Fundamental::YearMonth&)
+ {
+ // gyear_month := [-]CCYY[N]*-MM[Z|(+|-)HH:MM]
+ //
+ collapse (value_);
+
+ Size pos (value_.find ('-', value_[0] == '-' ? 5 : 4));
+
+ String year (value_, 0, pos);
+ String month (value_, pos + 1, 2);
+
+ strip_zeros (year);
+ strip_zeros (month);
+
+ os << member_ << "year (" << year << ");";
+ os << member_ << "month (" << month << ");";
+
+ time_zone (pos + 3);
+ }
+
+ Void InitValue::
+ traverse (SemanticGraph::Fundamental::Time&)
+ {
+ // time := HH:MM:SS[.S+][Z|(+|-)HH:MM]
+ //
+ collapse (value_);
+
+ String hours (value_, 0, 2);
+ String minutes (value_, 3, 2);
+
+ Size e (8);
+ for (; e < value_.size (); ++e)
+ {
+ WideChar c (value_[e]);
+
+ if (c == 'Z' || c == '+' || c == '-')
+ break;
+ }
+
+ String seconds (value_, 6, e - 6);
+
+ strip_zeros (hours);
+ strip_zeros (minutes);
+ strip_zeros (seconds);
+
+ os << member_ << "hours (" << hours << ");"
+ << member_ << "minutes (" << minutes << ");"
+ << member_ << "seconds (" << seconds << ");";
+
+ time_zone (e);
+ }
+
+ Void InitValue::
+ time_zone (Size pos)
+ {
+ // time_zone := Z|(+|-)HH:MM
+ //
+ if (pos < value_.size ())
+ {
+ String h, m;
+
+ if (value_[pos] == 'Z')
+ {
+ h = "0";
+ m = "0";
+ }
+ else
+ {
+ if (value_[pos] == '-')
+ {
+ h = "-";
+ m = "-";
+ }
+
+ h.append (value_, pos + 1, 2);
+ m.append (value_, pos + 4, 2);
+
+ strip_zeros (h);
+ strip_zeros (m);
+ }
+
+ os << member_ << "zone_hours (" << h << ");"
+ << member_ << "zone_minutes (" << m << ");";
+ }
+ }
+
+ // Entity.
+ //
+ Void InitValue::
+ traverse (SemanticGraph::Fundamental::Entity& t)
+ {
+ string_type (t);
+ }
+
+ Void InitValue::
+ traverse (SemanticGraph::Fundamental::Entities&)
+ {
+ string_sequence_type ();
+ }
+
+ Void InitValue::
+ string_type (SemanticGraph::Fundamental::Type& t)
+ {
+ // In case STL is disabled, strings are returned as literals
+ // so we end up here only if the type is derived from a string.
+ // Otherwise, use assign() which handles both derivations as
+ // well as the straight std::string value.
+ //
+ if (stl)
+ os << member_ << "assign (" << literal_value_.dispatch (t, value_) <<
+ ");";
+ else
+ {
+ if (exceptions)
+ os << member_ << "base_value (";
+ else
+ os << "char* v = ";
+
+ os << "::xsde::cxx::strdupx (" <<
+ literal_value_.dispatch (t, value_) << ")";
+
+ if (exceptions)
+ os << ");";
+ else
+ {
+ os << ";"
+ << endl
+ << "if (!v)"
+ << "{"
+ << "assert (false);"
+ << "exit (1);"
+ << "}"
+ << member_ << "base_value (v);";
+ }
+ }
+ }
+
+ Void InitValue::
+ string_sequence_type ()
+ {
+ collapse (value_);
+
+ if (!value_)
+ return;
+
+ Size b (0);
+
+ for (Size e (value_.find (' ')); ; e = value_.find (' ', b))
+ {
+ String v (value_, b, e != String::npos ? e - b : e);
+
+ os << "{";
+
+ if (stl)
+ os << "::std::string tmp (";
+ else
+ os << "char* tmp = ::xsde::cxx::strdupx (";
+
+ os << strlit (v) << ");";
+
+ if (!exceptions && !stl)
+ {
+ os << endl
+ << "if (!tmp)"
+ << "{"
+ << "assert (false);"
+ << "exit (1);"
+ << "}";
+ }
+
+ if (exceptions)
+ os << member_ << "push_back (tmp);";
+ else
+ os << "if (" << member_ << "push_back (tmp))"
+ << "{"
+ << "assert (false);"
+ << "exit (1);"
+ << "}";
+
+ os << "}";
+
+ if (e == String::npos)
+ break;
+
+ b = e + 1;
+ }
+ }
+
+ //
+ // CompareValue
+ //
+
+ CompareValue::
+ CompareValue (Context& c)
+ : Context (c)
+ {
+ }
+
+ Void CompareValue::
+ dispatch (SemanticGraph::Node& type, String const& lhs, String const& rhs)
+ {
+ lhs_ = &lhs;
+ rhs_ = &rhs;
+ Traversal::NodeBase::dispatch (type);
+ }
+
+ Void CompareValue::
+ traverse (SemanticGraph::Union& u)
+ {
+ String const& value (u.context ().get<String> ("value"));
+
+ os << *lhs_ << "." << value << " () == " << *rhs_ << "." << value <<
+ " ()";
+ }
+
+ Void CompareValue::
+ traverse (SemanticGraph::Complex& c)
+ {
+ Traversal::NodeBase::dispatch (ultimate_base (c));
+ }
+
+ Void CompareValue::
+ traverse (SemanticGraph::Type& t)
+ {
+ // This is a fall-back case where we handle all other types.
+ //
+ os << *lhs_ << " == " << *rhs_;
+ }
+ }
+}
diff --git a/xsde/cxx/hybrid/default-value.hxx b/xsde/cxx/hybrid/default-value.hxx
new file mode 100644
index 0000000..b9f902c
--- /dev/null
+++ b/xsde/cxx/hybrid/default-value.hxx
@@ -0,0 +1,366 @@
+// file : xsde/cxx/hybrid/default-value.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef CXX_HYBRID_DEFAULT_VALUE_HXX
+#define CXX_HYBRID_DEFAULT_VALUE_HXX
+
+#include <xsd-frontend/semantic-graph.hxx>
+#include <xsd-frontend/traversal.hxx>
+
+#include <cxx/hybrid/elements.hxx>
+
+namespace CXX
+{
+ namespace Hybrid
+ {
+ struct LiteralValue: Traversal::Fundamental::Byte,
+ Traversal::Fundamental::UnsignedByte,
+ Traversal::Fundamental::Short,
+ Traversal::Fundamental::UnsignedShort,
+ Traversal::Fundamental::Int,
+ Traversal::Fundamental::UnsignedInt,
+ Traversal::Fundamental::Long,
+ Traversal::Fundamental::UnsignedLong,
+ Traversal::Fundamental::Integer,
+ Traversal::Fundamental::NonPositiveInteger,
+ Traversal::Fundamental::NonNegativeInteger,
+ Traversal::Fundamental::PositiveInteger,
+ Traversal::Fundamental::NegativeInteger,
+
+ Traversal::Fundamental::Boolean,
+
+ Traversal::Fundamental::Float,
+ Traversal::Fundamental::Double,
+ Traversal::Fundamental::Decimal,
+
+ 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,
+
+ Context
+ {
+ LiteralValue (Context&);
+ LiteralValue (Context&, Boolean str);
+
+ String
+ dispatch (SemanticGraph::Node& type, String const& value);
+
+ // Boolean.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Boolean&);
+
+ // Integral types.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Byte&);
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::UnsignedByte&);
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Short&);
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::UnsignedShort&);
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Int&);
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::UnsignedInt&);
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Long&);
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::UnsignedLong&);
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Integer&);
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NonPositiveInteger&);
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NonNegativeInteger&);
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::PositiveInteger&);
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NegativeInteger&);
+
+ // Floats.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Float&);
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Double&);
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Decimal&);
+
+ // Strings.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::String&);
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NormalizedString&);
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Token&);
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NameToken&);
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Name&);
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NCName&);
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Language&);
+
+ // ID/IDREF.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Id&);
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::IdRef&);
+
+ // URI.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::AnyURI&);
+
+ // Entity.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Entity&);
+
+ private:
+ Boolean str_;
+ String value_;
+ String literal_;
+ };
+
+ struct InitValue: Traversal::List,
+ Traversal::Union,
+ Traversal::Complex,
+ Traversal::Type,
+
+ Traversal::AnySimpleType,
+
+ Traversal::Fundamental::String,
+ Traversal::Fundamental::NormalizedString,
+ Traversal::Fundamental::Token,
+ Traversal::Fundamental::Name,
+ Traversal::Fundamental::NameToken,
+ Traversal::Fundamental::NameTokens,
+ Traversal::Fundamental::NCName,
+ Traversal::Fundamental::Language,
+
+ Traversal::Fundamental::QName,
+
+ Traversal::Fundamental::Id,
+ Traversal::Fundamental::IdRef,
+ Traversal::Fundamental::IdRefs,
+
+ Traversal::Fundamental::AnyURI,
+
+ Traversal::Fundamental::Base64Binary,
+ Traversal::Fundamental::HexBinary,
+
+ Traversal::Fundamental::Date,
+ Traversal::Fundamental::DateTime,
+ Traversal::Fundamental::Duration,
+ Traversal::Fundamental::Day,
+ Traversal::Fundamental::Month,
+ Traversal::Fundamental::MonthDay,
+ Traversal::Fundamental::Year,
+ Traversal::Fundamental::YearMonth,
+ Traversal::Fundamental::Time,
+
+ Traversal::Fundamental::Entity,
+ Traversal::Fundamental::Entities,
+
+ Context
+ {
+ InitValue (Context&);
+
+ Void
+ dispatch (SemanticGraph::Node& type, String const& value);
+
+ virtual Void
+ traverse (SemanticGraph::List&);
+
+ virtual Void
+ traverse (SemanticGraph::Union&);
+
+ virtual Void
+ traverse (SemanticGraph::Complex&);
+
+ virtual Void
+ traverse (SemanticGraph::Type& t);
+
+ // anySimpleType.
+ //
+ virtual Void
+ traverse (SemanticGraph::AnySimpleType&);
+
+ // Strings.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::String&);
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NormalizedString&);
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Token&);
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NameToken&);
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NameTokens&);
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Name&);
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NCName&);
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Language&);
+
+ // Qualified name.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::QName&);
+
+ // ID/IDREF.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Id&);
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::IdRef&);
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::IdRefs&);
+
+ // URI.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::AnyURI&);
+
+ // Binary.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Base64Binary&);
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::HexBinary&);
+
+ // Date/time.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Date&);
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::DateTime&);
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Duration&);
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Day&);
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Month&);
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::MonthDay&);
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Year&);
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::YearMonth&);
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Time&);
+
+ // Entity.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Entity&);
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Entities&);
+
+ private:
+ Void
+ string_type (SemanticGraph::Fundamental::Type&);
+
+ Void
+ string_sequence_type ();
+
+ Void
+ time_zone (Size pos);
+
+ private:
+ String member_;
+ String value_;
+ TypeName var_;
+ TypeName var_value_;
+ LiteralValue literal_value_;
+ LiteralValue literal_value_list_;
+ };
+
+ struct CompareValue: Traversal::Union,
+ Traversal::Complex,
+ Traversal::Type,
+ Context
+ {
+ CompareValue (Context&);
+
+ Void
+ dispatch (SemanticGraph::Node& type,
+ String const& lhs,
+ String const& rhs);
+
+ virtual Void
+ traverse (SemanticGraph::Union&);
+
+ virtual Void
+ traverse (SemanticGraph::Complex&);
+
+ virtual Void
+ traverse (SemanticGraph::Type& t);
+
+ private:
+ String const* lhs_;
+ String const* rhs_;
+ };
+ }
+}
+
+#endif // CXX_HYBRID_DEFAULT_VALUE_HXX
diff --git a/xsde/cxx/hybrid/elements.hxx b/xsde/cxx/hybrid/elements.hxx
index 8452976..9faeb8d 100644
--- a/xsde/cxx/hybrid/elements.hxx
+++ b/xsde/cxx/hybrid/elements.hxx
@@ -161,6 +161,18 @@ namespace CXX
}
static String const&
+ edefault (SemanticGraph::Attribute& a)
+ {
+ return a.context ().get<String> ("default");
+ }
+
+ static String const&
+ edefault_value (SemanticGraph::Attribute& a)
+ {
+ return a.context ().get<String> ("default-value");
+ }
+
+ static String const&
epresent_member (SemanticGraph::Particle& p)
{
return p.context ().get<String> ("present-member");
@@ -922,6 +934,7 @@ namespace CXX
ret,
arg,
var,
+ var_value,
seq
};
@@ -1368,6 +1381,11 @@ namespace CXX
break;
}
+ case var_value:
+ {
+ os << fq;
+ break;
+ }
case seq:
{
os << (fixed_length (t) ? fix_seq : var_seq) << "< " <<
@@ -1437,6 +1455,7 @@ namespace CXX
break;
}
case var:
+ case var_value:
{
if (stl)
os << "::std::string";
diff --git a/xsde/cxx/hybrid/extraction-source.cxx b/xsde/cxx/hybrid/extraction-source.cxx
index 5945ce3..5460740 100644
--- a/xsde/cxx/hybrid/extraction-source.cxx
+++ b/xsde/cxx/hybrid/extraction-source.cxx
@@ -108,6 +108,11 @@ namespace CXX
virtual Void
traverse (SemanticGraph::Attribute& a)
{
+ // Nothing is serialized for fixed attributes.
+ //
+ if (a.fixed ())
+ return;
+
SemanticGraph::Type& t (a.type ());
Boolean fl (fixed_length (t));
@@ -125,21 +130,39 @@ namespace CXX
if (a.optional ())
{
- os << "bool p;";
+ if (!a.default_ ())
+ {
+ os << "bool p;";
+
+ if (exceptions)
+ os << "s >> p;";
+ else
+ os << endl
+ << "if (!(s >> p))" << endl
+ << "return false;";
- if (exceptions)
- os << "s >> p;";
- else
os << endl
- << "if (!(s >> p))" << endl
- << "return false;";
+ << "if (p)"
+ << "{";
- os << endl
- << "if (p)"
- << "{";
+ if (fl)
+ os << "x." << epresent (a) << " (true);";
+ }
+ else
+ {
+ os << "bool d;";
- if (fl)
- os << "x." << epresent (a) << " (true);";
+ if (exceptions)
+ os << "s >> d;";
+ else
+ os << endl
+ << "if (!(s >> d))" << endl
+ << "return false;";
+
+ os << endl
+ << "if (!d)"
+ << "{";
+ }
}
if (st)
@@ -181,9 +204,20 @@ namespace CXX
}
if (a.optional ())
- os << "}"
- << "else" << endl
- << "x." << epresent (a) << " (false);";
+ {
+ if (!a.default_ ())
+ {
+ os << "}"
+ << "else" << endl
+ << "x." << epresent (a) << " (false);";
+ }
+ else
+ {
+ os << "}"
+ << "else" << endl
+ << "x." << edefault (a) << " (true);";
+ }
+ }
os << "}";
}
diff --git a/xsde/cxx/hybrid/generator.cxx b/xsde/cxx/hybrid/generator.cxx
index 3eba4ba..78b9142 100644
--- a/xsde/cxx/hybrid/generator.cxx
+++ b/xsde/cxx/hybrid/generator.cxx
@@ -121,6 +121,7 @@ namespace CXX
extern Key suppress_validation = "suppress-validation";
extern Key suppress_parser_val = "suppress-parser-val";
extern Key suppress_serializer_val = "suppress-serializer-val";
+ extern Key omit_default_attributes = "omit-default-attributes";
extern Key generate_detach = "generate-detach";
extern Key generate_insertion = "generate-insertion";
extern Key generate_extraction = "generate-extraction";
@@ -251,6 +252,11 @@ namespace CXX
<< " serializer."
<< endl;
+ e << "--omit-default-attributes" << endl
+ << " Omit attributes with default and fixed values\n"
+ << " from serialized XML documents."
+ << endl;
+
e << "--generate-detach" << endl
<< " Generate detach functions for elements and\n"
<< " attributes of variable-length types."
diff --git a/xsde/cxx/hybrid/insertion-source.cxx b/xsde/cxx/hybrid/insertion-source.cxx
index b0b89c9..7dc6fcb 100644
--- a/xsde/cxx/hybrid/insertion-source.cxx
+++ b/xsde/cxx/hybrid/insertion-source.cxx
@@ -100,19 +100,41 @@ namespace CXX
virtual Void
traverse (SemanticGraph::Attribute& a)
{
+ // Don't waste space on fixed attributes.
+ //
+ if (a.fixed ())
+ return;
+
if (a.optional ())
{
- String const& present (epresent (a));
+ if (!a.default_ ())
+ {
+ String const& present (epresent (a));
- if (exceptions)
- os << "s << x." << present << " ();";
+ if (exceptions)
+ os << "s << x." << present << " ();";
+ else
+ os << "if (!(s << x." << present << " ()))" << endl
+ << "return false;";
+
+ os << endl
+ << "if (x." << present << " ())"
+ << "{";
+ }
else
- os << "if (!(s << x." << present << " ()))" << endl
- << "return false;";
+ {
+ String const& default_ (edefault (a));
- os << endl
- << "if (x." << present << " ())"
- << "{";
+ if (exceptions)
+ os << "s << x." << default_ << " ();";
+ else
+ os << "if (!(s << x." << default_ << " ()))" << endl
+ << "return false;";
+
+ os << endl
+ << "if (!x." << default_ << " ())"
+ << "{";
+ }
}
String const& name (ename (a));
diff --git a/xsde/cxx/hybrid/parser-header.cxx b/xsde/cxx/hybrid/parser-header.cxx
index 6a893c5..c174df4 100644
--- a/xsde/cxx/hybrid/parser-header.cxx
+++ b/xsde/cxx/hybrid/parser-header.cxx
@@ -334,6 +334,9 @@ namespace CXX
virtual Void
traverse (SemanticGraph::Attribute& a)
{
+ if (a.fixed ())
+ return;
+
String const& arg (parg_type (a.type ()));
os << "virtual void" << endl
diff --git a/xsde/cxx/hybrid/parser-source.cxx b/xsde/cxx/hybrid/parser-source.cxx
index 505d661..bfeb129 100644
--- a/xsde/cxx/hybrid/parser-source.cxx
+++ b/xsde/cxx/hybrid/parser-source.cxx
@@ -879,6 +879,9 @@ namespace CXX
{
using SemanticGraph::Complex;
+ if (a.fixed ())
+ return;
+
String const& name (epname (a));
String const& arg (parg_type (a.type ()));
Complex& c (dynamic_cast<Complex&> (a.scope ()));
diff --git a/xsde/cxx/hybrid/serializer-source.cxx b/xsde/cxx/hybrid/serializer-source.cxx
index 540d742..b0c194e 100644
--- a/xsde/cxx/hybrid/serializer-source.cxx
+++ b/xsde/cxx/hybrid/serializer-source.cxx
@@ -886,9 +886,26 @@ namespace CXX
{
os << "bool " << s << "::" << endl
<< espresent (a) << " ()"
- << "{"
- << "return " << access << epresent (a) << " ();"
- << "}";
+ << "{";
+
+ if (a.default_ ())
+ {
+ Boolean omit (options.value<CLI::omit_default_attributes> ());
+
+ if (a.fixed ())
+ os << "return " << (omit ? "false" : "true") << ";";
+ else
+ {
+ if (omit)
+ os << "return !" << access << edefault (a) << " ();";
+ else
+ os << "return true;";
+ }
+ }
+ else
+ os << "return " << access << epresent (a) << " ();";
+
+ os << "}";
}
SemanticGraph::Type& t (a.type ());
diff --git a/xsde/cxx/hybrid/tree-forward.cxx b/xsde/cxx/hybrid/tree-forward.cxx
index 7b2cae6..9bcb6f5 100644
--- a/xsde/cxx/hybrid/tree-forward.cxx
+++ b/xsde/cxx/hybrid/tree-forward.cxx
@@ -350,7 +350,10 @@ namespace CXX
traverse (SemanticGraph::Fundamental::String&)
{
gen_typedef ("string", string_type_);
- gen_using ("::xsde::cxx::hybrid::string_base");
+
+ if (!stl)
+ gen_using ("::xsde::cxx::hybrid::string_base");
+
os << endl;
}
diff --git a/xsde/cxx/hybrid/tree-header.cxx b/xsde/cxx/hybrid/tree-header.cxx
index 3003e4c..77a1c71 100644
--- a/xsde/cxx/hybrid/tree-header.cxx
+++ b/xsde/cxx/hybrid/tree-header.cxx
@@ -369,6 +369,7 @@ namespace CXX
Traversal::Fundamental::Token,
Traversal::Fundamental::Name,
Traversal::Fundamental::NameToken,
+ Traversal::Fundamental::NameTokens,
Traversal::Fundamental::NCName,
Traversal::Fundamental::Language,
@@ -376,6 +377,7 @@ namespace CXX
Traversal::Fundamental::Id,
Traversal::Fundamental::IdRef,
+ Traversal::Fundamental::IdRefs,
Traversal::Fundamental::AnyURI,
@@ -390,6 +392,7 @@ namespace CXX
Traversal::Fundamental::Time,
Traversal::Fundamental::Entity,
+ Traversal::Fundamental::Entities,
Context
{
@@ -636,6 +639,12 @@ namespace CXX
}
virtual Void
+ traverse (SemanticGraph::Fundamental::NameTokens&)
+ {
+ align_type ("size_t");
+ }
+
+ virtual Void
traverse (SemanticGraph::Fundamental::Name&)
{
align_type ("size_t"); // std::string
@@ -676,6 +685,12 @@ namespace CXX
align_type ("size_t"); // std::string
}
+ virtual Void
+ traverse (SemanticGraph::Fundamental::IdRefs&)
+ {
+ align_type ("size_t");
+ }
+
// URI.
//
virtual Void
@@ -749,6 +764,12 @@ namespace CXX
align_type ("size_t"); // std::string
}
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Entities&)
+ {
+ align_type ("size_t");
+ }
+
private:
Void
align_type (Char const* t)
@@ -767,7 +788,17 @@ namespace CXX
private:
Traversal::Inherits inherits_;
- Traversal::Attribute attribute_;
+ struct Attribute: Traversal::Attribute
+ {
+ virtual Void
+ traverse (Type& a)
+ {
+ if (!a.fixed ())
+ Traversal::Attribute::traverse (a);
+ }
+ };
+
+ Attribute attribute_;
Traversal::Names attribute_names_;
Traversal::Element particle_;
@@ -787,13 +818,16 @@ namespace CXX
virtual Void
traverse (SemanticGraph::Attribute& a)
{
- SemanticGraph::Type& t (a.type ());
+ if (!a.fixed ())
+ {
+ SemanticGraph::Type& t (a.type ());
- var_.dispatch (t);
- os << " " << emember (a) << ";";
+ var_.dispatch (t);
+ os << " " << emember (a) << ";";
- if (a.optional () && fixed_length (t))
- os << "bool " << epresent_member (a) << ";";
+ if (a.optional () && !a.default_ () && fixed_length (t))
+ os << "bool " << epresent_member (a) << ";";
+ }
}
private:
@@ -1105,19 +1139,23 @@ namespace CXX
os << "// " << comment (a.name ()) << endl
<< "// " << endl;
+ Boolean def (a.default_ ());
+ Boolean fix (a.fixed ());
+
String const& name (ename (a));
SemanticGraph::Type& t (a.type ());
- if (a.optional ())
+
+ if (a.optional () && !fix)
{
- String const& present (epresent (a));
+ String const& name (def ? edefault (a) : epresent (a));
os << "bool" << endl
- << present << " () const;"
+ << name << " () const;"
<< endl;
os << "void" << endl
- << present << " (bool);"
+ << name << " (bool);"
<< endl;
}
@@ -1129,32 +1167,49 @@ namespace CXX
<< name << " () const;"
<< endl;
- // type&
- // name ()
+ // Do not generate modifiers for fixed attributes.
//
- ret_.dispatch (t);
- os << endl
- << name << " ();"
- << endl;
+ if (!fix)
+ {
+ // type&
+ // name ()
+ //
+ ret_.dispatch (t);
+ os << endl
+ << name << " ();"
+ << endl;
- // void
- // name (const type& | type*)
- //
- os << "void" << endl
- << name << " (";
- arg_.dispatch (t);
- os << ");"
- << endl;
+ // void
+ // name (const type& | type*)
+ //
+ os << "void" << endl
+ << name << " (";
+ arg_.dispatch (t);
+ os << ");"
+ << endl;
- // type*
- // detach ()
- //
- if (detach && !fixed_length (t))
+ // type*
+ // detach ()
+ //
+ if (detach && !fixed_length (t))
+ {
+ arg_.dispatch (t);
+ os << endl
+ << edetach (a) << " ();"
+ << endl;
+ }
+ }
+
+ if (def)
{
- arg_.dispatch (t);
+ // static const type&
+ // name_{default|fixed}_value ()
+ //
+ os << "static ";
+ ro_ret_.dispatch (t);
os << endl
- << edetach (a) << " ();"
+ << edefault_value (a) << " ();"
<< endl;
}
}
diff --git a/xsde/cxx/hybrid/tree-inline.cxx b/xsde/cxx/hybrid/tree-inline.cxx
index 7cb4b2c..2783b5c 100644
--- a/xsde/cxx/hybrid/tree-inline.cxx
+++ b/xsde/cxx/hybrid/tree-inline.cxx
@@ -4,6 +4,7 @@
// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
#include <cxx/hybrid/tree-inline.hxx>
+#include <cxx/hybrid/default-value.hxx>
#include <xsd-frontend/semantic-graph.hxx>
#include <xsd-frontend/traversal.hxx>
@@ -239,36 +240,58 @@ namespace CXX
ret_ (c, TypeName::ret),
arg_ (c, TypeName::arg),
deref_ (c, TypeOps::deref),
- delete_ (c, TypeOps::delete_)
+ delete_ (c, TypeOps::delete_),
+ compare_value_ (c)
{
}
virtual Void
traverse (SemanticGraph::Attribute& a)
{
+ Boolean def (a.default_ ());
+ Boolean fix (a.fixed ());
+
String const& name (ename (a));
- String const& member (emember (a));
+ String member;
+
+ if (!fix)
+ member = emember (a);
SemanticGraph::Type& t (a.type ());
Boolean fl (fixed_length (t));
String scope (Context::scope (a));
- if (a.optional ())
+ if (a.optional () && !fix)
{
- String const& present (epresent (a));
+ String const& name (def ? edefault (a) : epresent (a));
// bool
// preset () const;
//
os << inl
<< "bool " << scope << "::" << endl
- << present << " () const"
+ << name << " () const"
<< "{";
- if (fl)
- os << "return this->" << epresent_member (a) << ";";
+ if (def)
+ {
+ if (fl)
+ {
+ os << "return ";
+ compare_value_.dispatch (
+ t, L"this->" + member, edefault_value (a) + L" ()");
+ os << ";";
+ }
+ else
+ os << "return this->" << member << " == 0;";
+ }
else
- os << "return this->" << member << " != 0;";
+ {
+ if (fl)
+ os << "return this->" << epresent_member (a) << ";";
+ else
+ os << "return this->" << member << " != 0;";
+ }
os << "}";
@@ -277,19 +300,41 @@ namespace CXX
//
os << inl
<< "void " << scope << "::" << endl
- << present << " (bool x)"
+ << name << " (bool x)"
<< "{";
- if (fl)
- os << "this->" << epresent_member (a) << " = x;";
+ if (def)
+ {
+ os << "if (x)";
+
+ if (fl)
+ {
+ os << endl
+ << "this->" << member << " = " << edefault_value (a) <<
+ " ();";
+ }
+ else
+ {
+ os << "{";
+ delete_.dispatch (t);
+ os << " this->" << member << ";"
+ << "this->" << member << " = 0;"
+ << "}";
+ }
+ }
else
{
- os << "if (!x)"
- << "{";
- delete_.dispatch (t);
- os << " this->" << member << ";"
- << "this->" << member << " = 0;"
- << "}";
+ if (fl)
+ os << "this->" << epresent_member (a) << " = x;";
+ else
+ {
+ os << "if (!x)"
+ << "{";
+ delete_.dispatch (t);
+ os << " this->" << member << ";"
+ << "this->" << member << " = 0;"
+ << "}";
+ }
}
os << "}";
@@ -302,65 +347,109 @@ namespace CXX
ro_ret_.dispatch (t);
os << " " << scope << "::" << endl
<< name << " () const"
- << "{"
- << "return ";
- deref_.dispatch (t);
- os << "this->" << member << ";"
- << "}";
-
- // type&
- // name ()
- //
- os << inl;
- ret_.dispatch (t);
- os << " " << scope << "::" << endl
- << name << " ()"
- << "{"
- << "return ";
- deref_.dispatch (t);
- os << "this->" << member << ";"
- << "}";
-
-
- // void
- // name (const type& | type*)
- //
- os << inl
- << "void " << scope << "::" << endl
- << name << " (";
- arg_.dispatch (t);
- os << " x)"
<< "{";
- if (!fl)
+ if (fix)
{
- delete_.dispatch (t);
- os << " this->" << member << ";";
+ os << "return " << edefault_value (a) << " ();";
+ }
+ else if (def)
+ {
+ if (fl)
+ os << "return this->" << member << ";";
+ else
+ {
+ os << "return this->" << member << " ? ";
+ deref_.dispatch (t);
+ os << "this->" << member << " : " <<
+ edefault_value (a) << " ();";
+ }
+ }
+ else
+ {
+ os << "return ";
+ deref_.dispatch (t);
+ os << "this->" << member << ";";
}
-
- os << "this->" << member << " = x;";
-
- if (fl && a.optional ())
- os << "this->" << epresent_member (a) << " = true;";
os << "}";
-
- // type*
- // detach ()
+ // Do not generate modifiers for fixed attributes.
//
- if (detach && !fl)
+ if (!fix)
{
+ // type&
+ // name ()
+ //
os << inl;
- arg_.dispatch (t);
+ ret_.dispatch (t);
os << " " << scope << "::" << endl
- << edetach (a) << " ()"
+ << name << " ()"
<< "{";
+
+ if (def)
+ {
+ if (fl)
+ os << "return this->" << member << ";";
+ else
+ {
+ os << "return this->" << member << " ? ";
+ deref_.dispatch (t);
+ os << "this->" << member << " : const_cast< ";
+ ret_.dispatch (t);
+ os << " > (" << edefault_value (a) << " ());";
+ }
+ }
+ else
+ {
+ os << "return ";
+ deref_.dispatch (t);
+ os << "this->" << member << ";";
+ }
+
+ os << "}";
+
+
+ // void
+ // name (const type& | type*)
+ //
+ os << inl
+ << "void " << scope << "::" << endl
+ << name << " (";
arg_.dispatch (t);
- os << " r = this->" << member << ";"
- << "this->" << member << " = 0;"
- << "return r;"
- << "}";
+ os << " x)"
+ << "{";
+
+ if (!fl)
+ {
+ delete_.dispatch (t);
+ os << " this->" << member << ";";
+ }
+
+ os << "this->" << member << " = x;";
+
+ if (fl && !def && a.optional ())
+ os << "this->" << epresent_member (a) << " = true;";
+
+ os << "}";
+
+
+ // type*
+ // detach ()
+ //
+ if (detach && !fl)
+ {
+ os << inl;
+ arg_.dispatch (t);
+ os << " " << scope << "::" << endl
+ << edetach (a) << " ()"
+ << "{";
+ arg_.dispatch (t);
+ os << " r = this->" << member << ";"
+ << "this->" << member << " = 0;"
+ << "return r;"
+ << "}";
+ }
}
}
@@ -370,6 +459,7 @@ namespace CXX
TypeName arg_;
TypeOps deref_;
TypeOps delete_;
+ CompareValue compare_value_;
};
struct ElementFunc: Traversal::Element, Context
diff --git a/xsde/cxx/hybrid/tree-name-processor.cxx b/xsde/cxx/hybrid/tree-name-processor.cxx
index 9308598..da128c0 100644
--- a/xsde/cxx/hybrid/tree-name-processor.cxx
+++ b/xsde/cxx/hybrid/tree-name-processor.cxx
@@ -546,28 +546,41 @@ namespace CXX
{
SemanticGraph::Context& ac (a.context ());
+ Boolean def (a.default_ ());
+ Boolean fix (a.fixed ());
+
+ String const& base (ac.get<String> ("name"));
+
if (!data_members_)
{
- if (a.optional ())
- ac.set (
- "present",
- find_name (ac.get<String> ("name") + L"_present", set_));
+ if (a.optional () && !fix)
+ {
+ String n;
+ if (def)
+ n = find_name (base + L"_default", set_);
+ else
+ n = find_name (base + L"_present", set_);
- if (detach && !fixed_length (a.type ()))
- ac.set (
- "detach",
- find_name (ac.get<String> ("name") + L"_detach", set_));
+ ac.set (def ? "default" : "present", n);
+ }
+
+ if (detach && !fix && !fixed_length (a.type ()))
+ ac.set ("detach", find_name (base + L"_detach", set_));
+ if (def)
+ {
+ ac.set (
+ "default-value",
+ find_name (base + (fix ? L"_fixed_value" : L"_default_value"),
+ set_));
+ }
}
- else
+ else if (!fix)
{
- String const& base (ac.get<String> ("name"));
-
- if (a.optional ())
+ if (a.optional () && !a.default_ () && fixed_length (a.type ()))
{
- if (fixed_length (a.type ()))
- ac.set ("present-member",
- find_name (ac.get<String> ("present") + L"_", set_));
+ ac.set ("present-member",
+ find_name (ac.get<String> ("present") + L"_", set_));
}
ac.set ("member", find_name (base + L"_", set_));
diff --git a/xsde/cxx/hybrid/tree-source.cxx b/xsde/cxx/hybrid/tree-source.cxx
index 2723046..eb83658 100644
--- a/xsde/cxx/hybrid/tree-source.cxx
+++ b/xsde/cxx/hybrid/tree-source.cxx
@@ -4,6 +4,7 @@
// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
#include <cxx/hybrid/tree-source.hxx>
+#include <cxx/hybrid/default-value.hxx>
#include <xsd-frontend/semantic-graph.hxx>
#include <xsd-frontend/traversal.hxx>
@@ -169,6 +170,73 @@ namespace CXX
}
};
+
+ struct AttributeFunc: Traversal::Attribute, Context
+ {
+ AttributeFunc (Context& c)
+ : Context (c),
+ var_ (c, TypeName::var_value),
+ ro_ret_ (c, TypeName::ro_ret),
+ literal_value_ (c),
+ init_value_ (c)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Attribute& a)
+ {
+ if (a.default_ ())
+ {
+ SemanticGraph::Type& t (a.type ());
+
+ String literal (literal_value_.dispatch (t, a.value ()));
+ String init;
+
+ if (!literal)
+ {
+ String const& name (ename (a));
+ String const& scope_name (ename (a.scope ()));
+
+ init = L"_xsde_" + scope_name + L"_" + name + L"_default_value";
+
+ os << "struct " << init
+ << "{"
+ << init << " ()"
+ << "{";
+ init_value_.dispatch (t, a.value ());
+ os << "}";
+
+ var_.dispatch (t);
+ os << " value_;"
+ << "};"
+ << "static const " << init << " " << init << "_;"
+ << endl;
+ }
+
+ // static const type&
+ // name_{default|fixed}_value ()
+ //
+ ro_ret_.dispatch (t);
+ os << " " << scope (a) << "::" << endl
+ << edefault_value (a) << " ()"
+ << "{";
+
+ if (literal)
+ os << "return " << literal << ";";
+ else
+ os << "return " << init << "_.value_;";
+
+ os << "}";
+ }
+ }
+
+ private:
+ TypeName var_;
+ TypeName ro_ret_;
+ LiteralValue literal_value_;
+ InitValue init_value_;
+ };
+
struct ChoiceParticle: Traversal::Element,
Traversal::Compositor,
Context
@@ -600,13 +668,24 @@ namespace CXX
virtual Void
traverse (SemanticGraph::Attribute& a)
{
- Boolean fl (fixed_length (a.type ()));
+ if (!a.fixed ())
+ {
+ Boolean def (a.default_ ());
+ Boolean fl (fixed_length (a.type ()));
- if (!fl)
- os << "this->" << emember (a) << " = 0;";
+ if (!fl)
+ {
+ os << "this->" << emember (a) << " = 0;";
+ }
+ else if (def)
+ {
+ os << "this->" << emember (a) << " = " <<
+ edefault_value (a) << " ();";
+ }
- if (fl && a.optional ())
- os << "this->" << epresent_member (a) << " = false;";
+ if (fl && !def && a.optional ())
+ os << "this->" << epresent_member (a) << " = false;";
+ }
}
};
@@ -726,12 +805,15 @@ namespace CXX
virtual Void
traverse (SemanticGraph::Attribute& a)
{
- SemanticGraph::Type& t (a.type ());
-
- if (!fixed_length (t))
+ if (!a.fixed ())
{
- delete_.dispatch (t);
- os << " this->" << emember (a) << ";";
+ SemanticGraph::Type& t (a.type ());
+
+ if (!fixed_length (t))
+ {
+ delete_.dispatch (t);
+ os << " this->" << emember (a) << ";";
+ }
}
}
@@ -852,17 +934,20 @@ namespace CXX
virtual Void
traverse (SemanticGraph::Attribute& a)
{
- String const& member (emember (a));
-
- if (a.optional ())
+ if (!a.fixed ())
{
- String const& present_member (epresent_member (a));
+ String const& member (emember (a));
- os << "this->" << present_member << " = x." << present_member << ";"
- << "if (this->" << present_member << ")" << endl;
- }
+ if (a.optional () && !a.default_ ())
+ {
+ String const& present (epresent_member (a));
- os << "this->" << member << " = x." << member << ";";
+ os << "this->" << present << " = x." << present << ";"
+ << "if (this->" << present << ")" << endl;
+ }
+
+ os << "this->" << member << " = x." << member << ";";
+ }
}
};
@@ -993,17 +1078,20 @@ namespace CXX
virtual Void
traverse (SemanticGraph::Attribute& a)
{
- String const& member (emember (a));
-
- if (a.optional ())
+ if (!a.fixed ())
{
- String const& present_member (epresent_member (a));
+ String const& member (emember (a));
- os << "this->" << present_member << " = x." << present_member << ";"
- << "if (this->" << present_member << ")" << endl;
- }
+ if (a.optional () && !a.default_ ())
+ {
+ String const& present (epresent_member (a));
- os << "this->" << member << " = x." << member << ";";
+ os << "this->" << present << " = x." << present << ";"
+ << "if (this->" << present << ")" << endl;
+ }
+
+ os << "this->" << member << " = x." << member << ";";
+ }
}
};
@@ -1451,6 +1539,7 @@ namespace CXX
// Functions.
//
+ attribute_func_ (c),
choice_in_choice_func_ (c, true),
choice_in_sequence_func_ (c, false),
sequence_in_choice_func_ (c, true),
@@ -1516,6 +1605,8 @@ namespace CXX
{
// Functions.
//
+ attribute_names_func_ >> attribute_func_;
+
sequence_in_choice_func_ >> sequence_contains_func_;
sequence_in_sequence_func_ >> sequence_contains_func_;
sequence_contains_func_ >> choice_in_sequence_func_;
@@ -1713,6 +1804,8 @@ namespace CXX
// Functions.
//
+ Complex::names (c, attribute_names_func_);
+
if (c.contains_compositor_p ())
Complex::contains_compositor (c, contains_compositor_func_);
}
@@ -1770,6 +1863,9 @@ namespace CXX
// Functions.
//
+ AttributeFunc attribute_func_;
+ Traversal::Names attribute_names_func_;
+
ChoiceFunc choice_in_choice_func_;
ChoiceFunc choice_in_sequence_func_;
SequenceFunc sequence_in_choice_func_;
@@ -1855,6 +1951,11 @@ namespace CXX
{
// Needed for placement new.
//
+ ctx.os << "#include <stdlib.h>" << endl; // strtod, exit
+
+ if (!ctx.exceptions)
+ ctx.os << "#include <assert.h>" << endl;
+
ctx.os << "#include <new>" << endl
<< endl;