diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2009-12-14 17:32:14 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2009-12-14 17:32:14 +0200 |
commit | af83df9be50a9383d0c54fb24b8e486a658a2a02 (patch) | |
tree | 5d937c9015c6438a60122743c7fb72ec30de32be | |
parent | c12b36470adb57100f1d5f22e3ddd6fc163f6ab4 (diff) |
New default/fixed value initialization code
Now the default/fixed values are parsed by the compiler at compile time
instead of the standard parsing code at runtime.
19 files changed, 1911 insertions, 157 deletions
@@ -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 \ |