summaryrefslogtreecommitdiff
path: root/xsd/cxx/tree/default-value.cxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2009-12-14 17:32:14 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2009-12-14 17:32:14 +0200
commitaf83df9be50a9383d0c54fb24b8e486a658a2a02 (patch)
tree5d937c9015c6438a60122743c7fb72ec30de32be /xsd/cxx/tree/default-value.cxx
parentc12b36470adb57100f1d5f22e3ddd6fc163f6ab4 (diff)
New default/fixed value initialization code
Now the default/fixed values are parsed by the compiler at compile time instead of the standard parsing code at runtime.
Diffstat (limited to 'xsd/cxx/tree/default-value.cxx')
-rw-r--r--xsd/cxx/tree/default-value.cxx971
1 files changed, 971 insertions, 0 deletions
diff --git a/xsd/cxx/tree/default-value.cxx b/xsd/cxx/tree/default-value.cxx
new file mode 100644
index 0000000..ee39931
--- /dev/null
+++ b/xsd/cxx/tree/default-value.cxx
@@ -0,0 +1,971 @@
+// file : xsd/cxx/tree/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/tree/default-value.hxx>
+
+namespace CXX
+{
+ namespace Tree
+ {
+ 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);
+ }
+
+ Void
+ make_float (String& s)
+ {
+ if (s.find ('.') == String::npos &&
+ s.find ('e') == String::npos &&
+ s.find ('E') == String::npos)
+ s += L".0";
+ }
+ }
+
+ //
+ // IsLiteralValue
+ //
+
+ IsLiteralValue::
+ IsLiteralValue (Boolean& r)
+ : IsFundamentalType (r)
+ {
+ *this >> inherits_ >> *this;
+ }
+
+ Void IsLiteralValue::
+ traverse (SemanticGraph::Complex& c)
+ {
+ inherits (c);
+ }
+
+ //
+ // LiteralValue
+ //
+
+ LiteralValue::
+ LiteralValue (Context& c)
+ : Context (c)
+ {
+ *this >> inherits_ >> *this;
+ }
+
+ String LiteralValue::
+ dispatch (SemanticGraph::Node& type, String const& value)
+ {
+ literal_.clear ();
+ value_ = value;
+ Traversal::NodeBase::dispatch (type);
+ return literal_;
+ }
+
+ Void LiteralValue::
+ traverse (SemanticGraph::Complex& c)
+ {
+ inherits (c);
+ }
+
+ // Boolean.
+ //
+ Void LiteralValue::
+ traverse (SemanticGraph::Fundamental::Boolean&)
+ {
+ collapse (value_);
+ literal_ = (value_ == L"true" || value_ == L"1") ? L"true" : L"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_ += L"LL";
+ }
+
+ Void LiteralValue::
+ traverse (SemanticGraph::Fundamental::UnsignedLong&)
+ {
+ collapse (value_);
+ strip_zeros (value_);
+ literal_ = value_;
+ literal_ += L"ULL";
+ }
+
+ Void LiteralValue::
+ traverse (SemanticGraph::Fundamental::Integer&)
+ {
+ collapse (value_);
+ strip_zeros (value_);
+ literal_ = value_ + L"LL";
+ }
+
+ Void LiteralValue::
+ traverse (SemanticGraph::Fundamental::NonPositiveInteger&)
+ {
+ collapse (value_);
+ strip_zeros (value_);
+ literal_ = value_ + L"LL";
+ }
+
+ Void LiteralValue::
+ traverse (SemanticGraph::Fundamental::NonNegativeInteger&)
+ {
+ collapse (value_);
+ strip_zeros (value_);
+ literal_ = value_ + L"ULL";
+ }
+
+ Void LiteralValue::
+ traverse (SemanticGraph::Fundamental::PositiveInteger&)
+ {
+ collapse (value_);
+ strip_zeros (value_);
+ literal_ = value_ + L"ULL";
+ }
+
+ Void LiteralValue::
+ traverse (SemanticGraph::Fundamental::NegativeInteger&)
+ {
+ collapse (value_);
+ strip_zeros (value_);
+ literal_ = value_ + L"LL";
+ }
+
+ // Floats.
+ //
+ Void LiteralValue::
+ traverse (SemanticGraph::Fundamental::Float& t)
+ {
+ collapse (value_);
+
+ if (value_ == L"NaN")
+ {
+ literal_ = L"::std::numeric_limits< " + fq_name (t) +
+ L" >::quiet_NaN ()";
+ }
+ else if (value_ == L"INF")
+ {
+ literal_ = L"::std::numeric_limits< " + fq_name (t) +
+ L" >::infinity ()";
+ }
+ else if (value_ == L"-INF")
+ {
+ literal_ = L"- ::std::numeric_limits< " + fq_name (t) +
+ L" >::infinity ()";
+ }
+ else
+ {
+ strip_zeros (value_);
+ make_float (value_);
+ literal_ = value_ + L"F";
+ }
+ }
+
+ Void LiteralValue::
+ traverse (SemanticGraph::Fundamental::Double& t)
+ {
+ collapse (value_);
+
+ if (value_ == L"NaN")
+ {
+ literal_ = L"::std::numeric_limits< " + fq_name (t) +
+ L" >::quiet_NaN ()";
+ }
+ else if (value_ == L"INF")
+ {
+ literal_ = L"::std::numeric_limits< " + fq_name (t) +
+ L" >::infinity ()";
+ }
+ else if (value_ == L"-INF")
+ {
+ literal_ = L"- ::std::numeric_limits< " + fq_name (t) +
+ L" >::infinity ()";
+ }
+ else
+ {
+ strip_zeros (value_);
+ make_float (value_);
+ literal_ = value_;
+ }
+ }
+
+ Void LiteralValue::
+ traverse (SemanticGraph::Fundamental::Decimal&)
+ {
+ collapse (value_);
+ strip_zeros (value_);
+ make_float (value_);
+ literal_ = value_;
+ }
+
+ //
+ // InitValue
+ //
+
+ IsSimpleInit::
+ IsSimpleInit (Boolean& r)
+ : r_ (r)
+ {
+ *this >> inherits_ >> *this;
+ }
+
+ Void IsSimpleInit::
+ traverse (SemanticGraph::List&)
+ {
+ r_ = false;
+ }
+
+ Void IsSimpleInit::
+ traverse (SemanticGraph::Complex& c)
+ {
+ inherits (c);
+ }
+
+ Void IsSimpleInit::
+ traverse (SemanticGraph::Fundamental::NameTokens&)
+ {
+ r_ = false;
+ }
+
+ Void IsSimpleInit::
+ traverse (SemanticGraph::Fundamental::IdRefs&)
+ {
+ r_ = false;
+ }
+
+ Void IsSimpleInit::
+ traverse (SemanticGraph::Fundamental::Entities&)
+ {
+ r_ = false;
+ }
+
+ //
+ // InitValue
+ //
+
+ InitValue::
+ InitValue (Context& c)
+ : Context (c), type_name_ (c), literal_value_ (c)
+ {
+ }
+
+ Void InitValue::
+ dispatch (SemanticGraph::Node& type, String const& value)
+ {
+ value_ = value;
+ Traversal::NodeBase::dispatch (type);
+ }
+
+ Void InitValue::
+ traverse (SemanticGraph::List& l)
+ {
+ collapse (value_);
+
+ if (!value_)
+ return;
+
+ SemanticGraph::Type& t (l.argumented ().type ());
+
+ String ov (value_);
+ Size b (0);
+
+ for (Size e (ov.find (' ')); ; e = ov.find (' ', b))
+ {
+ String v (ov, b, e != String::npos ? e - b : e);
+
+ os << "{";
+ type_name_.dispatch (t);
+ os << " tmp (";
+
+ String lit (literal_value_.dispatch (t, v));
+
+ if (lit)
+ os << lit;
+ else
+ {
+ value_ = v;
+ Traversal::NodeBase::dispatch (t);
+ }
+
+ os << ");"
+ << "r.push_back (tmp);"
+ << "}";
+
+ if (e == String::npos)
+ break;
+
+ b = e + 1;
+ }
+
+ value_ = ov;
+ }
+
+ Void InitValue::
+ traverse (SemanticGraph::Union&)
+ {
+ os << strlit (value_);
+ }
+
+ Void InitValue::
+ traverse (SemanticGraph::Complex& c)
+ {
+ Traversal::NodeBase::dispatch (ultimate_base (c));
+ }
+
+ // anySimpleType.
+ //
+ Void InitValue::
+ traverse (SemanticGraph::AnySimpleType&)
+ {
+ }
+
+ // Strings.
+ //
+ Void InitValue::
+ traverse (SemanticGraph::Fundamental::String&)
+ {
+ os << strlit (value_);
+ }
+
+ Void InitValue::
+ traverse (SemanticGraph::Fundamental::NormalizedString&)
+ {
+ normalize (value_);
+ os << strlit (value_);
+ }
+
+ Void InitValue::
+ traverse (SemanticGraph::Fundamental::Token&)
+ {
+ collapse (value_);
+ os << strlit (value_);
+ }
+
+ Void InitValue::
+ traverse (SemanticGraph::Fundamental::NameToken&)
+ {
+ collapse (value_);
+ os << strlit (value_);
+ }
+
+ Void InitValue::
+ traverse (SemanticGraph::Fundamental::NameTokens&)
+ {
+ string_sequence_type (
+ dynamic_cast<SemanticGraph::Type&> (
+ xs_ns ().find ("NMTOKEN").first->named ()));
+ }
+
+ Void InitValue::
+ traverse (SemanticGraph::Fundamental::Name&)
+ {
+ collapse (value_);
+ os << strlit (value_);
+ }
+
+ Void InitValue::
+ traverse (SemanticGraph::Fundamental::NCName&)
+ {
+ collapse (value_);
+ os << strlit (value_);
+ }
+
+ Void InitValue::
+ traverse (SemanticGraph::Fundamental::Language&)
+ {
+ collapse (value_);
+ os << strlit (value_);
+ }
+
+ // Qualified name.
+ //
+ Void InitValue::
+ traverse (SemanticGraph::Fundamental::QName&)
+ {
+ }
+
+ // ID/IDREF.
+ //
+ Void InitValue::
+ traverse (SemanticGraph::Fundamental::Id&)
+ {
+ collapse (value_);
+ os << strlit (value_);
+ }
+
+ Void InitValue::
+ traverse (SemanticGraph::Fundamental::IdRef&)
+ {
+ collapse (value_);
+ os << strlit (value_);
+ }
+
+ Void InitValue::
+ traverse (SemanticGraph::Fundamental::IdRefs&)
+ {
+ string_sequence_type (
+ dynamic_cast<SemanticGraph::Type&> (
+ xs_ns ().find ("IDREF").first->named ()));
+ }
+
+ // URI.
+ //
+ Void InitValue::
+ traverse (SemanticGraph::Fundamental::AnyURI&)
+ {
+ collapse (value_);
+ os << strlit (value_);
+ }
+
+ // 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 << year << ", " << month << ", " << 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);
+ make_float (seconds);
+
+ os << year << ", " << month << ", " << day << ", "
+ << hours << ", " << minutes << ", " << 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 << "true, ";
+ b++;
+ }
+ else
+ os << "false, ";
+
+ e = find_delim (value_, b);
+
+ if (e < n && value_[e] == 'Y')
+ {
+ String v (value_, b, e - b);
+ strip_zeros (v);
+ os << v << ", ";
+
+ b = e + 1;
+ e = find_delim (value_, b);
+ }
+ else
+ os << "0, ";
+
+ if (e < n && value_[e] == 'M')
+ {
+ String v (value_, b, e - b);
+ strip_zeros (v);
+ os << v << ", ";
+
+ b = e + 1;
+ e = find_delim (value_, b);
+ }
+ else
+ os << "0, ";
+
+ if (e < n && value_[e] == 'D')
+ {
+ String v (value_, b, e - b);
+ strip_zeros (v);
+ os << v << ", ";
+
+ b = e + 1;
+ e = find_delim (value_, b);
+ }
+ else
+ os << "0, ";
+
+ 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 << v << ", ";
+
+ b = e + 1;
+ e = find_delim (value_, b);
+ }
+ else
+ os << "0, ";
+
+ if (e < n && value_[e] == 'M')
+ {
+ String v (value_, b, e - b);
+ strip_zeros (v);
+ os << v << ", ";
+
+ b = e + 1;
+ e = find_delim (value_, b);
+ }
+ else
+ os << "0, ";
+
+ if (e < n && value_[e] == 'S')
+ {
+ String v (value_, b, e - b);
+ strip_zeros (v);
+ make_float (v);
+ os << v;
+
+ b = e + 1;
+ e = find_delim (value_, b);
+ }
+ else
+ os << "0.0";
+ }
+
+ Void InitValue::
+ traverse (SemanticGraph::Fundamental::Day&)
+ {
+ // gday := ---DD[Z|(+|-)HH:MM]
+ //
+ collapse (value_);
+
+ String day (value_, 3, 2);
+ strip_zeros (day);
+
+ os << 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 << 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 << month << ", " << 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 << 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 << year << ", " << 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);
+ make_float (seconds);
+
+ os << hours << ", " << minutes << ", " << 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 << ", " << h << ", " << m;
+ }
+ }
+
+ // Entity.
+ //
+ Void InitValue::
+ traverse (SemanticGraph::Fundamental::Entity&)
+ {
+ collapse (value_);
+ os << strlit (value_);
+ }
+
+ Void InitValue::
+ traverse (SemanticGraph::Fundamental::Entities&)
+ {
+ string_sequence_type (
+ dynamic_cast<SemanticGraph::Type&> (
+ xs_ns ().find ("ENTITY").first->named ()));
+ }
+
+ Void InitValue::
+ string_sequence_type (SemanticGraph::Type& t)
+ {
+ 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 << "{";
+ type_name_.dispatch (t);
+ os << " tmp (" << strlit (v) << ");"
+ << "r.push_back (tmp);"
+ << "}";
+
+ if (e == String::npos)
+ break;
+
+ b = e + 1;
+ }
+ }
+ }
+}