From 8336dd4c16d4885989a6d8f0c83a4b401f5cb63b Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Thu, 2 Apr 2009 12:22:38 +0200 Subject: 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 --- xsde/cxx/hybrid/cli.hxx | 2 + xsde/cxx/hybrid/default-value.cxx | 1210 +++++++++++++++++++++++++++++++ xsde/cxx/hybrid/default-value.hxx | 366 ++++++++++ xsde/cxx/hybrid/elements.hxx | 19 + xsde/cxx/hybrid/extraction-source.cxx | 62 +- xsde/cxx/hybrid/generator.cxx | 6 + xsde/cxx/hybrid/insertion-source.cxx | 38 +- xsde/cxx/hybrid/parser-header.cxx | 3 + xsde/cxx/hybrid/parser-source.cxx | 3 + xsde/cxx/hybrid/serializer-source.cxx | 23 +- xsde/cxx/hybrid/tree-forward.cxx | 5 +- xsde/cxx/hybrid/tree-header.cxx | 115 ++- xsde/cxx/hybrid/tree-inline.cxx | 216 ++++-- xsde/cxx/hybrid/tree-name-processor.cxx | 43 +- xsde/cxx/hybrid/tree-source.cxx | 153 +++- xsde/makefile | 3 +- 16 files changed, 2105 insertions(+), 162 deletions(-) create mode 100644 xsde/cxx/hybrid/default-value.cxx create mode 100644 xsde/cxx/hybrid/default-value.hxx (limited to 'xsde') 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, generate_extraction, Cult::Containers::Vector, 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 +// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include + +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 () ? L"L" : L"LL"; + } + + Void LiteralValue:: + traverse (SemanticGraph::Fundamental::UnsignedLong&) + { + collapse (value_); + strip_zeros (value_); + literal_ = value_; + literal_ += options.value () ? 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 ("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 ("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 +// 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 +#include + +#include + +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 ("default"); + } + + static String const& + edefault_value (SemanticGraph::Attribute& a) + { + return a.context ().get ("default-value"); + } + + static String const& epresent_member (SemanticGraph::Particle& p) { return p.context ().get ("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 (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 ()); + + 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 +#include #include #include @@ -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 ("name")); + if (!data_members_) { - if (a.optional ()) - ac.set ( - "present", - find_name (ac.get ("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 ("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 ("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 ("present") + L"_", set_)); + ac.set ("present-member", + find_name (ac.get ("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 +#include #include #include @@ -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 " << endl; // strtod, exit + + if (!ctx.exceptions) + ctx.os << "#include " << endl; + ctx.os << "#include " << endl << endl; diff --git a/xsde/makefile b/xsde/makefile index a8a4928..75a55a4 100644 --- a/xsde/makefile +++ b/xsde/makefile @@ -53,6 +53,7 @@ cxx_tun += cxx/serializer/elements.cxx \ cxx_tun += cxx/hybrid/elements.cxx \ cxx/hybrid/validator.cxx \ cxx/hybrid/generator.cxx \ + cxx/hybrid/default-value.cxx \ cxx/hybrid/tree-size-processor.cxx \ cxx/hybrid/tree-name-processor.cxx \ cxx/hybrid/tree-forward.cxx \ @@ -75,13 +76,11 @@ cxx_tun += cxx/hybrid/elements.cxx \ cxx/hybrid/serializer-aggregate-header.cxx \ cxx/hybrid/serializer-aggregate-source.cxx - # Type map # cxx_tun += type-map/lexer.cxx \ type-map/parser.cxx - # Processing # cxx_tun += processing/inheritance/processor.cxx -- cgit v1.1