aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS6
-rw-r--r--tests/cxx/tree/default/general/driver.cxx39
-rw-r--r--tests/cxx/tree/default/general/makefile83
-rw-r--r--tests/cxx/tree/default/general/output28
-rw-r--r--tests/cxx/tree/default/general/test.xml16
-rw-r--r--tests/cxx/tree/default/general/test.xsd231
-rw-r--r--tests/cxx/tree/default/makefile81
-rw-r--r--tests/cxx/tree/default/omit/driver.cxx (renamed from tests/cxx/tree/default/driver.cxx)4
-rw-r--r--tests/cxx/tree/default/omit/makefile83
-rw-r--r--tests/cxx/tree/default/omit/output (renamed from tests/cxx/tree/default/output)5
-rw-r--r--tests/cxx/tree/default/omit/test.xml (renamed from tests/cxx/tree/default/test.xml)2
-rw-r--r--tests/cxx/tree/default/omit/test.xsd (renamed from tests/cxx/tree/default/test.xsd)11
-rw-r--r--xsd/cxx/tree/default-value.cxx971
-rw-r--r--xsd/cxx/tree/default-value.hxx327
-rw-r--r--xsd/cxx/tree/name-processor.cxx26
-rw-r--r--xsd/cxx/tree/tree-header.cxx50
-rw-r--r--xsd/cxx/tree/tree-inline.cxx32
-rw-r--r--xsd/cxx/tree/tree-source.cxx72
-rw-r--r--xsd/makefile1
19 files changed, 1911 insertions, 157 deletions
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/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 <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+// Test default attribute/element values.
+//
+
+#include <memory> // std::auto_ptr
+#include <iostream>
+
+#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<type> 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 <boris@codesynthesis.com>
+# 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 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
+<t:root xmlns:t="test" bool1="true" bool2="true" bool3="false" bool4="false" byte="-99" decimal1="1.12345" decimal2="-0.456" double1="1.12345" double2="1123.45" double3="-0.00012345" double4="NaN" double5="-INF" fix1="123" fix2="123" fix3="abc" fix4="abc" fix5="aaa bbb ccc" fix6="aaa bbb ccc" float1="1.123" float2="1123" float3="-0.000123" float4="NaN" float5="-INF" id="this" idref="this" idrefs="this" int="-99999" integer="-99999" language="en-us" long="-99999" ncname="abcd" ninteger="-99999" nmtoken="ab:cd" nmtokens1="a:b efg aaa" nmtokens2="abc" nninteger="99999" npinteger="-99999" nstring=" a b " pinteger="99999" qname1="foo" qname2="t:bar" short="-999" string1="" string2=" a b " token="a b" ubyte="99" uint="99999" ulong="99999" uri="http://example.com" ushort="999">
+
+ <union a="abc"/>
+
+ <list a="123 345 678" b="ab cd ef" c="abc" d="abc def"/>
+
+ <simple a="123" b="abc" c="123" d="abc" e="abc" f="abc 123"/>
+
+ <date a="2009-03-31" b="2009-03-31Z" c="2009-03-31Z" d="2009-03-31Z" e="2009-03-31+12:30" f="2009-03-31-12:30" g="2002009-03-31-12:30"/>
+
+ <time a="12:03:45" b="12:03:45.123Z" c="12:03:05.123Z" d="12:03:45.123Z" e="12:03:45.123+12:30" f="12:03:45-12:30"/>
+
+ <date-time a="2009-03-31T12:03:45" b="2009-03-31T12:03:45.123Z" c="2002009-03-31T12:03:05.123-12:30"/>
+
+ <duration a="P100Y" b="P100M" c="P100D" d="PT12H" e="PT12M" f="PT12.123S" g="-P100Y10M20DT12H12M1.123S"/>
+
+ <day a="---02" b="---22Z" c="---22-12:30"/>
+
+ <month a="--02" b="--12Z" c="--12+12:30"/>
+
+ <year a="2009" b="-2002009Z" c="2009-12:30"/>
+
+ <month-day a="--02-02" b="--12-22Z" c="--12-22+12:30"/>
+
+ <year-month a="2009-02" b="-2002009-12Z" c="2009-12-12:30"/>
+
+</t:root>
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 @@
+<t:root xmlns:t="test" id="this" fix2="123" fix4="abc" fix6="aaa bbb ccc">
+
+ <union/>
+ <list/>
+ <simple/>
+ <date/>
+ <time/>
+ <date-time/>
+ <duration/>
+ <day/>
+ <month/>
+ <year/>
+ <month-day/>
+ <year-month/>
+
+</t:root>
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 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:t="test" targetNamespace="test">
+
+ <!-- union -->
+
+ <simpleType name="union">
+ <union memberTypes="int string"/>
+ </simpleType>
+
+ <complexType name="union-test">
+ <attribute default="abc" name="a" type="t:union"/>
+ </complexType>
+
+ <!-- list -->
+
+ <simpleType name="fix-list">
+ <list itemType="int"/>
+ </simpleType>
+
+ <simpleType name="var-list">
+ <list itemType="string"/>
+ </simpleType>
+
+ <simpleType name="list-item">
+ <restriction base="string"/>
+ </simpleType>
+
+ <simpleType name="usr-list">
+ <list itemType="t:list-item"/>
+ </simpleType>
+
+ <simpleType name="union-list">
+ <list itemType="t:union"/>
+ </simpleType>
+
+ <complexType name="list-test">
+ <attribute default="123 345 678" name="a" type="t:fix-list"/>
+ <attribute default=" ab cd ef " name="b" type="t:var-list"/>
+ <attribute default="abc" name="c" type="t:usr-list"/>
+ <attribute default="abc def" name="d" type="t:union-list"/>
+ </complexType>
+
+ <!-- simple type -->
+
+ <simpleType name="int-base">
+ <restriction base="int"/>
+ </simpleType>
+
+ <simpleType name="str-base">
+ <restriction base="string"/>
+ </simpleType>
+
+ <simpleType name="int">
+ <restriction base="t:int-base"/>
+ </simpleType>
+
+ <simpleType name="str">
+ <restriction base="t:str-base"/>
+ </simpleType>
+
+ <simpleType name="union-derived">
+ <restriction base="t:union"/>
+ </simpleType>
+
+ <simpleType name="list-derived">
+ <restriction base="t:usr-list"/>
+ </simpleType>
+
+ <complexType name="simple-test">
+ <attribute default="123" name="a" type="t:int-base"/>
+ <attribute default="abc" name="b" type="t:str-base"/>
+ <attribute default="123" name="c" type="t:int"/>
+ <attribute default="abc" name="d" type="t:str"/>
+ <attribute default="abc" name="e" type="t:union-derived"/>
+ <attribute default="abc 123" name="f" type="t:list-derived"/>
+ </complexType>
+
+ <!-- date/time types -->
+
+ <complexType name="date-test">
+ <attribute default="2009-03-31" name="a" type="date"/>
+ <attribute default="2009-03-31Z" name="b" type="date"/>
+ <attribute default="2009-03-31+00:00" name="c" type="date"/>
+ <attribute default="2009-03-31-00:00" name="d" type="date"/>
+ <attribute default="2009-03-31+12:30" name="e" type="date"/>
+ <attribute default="2009-03-31-12:30" name="f" type="date"/>
+ <attribute default="2002009-03-31-12:30" name="g" type="date"/>
+ </complexType>
+
+ <complexType name="time-test">
+ <attribute default="12:03:45" name="a" type="time"/>
+ <attribute default="12:03:45.123Z" name="b" type="time"/>
+ <attribute default="12:03:05.123+00:00" name="c" type="time"/>
+ <attribute default="12:03:45.123-00:00" name="d" type="time"/>
+ <attribute default="12:03:45.123+12:30" name="e" type="time"/>
+ <attribute default="12:03:45-12:30" name="f" type="time"/>
+ </complexType>
+
+ <complexType name="date-time-test">
+ <attribute default="2009-03-31T12:03:45" name="a" type="dateTime"/>
+ <attribute default="2009-03-31T12:03:45.123Z" name="b" type="dateTime"/>
+ <attribute default="2002009-03-31T12:03:05.123-12:30" name="c" type="dateTime"/>
+ </complexType>
+
+ <complexType name="duration-test">
+ <attribute default="P100Y" name="a" type="duration"/>
+ <attribute default="P100M" name="b" type="duration"/>
+ <attribute default="P100D" name="c" type="duration"/>
+ <attribute default="PT12H" name="d" type="duration"/>
+ <attribute default="PT12M" name="e" type="duration"/>
+ <attribute default="PT12.123S" name="f" type="duration"/>
+ <attribute default="-P100Y10M20DT12H12M1.123S" name="g" type="duration"/>
+ </complexType>
+
+ <complexType name="day-test">
+ <attribute default="---02" name="a" type="gDay"/>
+ <attribute default="---22Z" name="b" type="gDay"/>
+ <attribute default="---22-12:30" name="c" type="gDay"/>
+ </complexType>
+
+ <complexType name="month-test">
+ <attribute default="--02" name="a" type="gMonth"/>
+ <attribute default="--12Z" name="b" type="gMonth"/>
+ <attribute default="--12+12:30" name="c" type="gMonth"/>
+ </complexType>
+
+ <complexType name="year-test">
+ <attribute default="2009" name="a" type="gYear"/>
+ <attribute default="-2002009Z" name="b" type="gYear"/>
+ <attribute default="2009-12:30" name="c" type="gYear"/>
+ </complexType>
+
+ <complexType name="month-day-test">
+ <attribute default="--02-02" name="a" type="gMonthDay"/>
+ <attribute default="--12-22Z" name="b" type="gMonthDay"/>
+ <attribute default="--12-22+12:30" name="c" type="gMonthDay"/>
+ </complexType>
+
+ <complexType name="year-month-test">
+ <attribute default="2009-02" name="a" type="gYearMonth"/>
+ <attribute default="-2002009-12Z" name="b" type="gYearMonth"/>
+ <attribute default="2009-12-12:30" name="c" type="gYearMonth"/>
+ </complexType>
+
+
+ <complexType name="type">
+ <sequence>
+ <element name="union" type="t:union-test"/>
+ <element name="list" type="t:list-test"/>
+ <element name="simple" type="t:simple-test"/>
+ <element name="date" type="t:date-test"/>
+ <element name="time" type="t:time-test"/>
+ <element name="date-time" type="t:date-time-test"/>
+ <element name="duration" type="t:duration-test"/>
+ <element name="day" type="t:day-test"/>
+ <element name="month" type="t:month-test"/>
+ <element name="year" type="t:year-test"/>
+ <element name="month-day" type="t:month-day-test"/>
+ <element name="year-month" type="t:year-month-test"/>
+ </sequence>
+
+<!--
+ <attribute name="any" type="anySimpleType" default=""/>
+-->
+
+ <attribute name="bool1" type="boolean" default="true"/>
+ <attribute name="bool2" type="boolean" default="1"/>
+ <attribute name="bool3" type="boolean" default="false"/>
+ <attribute name="bool4" type="boolean" default="0"/>
+
+ <attribute name="byte" type="byte" default="-99"/>
+ <attribute name="ubyte" type="unsignedByte" default="99"/>
+ <attribute name="short" type="short" default="-999"/>
+ <attribute name="ushort" type="unsignedShort" default="999"/>
+ <attribute name="int" type="int" default="-99999"/>
+ <attribute name="uint" type="unsignedInt" default="99999"/>
+ <attribute name="long" type="long" default="-99999"/>
+ <attribute name="ulong" type="unsignedLong" default="99999"/>
+
+ <attribute name="integer" type="integer" default="-99999"/>
+ <attribute name="npinteger" type="nonPositiveInteger" default="-99999"/>
+ <attribute name="nninteger" type="nonNegativeInteger" default="99999"/>
+ <attribute name="pinteger" type="positiveInteger" default="99999"/>
+ <attribute name="ninteger" type="negativeInteger" default="-99999"/>
+
+ <attribute name="float1" type="float" default="1.123"/>
+ <attribute name="float2" type="float" default="1.123e3"/>
+ <attribute name="float3" type="float" default="-.123E-3"/>
+ <attribute name="float4" type="float" default="NaN"/>
+ <attribute name="float5" type="float" default="-INF"/>
+
+ <attribute name="double1" type="double" default="1.12345"/>
+ <attribute name="double2" type="double" default="1.12345e3"/>
+ <attribute name="double3" type="double" default="-.12345E-3"/>
+ <attribute name="double4" type="double" default="NaN"/>
+ <attribute name="double5" type="double" default="-INF"/>
+
+ <attribute name="decimal1" type="decimal" default="1.12345"/>
+ <attribute name="decimal2" type="decimal" default="-.456"/>
+
+ <attribute name="string1" type="string" default=""/>
+ <attribute name="string2" type="string" default=" a b "/>
+ <attribute name="nstring" type="normalizedString" default=" a b "/>
+ <attribute name="token" type="token" default=" a b "/>
+ <attribute name="nmtoken" type="NMTOKEN" default="ab:cd"/>
+ <attribute name="nmtokens1" type="NMTOKENS" default=" a:b efg aaa "/>
+ <attribute name="nmtokens2" type="NMTOKENS" default="abc"/>
+ <attribute name="ncname" type="NCName" default=" abcd "/>
+ <attribute name="language" type="language" default=" en-us "/>
+ <attribute name="id" type="ID"/>
+ <attribute name="idref" type="IDREF" default="this"/>
+ <attribute name="idrefs" type="IDREFS" default=" this "/>
+ <attribute name="uri" type="anyURI" default=" http://example.com "/>
+
+ <attribute name="qname1" type="QName" default="foo"/>
+ <attribute name="qname2" type="QName" default="t:bar"/>
+
+ <!-- fixed -->
+
+ <attribute name="fix1" type="int" fixed="123"/>
+ <attribute name="fix2" type="int" fixed="123" use="required"/>
+ <attribute name="fix3" type="string" fixed="abc"/>
+ <attribute name="fix4" type="string" fixed="abc" use="required"/>
+ <attribute name="fix5" type="NMTOKENS" fixed="aaa bbb ccc"/>
+ <attribute name="fix6" type="NMTOKENS" fixed="aaa bbb ccc" use="required"/>
+
+ </complexType>
+
+ <element name="root" type="t:type"/>
+
+</schema>
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/driver.cxx b/tests/cxx/tree/default/omit/driver.cxx
index 3c71222..e7c52f2 100644
--- a/tests/cxx/tree/default/driver.cxx
+++ b/tests/cxx/tree/default/omit/driver.cxx
@@ -1,9 +1,9 @@
-// file : tests/cxx/tree/default/driver.cxx
+// file : tests/cxx/tree/default/omit/driver.cxx
// author : Boris Kolpackov <boris@codesynthesis.com>
// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
-// Test default attribute/element values.
+// Test default attribute omission from the output.
//
#include <memory> // std::auto_ptr
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 <boris@codesynthesis.com>
+# 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/output b/tests/cxx/tree/default/omit/output
index 1259952..eef99a3 100644
--- a/tests/cxx/tree/default/output
+++ b/tests/cxx/tree/default/omit/output
@@ -6,9 +6,6 @@ q1: 1
y: -20
p: bar
q2: 2
-qname:
-x: x
-y: y
default x: foo
default y: -20
fixed p: bar
@@ -21,6 +18,4 @@ fixed q2: 2
<a>a</a>
</derived>
- <qname x="x" y="y"/>
-
</t:root>
diff --git a/tests/cxx/tree/default/test.xml b/tests/cxx/tree/default/omit/test.xml
index d568ac9..dec39b4 100644
--- a/tests/cxx/tree/default/test.xml
+++ b/tests/cxx/tree/default/omit/test.xml
@@ -6,6 +6,4 @@
<a>a</a>
</derived>
- <qname y="y"><!--a></a--></qname>
-
</t:root>
diff --git a/tests/cxx/tree/default/test.xsd b/tests/cxx/tree/default/omit/test.xsd
index aa9ac66..bfc68d4 100644
--- a/tests/cxx/tree/default/test.xsd
+++ b/tests/cxx/tree/default/omit/test.xsd
@@ -14,23 +14,14 @@
<extension base="t:base">
<attribute name="y" type="int" default="-20"/>
<attribute name="p" type="string" fixed="bar"/>
- <attribute name="q2" type="int" fixed="2" use="required"/>
+ <attribute name="q2" type="int" fixed="2" use="required"/>
</extension>
</complexContent>
</complexType>
- <complexType name="qname">
- <sequence>
- <!--element name="a" type="QName" default="a"/-->
- </sequence>
- <attribute name="x" type="QName" default="x"/>
- <attribute name="y" type="QName" fixed="y" use="required"/>
- </complexType>
-
<complexType name="type">
<sequence>
<element name="derived" type="t:derived"/>
- <element name="qname" type="t:qname"/>
</sequence>
</complexType>
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;
+ }
+ }
+ }
+}
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 <boris@codesynthesis.com>
+// 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 <xsd-frontend/semantic-graph.hxx>
+#include <xsd-frontend/traversal.hxx>
+
+#include <cxx/tree/elements.hxx>
+
+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 <cxx/tree/name-processor.hxx>
-
-#include <backend-elements/regex.hxx>
+#include <sstream>
+#include <iostream>
#include <cult/containers/set.hxx>
#include <cult/containers/map.hxx>
#include <cult/containers/vector.hxx>
-#include <sstream>
-#include <iostream>
+#include <backend-elements/regex.hxx>
+
+#include <cxx/tree/default-value.hxx>
+#include <cxx/tree/name-processor.hxx>
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 <cxx/tree/tree-header.hxx>
-#include <cxx/tree/fundamental-header.hxx>
-
#include <xsd-frontend/semantic-graph.hxx>
#include <xsd-frontend/traversal.hxx>
+#include <cxx/tree/tree-header.hxx>
+#include <cxx/tree/default-value.hxx>
+#include <cxx/tree/fundamental-header.hxx>
+
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<CLI::generate_inline> ());
ctx.os << "#include <memory> // std::auto_ptr" << endl
+ << "#include <limits> // std::numeric_limits" << endl
<< "#include <algorithm> // 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 <cxx/tree/tree-inline.hxx>
-
#include <xsd-frontend/semantic-graph.hxx>
#include <xsd-frontend/traversal.hxx>
+#include <cxx/tree/tree-inline.hxx>
+#include <cxx/tree/default-value.hxx>
+
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 <cxx/tree/tree-source.hxx>
+#include <cult/containers/list.hxx>
#include <xsd-frontend/semantic-graph.hxx>
#include <xsd-frontend/traversal.hxx>
-#include <cult/containers/list.hxx>
-
-#include <iostream>
-
-using std::wcerr;
+#include <cxx/tree/tree-source.hxx>
+#include <cxx/tree/default-value.hxx>
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<SemanticGraph::Fundamental::Double> ())
- os << ", ::xsd::cxx::tree::schema_type::double_";
- else if (t.is_a<SemanticGraph::Fundamental::Decimal> ())
- 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 \