From af83df9be50a9383d0c54fb24b8e486a658a2a02 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 14 Dec 2009 17:32:14 +0200 Subject: 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. --- NEWS | 6 + tests/cxx/tree/default/driver.cxx | 48 -- tests/cxx/tree/default/general/driver.cxx | 39 ++ tests/cxx/tree/default/general/makefile | 83 +++ tests/cxx/tree/default/general/output | 28 + tests/cxx/tree/default/general/test.xml | 16 + tests/cxx/tree/default/general/test.xsd | 231 +++++++ tests/cxx/tree/default/makefile | 81 +-- tests/cxx/tree/default/omit/driver.cxx | 48 ++ tests/cxx/tree/default/omit/makefile | 83 +++ tests/cxx/tree/default/omit/output | 21 + tests/cxx/tree/default/omit/test.xml | 9 + tests/cxx/tree/default/omit/test.xsd | 30 + tests/cxx/tree/default/output | 26 - tests/cxx/tree/default/test.xml | 11 - tests/cxx/tree/default/test.xsd | 39 -- xsd/cxx/tree/default-value.cxx | 971 ++++++++++++++++++++++++++++++ xsd/cxx/tree/default-value.hxx | 327 ++++++++++ xsd/cxx/tree/name-processor.cxx | 26 +- xsd/cxx/tree/tree-header.cxx | 50 +- xsd/cxx/tree/tree-inline.cxx | 32 +- xsd/cxx/tree/tree-source.cxx | 72 +-- xsd/makefile | 1 + 23 files changed, 2016 insertions(+), 262 deletions(-) delete mode 100644 tests/cxx/tree/default/driver.cxx create mode 100644 tests/cxx/tree/default/general/driver.cxx create mode 100644 tests/cxx/tree/default/general/makefile create mode 100644 tests/cxx/tree/default/general/output create mode 100644 tests/cxx/tree/default/general/test.xml create mode 100644 tests/cxx/tree/default/general/test.xsd create mode 100644 tests/cxx/tree/default/omit/driver.cxx create mode 100644 tests/cxx/tree/default/omit/makefile create mode 100644 tests/cxx/tree/default/omit/output create mode 100644 tests/cxx/tree/default/omit/test.xml create mode 100644 tests/cxx/tree/default/omit/test.xsd delete mode 100644 tests/cxx/tree/default/output delete mode 100644 tests/cxx/tree/default/test.xml delete mode 100644 tests/cxx/tree/default/test.xsd create mode 100644 xsd/cxx/tree/default-value.cxx create mode 100644 xsd/cxx/tree/default-value.hxx diff --git a/NEWS b/NEWS index dfbb46d..01f7463 100644 --- a/NEWS +++ b/NEWS @@ -60,6 +60,12 @@ Version 3.3.0 can process parts of the document as they become available as well as handle documents that are too large to fit into memory. + * New default/fixed value initialization code. Now the default/fixed values + are parsed by the XSD compiler at compile time instead of the standard + parsing code at runtime. This will allow compiling schemas that use the + default/fixed values without support for XML parsing (--suppress-parsing + option). + * Empty XML Schema enumeration values are now mapped to the 'empty' C++ enumerator name instead of 'cxx'. diff --git a/tests/cxx/tree/default/driver.cxx b/tests/cxx/tree/default/driver.cxx deleted file mode 100644 index 3c71222..0000000 --- a/tests/cxx/tree/default/driver.cxx +++ /dev/null @@ -1,48 +0,0 @@ -// file : tests/cxx/tree/default/driver.cxx -// author : Boris Kolpackov -// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC -// license : GNU GPL v2 + exceptions; see accompanying LICENSE file - -// Test default attribute/element values. -// - -#include // std::auto_ptr -#include - -#include "test.hxx" - -using namespace std; -using namespace test; - -int -main (int argc, char* argv[]) -{ - if (argc != 2) - { - cerr << "usage: " << argv[0] << " test.xml" << endl; - return 1; - } - - try - { - auto_ptr r (root (argv[1], xml_schema::flags::dont_validate)); - - cout << *r << endl - << "default x: " << derived::x_default_value () << endl - << "default y: " << derived::y_default_value () << endl - << "fixed p: " << derived::p_default_value () << endl - << "fixed q1: " << derived::q1_default_value () << endl - << "fixed q2: " << derived::q2_default_value () << endl; - - // Serialize. - // - xml_schema::namespace_infomap map; - map["t"].name = "test"; - root (cout, *r, map); - } - catch (xml_schema::exception const& e) - { - cerr << e << endl; - return 1; - } -} diff --git a/tests/cxx/tree/default/general/driver.cxx b/tests/cxx/tree/default/general/driver.cxx new file mode 100644 index 0000000..e588a6b --- /dev/null +++ b/tests/cxx/tree/default/general/driver.cxx @@ -0,0 +1,39 @@ +// file : tests/cxx/tree/default/general/driver.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +// Test default attribute/element values. +// + +#include // std::auto_ptr +#include + +#include "test.hxx" + +using namespace std; +using namespace test; + +int +main (int argc, char* argv[]) +{ + if (argc != 2) + { + cerr << "usage: " << argv[0] << " test.xml" << endl; + return 1; + } + + try + { + auto_ptr r (root (argv[1], xml_schema::flags::dont_validate)); + + xml_schema::namespace_infomap map; + map["t"].name = "test"; + root (cout, *r, map); + } + catch (xml_schema::exception const& e) + { + cerr << e << endl; + return 1; + } +} diff --git a/tests/cxx/tree/default/general/makefile b/tests/cxx/tree/default/general/makefile new file mode 100644 index 0000000..78dd1c4 --- /dev/null +++ b/tests/cxx/tree/default/general/makefile @@ -0,0 +1,83 @@ +# file : tests/cxx/tree/default/general/makefile +# author : Boris Kolpackov +# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC +# license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +include $(dir $(lastword $(MAKEFILE_LIST)))../../../../../build/bootstrap.make + +xsd := test.xsd +cxx := driver.cxx + +obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=.o)) +dep := $(obj:.o=.o.d) + +driver := $(out_base)/driver +test := $(out_base)/.test +clean := $(out_base)/.clean + + +# Import. +# +$(call import,\ + $(scf_root)/import/libxerces-c/stub.make,\ + l: xerces_c.l,cpp-options: xerces_c.l.cpp-options) + + +# Build. +# +$(driver): $(obj) $(xerces_c.l) + +$(obj) $(dep): cpp_options := -I$(src_root)/libxsd +$(obj) $(dep): $(xerces_c.l.cpp-options) + +genf := $(xsd:.xsd=.hxx) $(xsd:.xsd=.ixx) $(xsd:.xsd=.cxx) +gen := $(addprefix $(out_base)/,$(genf)) + +$(gen): xsd := $(out_root)/xsd/xsd +$(gen): xsd_options := --generate-ostream --generate-serialization \ +--generate-default-ctor --generate-from-base-ctor +$(gen): $(out_root)/xsd/xsd + +$(call include-dep,$(dep)) + +# Convenience alias for default target. +# +$(out_base)/: $(driver) + + +# Test. +# +$(test): driver := $(driver) +$(test): $(driver) $(src_base)/test.xml $(src_base)/output + $(call message,test $$1,$$1 $(src_base)/test.xml | diff -u $(src_base)/output -,$(driver)) + +# Clean. +# +$(clean): $(driver).o.clean \ + $(addsuffix .cxx.clean,$(obj)) \ + $(addsuffix .cxx.clean,$(dep)) \ + $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean)) + +# Generated .gitignore. +# +ifeq ($(out_base),$(src_base)) +$(gen): | $(out_base)/.gitignore +$(driver): | $(out_base)/.gitignore + +$(out_base)/.gitignore: files := driver $(genf) +$(clean): $(out_base)/.gitignore.clean + +$(call include,$(bld_root)/git/gitignore.make) +endif + +# How to. +# +$(call include,$(bld_root)/cxx/o-e.make) +$(call include,$(bld_root)/cxx/cxx-o.make) +$(call include,$(bld_root)/cxx/cxx-d.make) +$(call include,$(scf_root)/xsd/tree/xsd-cxx.make) + + +# Dependencies. +# +$(call import,$(src_root)/xsd/makefile) diff --git a/tests/cxx/tree/default/general/output b/tests/cxx/tree/default/general/output new file mode 100644 index 0000000..89b4bb3 --- /dev/null +++ b/tests/cxx/tree/default/general/output @@ -0,0 +1,28 @@ + + + + + + + + + + + + diff --git a/tests/cxx/tree/default/general/test.xml b/tests/cxx/tree/default/general/test.xml new file mode 100644 index 0000000..11bd0a7 --- /dev/null +++ b/tests/cxx/tree/default/general/test.xml @@ -0,0 +1,16 @@ + + + + + + + diff --git a/tests/cxx/tree/default/general/test.xsd b/tests/cxx/tree/default/general/test.xsd new file mode 100644 index 0000000..e9a3bcb --- /dev/null +++ b/tests/cxx/tree/default/general/test.xsd @@ -0,0 +1,231 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/cxx/tree/default/makefile b/tests/cxx/tree/default/makefile index 431e708..a1055f9 100644 --- a/tests/cxx/tree/default/makefile +++ b/tests/cxx/tree/default/makefile @@ -5,79 +5,14 @@ include $(dir $(lastword $(MAKEFILE_LIST)))../../../../build/bootstrap.make -xsd := test.xsd -cxx := driver.cxx +tests := general omit -obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=.o)) -dep := $(obj:.o=.o.d) +default := $(out_base)/ +test := $(out_base)/.test +clean := $(out_base)/.clean -driver := $(out_base)/driver -test := $(out_base)/.test -clean := $(out_base)/.clean +$(default): $(addprefix $(out_base)/,$(addsuffix /,$(tests))) +$(test): $(addprefix $(out_base)/,$(addsuffix /.test,$(tests))) +$(clean): $(addprefix $(out_base)/,$(addsuffix /.clean,$(tests))) - -# Import. -# -$(call import,\ - $(scf_root)/import/libxerces-c/stub.make,\ - l: xerces_c.l,cpp-options: xerces_c.l.cpp-options) - - -# Build. -# -$(driver): $(obj) $(xerces_c.l) - -$(obj) $(dep): cpp_options := -I$(src_root)/libxsd -$(obj) $(dep): $(xerces_c.l.cpp-options) - -genf := $(xsd:.xsd=.hxx) $(xsd:.xsd=.ixx) $(xsd:.xsd=.cxx) -gen := $(addprefix $(out_base)/,$(genf)) - -$(gen): xsd := $(out_root)/xsd/xsd -$(gen): xsd_options := --generate-ostream --generate-serialization \ ---generate-default-ctor --generate-from-base-ctor --omit-default-attributes -$(gen): $(out_root)/xsd/xsd - -$(call include-dep,$(dep)) - -# Convenience alias for default target. -# -$(out_base)/: $(driver) - - -# Test. -# -$(test): driver := $(driver) -$(test): $(driver) $(src_base)/test.xml $(src_base)/output - $(call message,test $$1,$$1 $(src_base)/test.xml | diff -u $(src_base)/output -,$(driver)) - -# Clean. -# -$(clean): $(driver).o.clean \ - $(addsuffix .cxx.clean,$(obj)) \ - $(addsuffix .cxx.clean,$(dep)) \ - $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean)) - -# Generated .gitignore. -# -ifeq ($(out_base),$(src_base)) -$(gen): | $(out_base)/.gitignore -$(driver): | $(out_base)/.gitignore - -$(out_base)/.gitignore: files := driver $(genf) -$(clean): $(out_base)/.gitignore.clean - -$(call include,$(bld_root)/git/gitignore.make) -endif - -# How to. -# -$(call include,$(bld_root)/cxx/o-e.make) -$(call include,$(bld_root)/cxx/cxx-o.make) -$(call include,$(bld_root)/cxx/cxx-d.make) -$(call include,$(scf_root)/xsd/tree/xsd-cxx.make) - - -# Dependencies. -# -$(call import,$(src_root)/xsd/makefile) +$(foreach t,$(tests),$(call import,$(src_base)/$t/makefile)) diff --git a/tests/cxx/tree/default/omit/driver.cxx b/tests/cxx/tree/default/omit/driver.cxx new file mode 100644 index 0000000..e7c52f2 --- /dev/null +++ b/tests/cxx/tree/default/omit/driver.cxx @@ -0,0 +1,48 @@ +// file : tests/cxx/tree/default/omit/driver.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +// Test default attribute omission from the output. +// + +#include // std::auto_ptr +#include + +#include "test.hxx" + +using namespace std; +using namespace test; + +int +main (int argc, char* argv[]) +{ + if (argc != 2) + { + cerr << "usage: " << argv[0] << " test.xml" << endl; + return 1; + } + + try + { + auto_ptr r (root (argv[1], xml_schema::flags::dont_validate)); + + cout << *r << endl + << "default x: " << derived::x_default_value () << endl + << "default y: " << derived::y_default_value () << endl + << "fixed p: " << derived::p_default_value () << endl + << "fixed q1: " << derived::q1_default_value () << endl + << "fixed q2: " << derived::q2_default_value () << endl; + + // Serialize. + // + xml_schema::namespace_infomap map; + map["t"].name = "test"; + root (cout, *r, map); + } + catch (xml_schema::exception const& e) + { + cerr << e << endl; + return 1; + } +} diff --git a/tests/cxx/tree/default/omit/makefile b/tests/cxx/tree/default/omit/makefile new file mode 100644 index 0000000..8a78c51 --- /dev/null +++ b/tests/cxx/tree/default/omit/makefile @@ -0,0 +1,83 @@ +# file : tests/cxx/tree/default/omit/makefile +# author : Boris Kolpackov +# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC +# license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +include $(dir $(lastword $(MAKEFILE_LIST)))../../../../../build/bootstrap.make + +xsd := test.xsd +cxx := driver.cxx + +obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=.o)) +dep := $(obj:.o=.o.d) + +driver := $(out_base)/driver +test := $(out_base)/.test +clean := $(out_base)/.clean + + +# Import. +# +$(call import,\ + $(scf_root)/import/libxerces-c/stub.make,\ + l: xerces_c.l,cpp-options: xerces_c.l.cpp-options) + + +# Build. +# +$(driver): $(obj) $(xerces_c.l) + +$(obj) $(dep): cpp_options := -I$(src_root)/libxsd +$(obj) $(dep): $(xerces_c.l.cpp-options) + +genf := $(xsd:.xsd=.hxx) $(xsd:.xsd=.ixx) $(xsd:.xsd=.cxx) +gen := $(addprefix $(out_base)/,$(genf)) + +$(gen): xsd := $(out_root)/xsd/xsd +$(gen): xsd_options := --generate-ostream --generate-serialization \ +--generate-default-ctor --generate-from-base-ctor --omit-default-attributes +$(gen): $(out_root)/xsd/xsd + +$(call include-dep,$(dep)) + +# Convenience alias for default target. +# +$(out_base)/: $(driver) + + +# Test. +# +$(test): driver := $(driver) +$(test): $(driver) $(src_base)/test.xml $(src_base)/output + $(call message,test $$1,$$1 $(src_base)/test.xml | diff -u $(src_base)/output -,$(driver)) + +# Clean. +# +$(clean): $(driver).o.clean \ + $(addsuffix .cxx.clean,$(obj)) \ + $(addsuffix .cxx.clean,$(dep)) \ + $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean)) + +# Generated .gitignore. +# +ifeq ($(out_base),$(src_base)) +$(gen): | $(out_base)/.gitignore +$(driver): | $(out_base)/.gitignore + +$(out_base)/.gitignore: files := driver $(genf) +$(clean): $(out_base)/.gitignore.clean + +$(call include,$(bld_root)/git/gitignore.make) +endif + +# How to. +# +$(call include,$(bld_root)/cxx/o-e.make) +$(call include,$(bld_root)/cxx/cxx-o.make) +$(call include,$(bld_root)/cxx/cxx-d.make) +$(call include,$(scf_root)/xsd/tree/xsd-cxx.make) + + +# Dependencies. +# +$(call import,$(src_root)/xsd/makefile) diff --git a/tests/cxx/tree/default/omit/output b/tests/cxx/tree/default/omit/output new file mode 100644 index 0000000..eef99a3 --- /dev/null +++ b/tests/cxx/tree/default/omit/output @@ -0,0 +1,21 @@ + +derived: +a: a +x: foo +q1: 1 +y: -20 +p: bar +q2: 2 +default x: foo +default y: -20 +fixed p: bar +fixed q1: 1 +fixed q2: 2 + + + + + a + + + diff --git a/tests/cxx/tree/default/omit/test.xml b/tests/cxx/tree/default/omit/test.xml new file mode 100644 index 0000000..dec39b4 --- /dev/null +++ b/tests/cxx/tree/default/omit/test.xml @@ -0,0 +1,9 @@ + + + + a + + + diff --git a/tests/cxx/tree/default/omit/test.xsd b/tests/cxx/tree/default/omit/test.xsd new file mode 100644 index 0000000..bfc68d4 --- /dev/null +++ b/tests/cxx/tree/default/omit/test.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/cxx/tree/default/output b/tests/cxx/tree/default/output deleted file mode 100644 index 1259952..0000000 --- a/tests/cxx/tree/default/output +++ /dev/null @@ -1,26 +0,0 @@ - -derived: -a: a -x: foo -q1: 1 -y: -20 -p: bar -q2: 2 -qname: -x: x -y: y -default x: foo -default y: -20 -fixed p: bar -fixed q1: 1 -fixed q2: 2 - - - - - a - - - - - diff --git a/tests/cxx/tree/default/test.xml b/tests/cxx/tree/default/test.xml deleted file mode 100644 index d568ac9..0000000 --- a/tests/cxx/tree/default/test.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - a - - - - - diff --git a/tests/cxx/tree/default/test.xsd b/tests/cxx/tree/default/test.xsd deleted file mode 100644 index aa9ac66..0000000 --- a/tests/cxx/tree/default/test.xsd +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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 +// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include + +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 ( + 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 ( + 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 ( + 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; + } + } + } +} diff --git a/xsd/cxx/tree/default-value.hxx b/xsd/cxx/tree/default-value.hxx new file mode 100644 index 0000000..fb4b3d1 --- /dev/null +++ b/xsd/cxx/tree/default-value.hxx @@ -0,0 +1,327 @@ +// file : xsd/cxx/tree/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_TREE_DEFAULT_VALUE_HXX +#define CXX_TREE_DEFAULT_VALUE_HXX + +#include +#include + +#include + +namespace CXX +{ + namespace Tree + { + struct IsLiteralValue: IsFundamentalType, Traversal::Complex + { + IsLiteralValue (Boolean& r); + + virtual Void + traverse (SemanticGraph::Complex&); + + private: + Traversal::Inherits inherits_; + }; + + 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::Complex, + + Context + { + LiteralValue (Context&); + + String + dispatch (SemanticGraph::Node& type, String const& value); + + // Handle inheritance. + // + virtual Void + traverse (SemanticGraph::Complex&); + + // 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&); + + private: + String value_; + String literal_; + + Traversal::Inherits inherits_; + }; + + // Some initialization (e.g., list) need a function body. + // + struct IsSimpleInit: Traversal::List, + Traversal::Complex, + + Traversal::Fundamental::NameTokens, + Traversal::Fundamental::IdRefs, + Traversal::Fundamental::Entities + { + // Should be true initially. + // + IsSimpleInit (Boolean& r); + + virtual Void + traverse (SemanticGraph::List&); + + virtual Void + traverse (SemanticGraph::Complex&); + + virtual Void + traverse (SemanticGraph::Fundamental::NameTokens&); + + virtual Void + traverse (SemanticGraph::Fundamental::IdRefs&); + + virtual Void + traverse (SemanticGraph::Fundamental::Entities&); + + private: + Boolean& r_; + Traversal::Inherits inherits_; + }; + + struct InitValue: Traversal::List, + Traversal::Union, + Traversal::Complex, + + 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&); + + // 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_sequence_type (SemanticGraph::Type& element_type); + + Void + time_zone (Size pos); + + private: + String value_; + MemberTypeName type_name_; + LiteralValue literal_value_; + }; + } +} + +#endif // CXX_TREE_DEFAULT_VALUE_HXX diff --git a/xsd/cxx/tree/name-processor.cxx b/xsd/cxx/tree/name-processor.cxx index e15b072..e0636cd 100644 --- a/xsd/cxx/tree/name-processor.cxx +++ b/xsd/cxx/tree/name-processor.cxx @@ -3,16 +3,17 @@ // copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#include - -#include +#include +#include #include #include #include -#include -#include +#include + +#include +#include namespace CXX { @@ -817,9 +818,18 @@ namespace CXX m.context ().set ( "default-value", find_name (an, name_set_)); - m.context ().set ( - "default-value-member", - find_name (b + L"_default_value_", name_set_)); + Boolean lit (false); + { + IsLiteralValue test (lit); + test.dispatch (m.type ()); + } + + if (!lit) + { + m.context ().set ( + "default-value-member", + find_name (b + L"_default_value_", name_set_)); + } } } } diff --git a/xsd/cxx/tree/tree-header.cxx b/xsd/cxx/tree/tree-header.cxx index 9b39739..c5e3395 100644 --- a/xsd/cxx/tree/tree-header.cxx +++ b/xsd/cxx/tree/tree-header.cxx @@ -3,12 +3,13 @@ // copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#include -#include - #include #include +#include +#include +#include + namespace CXX { namespace Tree @@ -1358,20 +1359,35 @@ namespace CXX if (simple) { + Boolean lit (false); + { + IsLiteralValue test (lit); + test.dispatch (m.type ()); + } + if (doxygen) { os << "/**" << endl << " * @brief Return the default value for the " << kind << "." << endl - << " *" << endl - << " * @return A read-only (constant) reference to the " - << kind << "'s" << endl - << " * default value." << endl - << " */" << endl; + << " *" << endl; + + if (lit) + os << " * @return The " << kind << "'s default value." << endl; + else + os << " * @return A read-only (constant) reference to the " + << kind << "'s" << endl + << " * default value." << endl; + + os << " */" << endl; } - os << "static const " << etype (m) << "&" << endl - << edefault_value (m) << " ();" + if (lit) + os << "static " << etype (m) << endl; + else + os << "static const " << etype (m) << "&" << endl; + + os << edefault_value (m) << " ();" << endl; } } @@ -2157,8 +2173,17 @@ namespace CXX if (simple) { - os << "static const " << etype (m) << " " << - edefault_value_member (m) << ";"; + Boolean lit (false); + { + IsLiteralValue test (lit); + test.dispatch (m.type ()); + } + + if (!lit) + { + os << "static const " << etype (m) << " " << + edefault_value_member (m) << ";"; + } } } } @@ -3675,6 +3700,7 @@ namespace CXX Boolean inline_ (ctx.options.value ()); ctx.os << "#include // std::auto_ptr" << endl + << "#include // std::numeric_limits" << endl << "#include // std::binary_search" << endl << endl; diff --git a/xsd/cxx/tree/tree-inline.cxx b/xsd/cxx/tree/tree-inline.cxx index 148369f..19f9cd3 100644 --- a/xsd/cxx/tree/tree-inline.cxx +++ b/xsd/cxx/tree/tree-inline.cxx @@ -3,11 +3,12 @@ // copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#include - #include #include +#include +#include + namespace CXX { namespace Tree @@ -422,7 +423,7 @@ namespace CXX struct Member: Traversal::Member, Context { Member (Context& c, String const& scope) - : Context (c), scope_ (scope) + : Context (c), scope_ (scope), lit_value_ (c) { } @@ -611,19 +612,32 @@ namespace CXX if (simple) { - os << inl - << "const " << scope_ << "::" << etype (m) << "& " << - scope_ << "::" << endl + String lit (lit_value_.dispatch (m.type (), m.value ())); + + os << inl; + + if (lit) + os << scope_ << "::" << etype (m) << " "; + else + os << "const " << scope_ << "::" << etype (m) << "& "; + + os << scope_ << "::" << endl << edefault_value (m) << " ()" - << "{" - << "return " << edefault_value_member (m) << ";" - << "}"; + << "{"; + + if (lit) + os << "return " << etype (m) << " (" << lit << ");"; + else + os << "return " << edefault_value_member (m) << ";"; + + os << "}"; } } } private: String scope_; + LiteralValue lit_value_; }; struct Any: Traversal::Any, diff --git a/xsd/cxx/tree/tree-source.cxx b/xsd/cxx/tree/tree-source.cxx index 48702a1..2093e92 100644 --- a/xsd/cxx/tree/tree-source.cxx +++ b/xsd/cxx/tree/tree-source.cxx @@ -3,16 +3,13 @@ // copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#include +#include #include #include -#include - -#include - -using std::wcerr; +#include +#include namespace CXX { @@ -548,7 +545,7 @@ namespace CXX struct Member: Traversal::Member, Context { Member (Context& c, String const& scope) - : Context (c), scope_ (scope) + : Context (c), scope_ (scope), init_value_ (c) { } @@ -573,46 +570,48 @@ namespace CXX if (simple) { - Boolean fund (false); + Boolean lit (false); { - IsFundamentalType test (fund); + IsLiteralValue test (lit); test.dispatch (t); } - String type (etype (m)); - String q_type (scope_ + L"::" + type); - - if (fund) + if (!lit) { - String ftype; + Boolean simple_init (true); { - std::wostringstream o; - MemberTypeName test (*this, o); + IsSimpleInit test (simple_init); test.dispatch (t); - ftype = o.str (); } - os << "const " << q_type << " " << scope_ << "::" << - edefault_value_member (m) << " (" << endl - << "::xsd::cxx::tree::traits< " << ftype << ", " << - char_type; + String const& member (edefault_value_member (m)); - if (t.is_a ()) - os << ", ::xsd::cxx::tree::schema_type::double_"; - else if (t.is_a ()) - os << ", ::xsd::cxx::tree::schema_type::decimal"; + String init_func; + if (!simple_init) + { + init_func = escape (L"_xsd_" + scope_ + member + L"_init"); - os << " >::create (" << endl - << string_type << " (" << L << strlit (m.value ()) << - "), 0, 0, 0));" - << endl; - } - else - { - os << "const " << q_type << " " << scope_ << "::" << - edefault_value_member (m) << " (" << endl - << string_type << " (" << L << strlit (m.value ()) << - "), 0, 0, 0);" + os << "static " << scope_ << "::" << etype (m) << endl + << init_func << " ()" + << "{" + << scope_ << "::" << etype (m) << " r;" + << endl; + + init_value_.dispatch (t, m.value ()); + + os << "return r;" + << "};"; + } + + os << "const " << scope_ << "::" << etype (m) << " " << + scope_ << "::" << member << " (" << endl; + + if (simple_init) + init_value_.dispatch (t, m.value ()); + else + os << init_func << " ()"; + + os << ");" << endl; } } @@ -621,6 +620,7 @@ namespace CXX private: String scope_; + InitValue init_value_; }; diff --git a/xsd/makefile b/xsd/makefile index 12990a6..b26341d 100644 --- a/xsd/makefile +++ b/xsd/makefile @@ -31,6 +31,7 @@ cxx_tun += cxx/tree/elements.cxx \ cxx/tree/validator.cxx \ cxx/tree/counter.cxx \ cxx/tree/name-processor.cxx \ + cxx/tree/default-value.cxx \ cxx/tree/generator.cxx \ cxx/tree/tree-forward.cxx \ cxx/tree/tree-header.cxx \ -- cgit v1.1