diff options
Diffstat (limited to 'xsd')
-rw-r--r-- | xsd/.gitignore | 25 | ||||
l--------- | xsd/FLOSSE | 1 | ||||
l--------- | xsd/GPLv2 | 1 | ||||
l--------- | xsd/LICENSE | 1 | ||||
l--------- | xsd/NEWS | 1 | ||||
l--------- | xsd/PACKAGE-README.md | 1 | ||||
-rw-r--r-- | xsd/README.md | 12 | ||||
-rw-r--r-- | xsd/build/.gitignore | 3 | ||||
-rw-r--r-- | xsd/build/bootstrap.build | 10 | ||||
-rw-r--r-- | xsd/build/export.build | 9 | ||||
-rw-r--r-- | xsd/build/root.build | 37 | ||||
-rw-r--r-- | xsd/buildfile | 11 | ||||
-rw-r--r-- | xsd/doc/.gitignore | 5 | ||||
-rw-r--r-- | xsd/doc/buildfile | 295 | ||||
-rw-r--r-- | xsd/doc/custom-literals.xsd | 48 | ||||
-rw-r--r-- | xsd/doc/cxx/.gitignore | 2 | ||||
-rw-r--r-- | xsd/doc/cxx/parser/guide/figure-1.png | bin | 0 -> 34195 bytes | |||
-rw-r--r-- | xsd/doc/cxx/parser/guide/figure-1.svg | 373 | ||||
-rw-r--r-- | xsd/doc/cxx/parser/guide/guide.html2ps.in | 65 | ||||
-rw-r--r-- | xsd/doc/cxx/parser/guide/index.xhtml.in | 4163 | ||||
-rw-r--r-- | xsd/doc/cxx/tree/guide/guide.html2ps.in | 65 | ||||
-rw-r--r-- | xsd/doc/cxx/tree/guide/index.xhtml.in | 2736 | ||||
-rw-r--r-- | xsd/doc/cxx/tree/manual/index.xhtml.in | 6826 | ||||
-rw-r--r-- | xsd/doc/cxx/tree/manual/manual.html2ps.in | 66 | ||||
-rw-r--r-- | xsd/doc/default.css | 319 | ||||
-rw-r--r-- | xsd/doc/pregenerated/xsd.1 | 1500 | ||||
-rw-r--r-- | xsd/doc/pregenerated/xsd.xhtml | 1620 | ||||
-rw-r--r-- | xsd/doc/xsd-epilogue.1 | 576 | ||||
-rw-r--r-- | xsd/doc/xsd-epilogue.xhtml | 429 | ||||
-rw-r--r-- | xsd/doc/xsd-parser-header.1 | 4 | ||||
-rw-r--r-- | xsd/doc/xsd-parser-header.xhtml | 1 | ||||
-rw-r--r-- | xsd/doc/xsd-prologue.1 | 119 | ||||
-rw-r--r-- | xsd/doc/xsd-prologue.xhtml | 122 | ||||
-rw-r--r-- | xsd/doc/xsd-tree-header.1 | 4 | ||||
-rw-r--r-- | xsd/doc/xsd-tree-header.xhtml | 1 | ||||
-rw-r--r-- | xsd/makefile | 190 | ||||
-rw-r--r-- | xsd/manifest | 162 | ||||
-rw-r--r-- | xsd/processing/cardinality/processor.hxx | 28 | ||||
-rw-r--r-- | xsd/processing/inheritance/processor.hxx | 28 | ||||
-rw-r--r-- | xsd/tests/.gitignore | 2 | ||||
-rw-r--r-- | xsd/tests/build/.gitignore | 3 | ||||
-rw-r--r-- | xsd/tests/build/bootstrap.build | 8 | ||||
-rw-r--r-- | xsd/tests/build/root.build | 16 | ||||
-rw-r--r-- | xsd/tests/buildfile | 4 | ||||
-rw-r--r-- | xsd/tests/testscript | 26 | ||||
-rw-r--r-- | xsd/xsd/.gitignore | 3 | ||||
-rw-r--r-- | xsd/xsd/buildfile | 121 | ||||
-rw-r--r-- | xsd/xsd/cxx/.gitignore | 1 | ||||
-rw-r--r-- | xsd/xsd/cxx/elements.cxx (renamed from xsd/cxx/elements.cxx) | 50 | ||||
-rw-r--r-- | xsd/xsd/cxx/elements.hxx (renamed from xsd/cxx/elements.hxx) | 20 | ||||
-rw-r--r-- | xsd/xsd/cxx/literal-map.cxx (renamed from xsd/cxx/literal-map.cxx) | 8 | ||||
-rw-r--r-- | xsd/xsd/cxx/literal-map.hxx (renamed from xsd/cxx/literal-map.hxx) | 8 | ||||
-rw-r--r-- | xsd/xsd/cxx/option-types.cxx (renamed from xsd/cxx/option-types.cxx) | 16 | ||||
-rw-r--r-- | xsd/xsd/cxx/option-types.hxx (renamed from xsd/cxx/option-types.hxx) | 14 | ||||
-rw-r--r-- | xsd/xsd/cxx/options.cli (renamed from xsd/cxx/options.cli) | 28 | ||||
-rw-r--r-- | xsd/xsd/cxx/parser/attribute-validation-source.cxx (renamed from xsd/cxx/parser/attribute-validation-source.cxx) | 6 | ||||
-rw-r--r-- | xsd/xsd/cxx/parser/attribute-validation-source.hxx (renamed from xsd/cxx/parser/attribute-validation-source.hxx) | 8 | ||||
-rw-r--r-- | xsd/xsd/cxx/parser/characters-validation-source.cxx (renamed from xsd/cxx/parser/characters-validation-source.cxx) | 6 | ||||
-rw-r--r-- | xsd/xsd/cxx/parser/characters-validation-source.hxx (renamed from xsd/cxx/parser/characters-validation-source.hxx) | 8 | ||||
-rw-r--r-- | xsd/xsd/cxx/parser/driver-source.cxx (renamed from xsd/cxx/parser/driver-source.cxx) | 8 | ||||
-rw-r--r-- | xsd/xsd/cxx/parser/driver-source.hxx (renamed from xsd/cxx/parser/driver-source.hxx) | 8 | ||||
-rw-r--r-- | xsd/xsd/cxx/parser/element-validation-source.cxx (renamed from xsd/cxx/parser/element-validation-source.cxx) | 18 | ||||
-rw-r--r-- | xsd/xsd/cxx/parser/element-validation-source.hxx (renamed from xsd/cxx/parser/element-validation-source.hxx) | 8 | ||||
-rw-r--r-- | xsd/xsd/cxx/parser/elements.cxx (renamed from xsd/cxx/parser/elements.cxx) | 2 | ||||
-rw-r--r-- | xsd/xsd/cxx/parser/elements.hxx (renamed from xsd/cxx/parser/elements.hxx) | 14 | ||||
-rw-r--r-- | xsd/xsd/cxx/parser/generator.cxx (renamed from xsd/cxx/parser/generator.cxx) | 258 | ||||
-rw-r--r-- | xsd/xsd/cxx/parser/generator.hxx (renamed from xsd/cxx/parser/generator.hxx) | 18 | ||||
-rw-r--r-- | xsd/xsd/cxx/parser/impl-header.cxx (renamed from xsd/cxx/parser/impl-header.cxx) | 6 | ||||
-rw-r--r-- | xsd/xsd/cxx/parser/impl-header.hxx (renamed from xsd/cxx/parser/impl-header.hxx) | 8 | ||||
-rw-r--r-- | xsd/xsd/cxx/parser/impl-source.cxx (renamed from xsd/cxx/parser/impl-source.cxx) | 8 | ||||
-rw-r--r-- | xsd/xsd/cxx/parser/impl-source.hxx (renamed from xsd/cxx/parser/impl-source.hxx) | 8 | ||||
-rw-r--r-- | xsd/xsd/cxx/parser/name-processor.cxx (renamed from xsd/cxx/parser/name-processor.cxx) | 6 | ||||
-rw-r--r-- | xsd/xsd/cxx/parser/name-processor.hxx (renamed from xsd/cxx/parser/name-processor.hxx) | 14 | ||||
-rw-r--r-- | xsd/xsd/cxx/parser/options.cli (renamed from xsd/cxx/parser/options.cli) | 4 | ||||
-rw-r--r-- | xsd/xsd/cxx/parser/parser-forward.cxx (renamed from xsd/cxx/parser/parser-forward.cxx) | 6 | ||||
-rw-r--r-- | xsd/xsd/cxx/parser/parser-forward.hxx (renamed from xsd/cxx/parser/parser-forward.hxx) | 8 | ||||
-rw-r--r-- | xsd/xsd/cxx/parser/parser-header.cxx (renamed from xsd/cxx/parser/parser-header.cxx) | 18 | ||||
-rw-r--r-- | xsd/xsd/cxx/parser/parser-header.hxx (renamed from xsd/cxx/parser/parser-header.hxx) | 8 | ||||
-rw-r--r-- | xsd/xsd/cxx/parser/parser-inline.cxx (renamed from xsd/cxx/parser/parser-inline.cxx) | 6 | ||||
-rw-r--r-- | xsd/xsd/cxx/parser/parser-inline.hxx (renamed from xsd/cxx/parser/parser-inline.hxx) | 8 | ||||
-rw-r--r-- | xsd/xsd/cxx/parser/parser-source.cxx (renamed from xsd/cxx/parser/parser-source.cxx) | 6 | ||||
-rw-r--r-- | xsd/xsd/cxx/parser/parser-source.hxx (renamed from xsd/cxx/parser/parser-source.hxx) | 8 | ||||
-rw-r--r-- | xsd/xsd/cxx/parser/print-impl-common.hxx (renamed from xsd/cxx/parser/print-impl-common.hxx) | 12 | ||||
-rw-r--r-- | xsd/xsd/cxx/parser/state-processor.cxx (renamed from xsd/cxx/parser/state-processor.cxx) | 16 | ||||
-rw-r--r-- | xsd/xsd/cxx/parser/state-processor.hxx (renamed from xsd/cxx/parser/state-processor.hxx) | 10 | ||||
-rw-r--r-- | xsd/xsd/cxx/parser/type-processor.cxx (renamed from xsd/cxx/parser/type-processor.cxx) | 8 | ||||
-rw-r--r-- | xsd/xsd/cxx/parser/type-processor.hxx (renamed from xsd/cxx/parser/type-processor.hxx) | 14 | ||||
-rw-r--r-- | xsd/xsd/cxx/parser/validator.cxx (renamed from xsd/cxx/parser/validator.cxx) | 15 | ||||
-rw-r--r-- | xsd/xsd/cxx/parser/validator.hxx (renamed from xsd/cxx/parser/validator.hxx) | 14 | ||||
-rw-r--r-- | xsd/xsd/cxx/tree/counter.cxx (renamed from xsd/cxx/tree/counter.cxx) | 25 | ||||
-rw-r--r-- | xsd/xsd/cxx/tree/counter.hxx (renamed from xsd/cxx/tree/counter.hxx) | 10 | ||||
-rw-r--r-- | xsd/xsd/cxx/tree/default-value.cxx (renamed from xsd/cxx/tree/default-value.cxx) | 6 | ||||
-rw-r--r-- | xsd/xsd/cxx/tree/default-value.hxx (renamed from xsd/cxx/tree/default-value.hxx) | 20 | ||||
-rw-r--r-- | xsd/xsd/cxx/tree/elements.cxx (renamed from xsd/cxx/tree/elements.cxx) | 2 | ||||
-rw-r--r-- | xsd/xsd/cxx/tree/elements.hxx (renamed from xsd/cxx/tree/elements.hxx) | 18 | ||||
-rw-r--r-- | xsd/xsd/cxx/tree/fundamental-header.hxx (renamed from xsd/cxx/tree/fundamental-header.hxx) | 14 | ||||
-rw-r--r-- | xsd/xsd/cxx/tree/generator.cxx (renamed from xsd/cxx/tree/generator.cxx) | 249 | ||||
-rw-r--r-- | xsd/xsd/cxx/tree/generator.hxx (renamed from xsd/cxx/tree/generator.hxx) | 18 | ||||
-rw-r--r-- | xsd/xsd/cxx/tree/name-processor.cxx (renamed from xsd/cxx/tree/name-processor.cxx) | 34 | ||||
-rw-r--r-- | xsd/xsd/cxx/tree/name-processor.hxx (renamed from xsd/cxx/tree/name-processor.hxx) | 12 | ||||
-rw-r--r-- | xsd/xsd/cxx/tree/options.cli (renamed from xsd/cxx/tree/options.cli) | 10 | ||||
-rw-r--r-- | xsd/xsd/cxx/tree/order-processor.cxx (renamed from xsd/cxx/tree/order-processor.cxx) | 8 | ||||
-rw-r--r-- | xsd/xsd/cxx/tree/order-processor.hxx (renamed from xsd/cxx/tree/order-processor.hxx) | 14 | ||||
-rw-r--r-- | xsd/xsd/cxx/tree/parser-header.cxx (renamed from xsd/cxx/tree/parser-header.cxx) | 6 | ||||
-rw-r--r-- | xsd/xsd/cxx/tree/parser-header.hxx (renamed from xsd/cxx/tree/parser-header.hxx) | 8 | ||||
-rw-r--r-- | xsd/xsd/cxx/tree/parser-source.cxx (renamed from xsd/cxx/tree/parser-source.cxx) | 6 | ||||
-rw-r--r-- | xsd/xsd/cxx/tree/parser-source.hxx (renamed from xsd/cxx/tree/parser-source.hxx) | 8 | ||||
-rw-r--r-- | xsd/xsd/cxx/tree/polymorphism-processor.cxx (renamed from xsd/cxx/tree/polymorphism-processor.cxx) | 8 | ||||
-rw-r--r-- | xsd/xsd/cxx/tree/polymorphism-processor.hxx (renamed from xsd/cxx/tree/polymorphism-processor.hxx) | 14 | ||||
-rw-r--r-- | xsd/xsd/cxx/tree/serialization-header.cxx (renamed from xsd/cxx/tree/serialization-header.cxx) | 6 | ||||
-rw-r--r-- | xsd/xsd/cxx/tree/serialization-header.hxx (renamed from xsd/cxx/tree/serialization-header.hxx) | 8 | ||||
-rw-r--r-- | xsd/xsd/cxx/tree/serialization-source.cxx (renamed from xsd/cxx/tree/serialization-source.cxx) | 59 | ||||
-rw-r--r-- | xsd/xsd/cxx/tree/serialization-source.hxx (renamed from xsd/cxx/tree/serialization-source.hxx) | 8 | ||||
-rw-r--r-- | xsd/xsd/cxx/tree/stream-extraction-source.cxx (renamed from xsd/cxx/tree/stream-extraction-source.cxx) | 6 | ||||
-rw-r--r-- | xsd/xsd/cxx/tree/stream-extraction-source.hxx (renamed from xsd/cxx/tree/stream-extraction-source.hxx) | 8 | ||||
-rw-r--r-- | xsd/xsd/cxx/tree/stream-header.cxx (renamed from xsd/cxx/tree/stream-header.cxx) | 6 | ||||
-rw-r--r-- | xsd/xsd/cxx/tree/stream-header.hxx (renamed from xsd/cxx/tree/stream-header.hxx) | 8 | ||||
-rw-r--r-- | xsd/xsd/cxx/tree/stream-insertion-header.cxx (renamed from xsd/cxx/tree/stream-insertion-header.cxx) | 6 | ||||
-rw-r--r-- | xsd/xsd/cxx/tree/stream-insertion-header.hxx (renamed from xsd/cxx/tree/stream-insertion-header.hxx) | 8 | ||||
-rw-r--r-- | xsd/xsd/cxx/tree/stream-insertion-source.cxx (renamed from xsd/cxx/tree/stream-insertion-source.cxx) | 6 | ||||
-rw-r--r-- | xsd/xsd/cxx/tree/stream-insertion-source.hxx (renamed from xsd/cxx/tree/stream-insertion-source.hxx) | 8 | ||||
-rw-r--r-- | xsd/xsd/cxx/tree/stream-source.cxx (renamed from xsd/cxx/tree/stream-source.cxx) | 6 | ||||
-rw-r--r-- | xsd/xsd/cxx/tree/stream-source.hxx (renamed from xsd/cxx/tree/stream-source.hxx) | 8 | ||||
-rw-r--r-- | xsd/xsd/cxx/tree/tree-forward.cxx (renamed from xsd/cxx/tree/tree-forward.cxx) | 8 | ||||
-rw-r--r-- | xsd/xsd/cxx/tree/tree-forward.hxx (renamed from xsd/cxx/tree/tree-forward.hxx) | 8 | ||||
-rw-r--r-- | xsd/xsd/cxx/tree/tree-header.cxx (renamed from xsd/cxx/tree/tree-header.cxx) | 48 | ||||
-rw-r--r-- | xsd/xsd/cxx/tree/tree-header.hxx (renamed from xsd/cxx/tree/tree-header.hxx) | 8 | ||||
-rw-r--r-- | xsd/xsd/cxx/tree/tree-inline.cxx (renamed from xsd/cxx/tree/tree-inline.cxx) | 14 | ||||
-rw-r--r-- | xsd/xsd/cxx/tree/tree-inline.hxx (renamed from xsd/cxx/tree/tree-inline.hxx) | 8 | ||||
-rw-r--r-- | xsd/xsd/cxx/tree/tree-source.cxx (renamed from xsd/cxx/tree/tree-source.cxx) | 38 | ||||
-rw-r--r-- | xsd/xsd/cxx/tree/tree-source.hxx (renamed from xsd/cxx/tree/tree-source.hxx) | 8 | ||||
-rw-r--r-- | xsd/xsd/cxx/tree/validator.cxx (renamed from xsd/cxx/tree/validator.cxx) | 15 | ||||
-rw-r--r-- | xsd/xsd/cxx/tree/validator.hxx (renamed from xsd/cxx/tree/validator.hxx) | 12 | ||||
-rw-r--r-- | xsd/xsd/elements.hxx (renamed from xsd/elements.hxx) | 12 | ||||
-rw-r--r-- | xsd/xsd/options-parser.hxx (renamed from xsd/options-parser.hxx) | 10 | ||||
-rw-r--r-- | xsd/xsd/options.cli (renamed from xsd/options.cli) | 20 | ||||
-rw-r--r-- | xsd/xsd/pregenerated/xsd/cxx/options.cxx | 739 | ||||
-rw-r--r-- | xsd/xsd/pregenerated/xsd/cxx/options.hxx | 451 | ||||
-rw-r--r-- | xsd/xsd/pregenerated/xsd/cxx/options.ixx | 615 | ||||
-rw-r--r-- | xsd/xsd/pregenerated/xsd/cxx/parser/options.cxx | 776 | ||||
-rw-r--r-- | xsd/xsd/pregenerated/xsd/cxx/parser/options.hxx | 186 | ||||
-rw-r--r-- | xsd/xsd/pregenerated/xsd/cxx/parser/options.ixx | 162 | ||||
-rw-r--r-- | xsd/xsd/pregenerated/xsd/cxx/tree/options.cxx | 1343 | ||||
-rw-r--r-- | xsd/xsd/pregenerated/xsd/cxx/tree/options.hxx | 414 | ||||
-rw-r--r-- | xsd/xsd/pregenerated/xsd/cxx/tree/options.ixx | 504 | ||||
-rw-r--r-- | xsd/xsd/pregenerated/xsd/options.cxx | 1297 | ||||
-rw-r--r-- | xsd/xsd/pregenerated/xsd/options.hxx | 702 | ||||
-rw-r--r-- | xsd/xsd/pregenerated/xsd/options.ixx | 555 | ||||
-rw-r--r-- | xsd/xsd/processing/cardinality/processor.cxx (renamed from xsd/processing/cardinality/processor.cxx) | 10 | ||||
-rw-r--r-- | xsd/xsd/processing/cardinality/processor.hxx | 28 | ||||
-rw-r--r-- | xsd/xsd/processing/inheritance/processor.cxx (renamed from xsd/processing/inheritance/processor.cxx) | 10 | ||||
-rw-r--r-- | xsd/xsd/processing/inheritance/processor.hxx | 28 | ||||
-rw-r--r-- | xsd/xsd/type-map/lexer.cxx (renamed from xsd/type-map/lexer.cxx) | 2 | ||||
-rw-r--r-- | xsd/xsd/type-map/lexer.hxx (renamed from xsd/type-map/lexer.hxx) | 2 | ||||
-rw-r--r-- | xsd/xsd/type-map/parser.cxx (renamed from xsd/type-map/parser.cxx) | 4 | ||||
-rw-r--r-- | xsd/xsd/type-map/parser.hxx (renamed from xsd/type-map/parser.hxx) | 6 | ||||
-rw-r--r-- | xsd/xsd/type-map/type-map.hxx (renamed from xsd/type-map/type-map.hxx) | 10 | ||||
-rw-r--r-- | xsd/xsd/types.hxx (renamed from xsd/types.hxx) | 8 | ||||
-rw-r--r-- | xsd/xsd/version.hxx.in | 55 | ||||
-rw-r--r-- | xsd/xsd/xsd.cxx (renamed from xsd/xsd.cxx) | 101 | ||||
-rw-r--r-- | xsd/xsd/xsd.hxx (renamed from xsd/xsd.hxx) | 14 |
161 files changed, 28682 insertions, 950 deletions
diff --git a/xsd/.gitignore b/xsd/.gitignore new file mode 100644 index 0000000..1c363a0 --- /dev/null +++ b/xsd/.gitignore @@ -0,0 +1,25 @@ +# Compiler/linker output. +# +*.d +*.t +*.i +*.i.* +*.ii +*.ii.* +*.o +*.obj +*.gcm +*.pcm +*.ifc +*.so +*.dylib +*.dll +*.a +*.lib +*.exp +*.pdb +*.ilk +*.exe +*.exe.dlls/ +*.exe.manifest +*.pc diff --git a/xsd/FLOSSE b/xsd/FLOSSE new file mode 120000 index 0000000..be6df3d --- /dev/null +++ b/xsd/FLOSSE @@ -0,0 +1 @@ +../FLOSSE
\ No newline at end of file diff --git a/xsd/GPLv2 b/xsd/GPLv2 new file mode 120000 index 0000000..08e5586 --- /dev/null +++ b/xsd/GPLv2 @@ -0,0 +1 @@ +../GPLv2
\ No newline at end of file diff --git a/xsd/LICENSE b/xsd/LICENSE new file mode 120000 index 0000000..ea5b606 --- /dev/null +++ b/xsd/LICENSE @@ -0,0 +1 @@ +../LICENSE
\ No newline at end of file diff --git a/xsd/NEWS b/xsd/NEWS new file mode 120000 index 0000000..0fae0f8 --- /dev/null +++ b/xsd/NEWS @@ -0,0 +1 @@ +../NEWS
\ No newline at end of file diff --git a/xsd/PACKAGE-README.md b/xsd/PACKAGE-README.md new file mode 120000 index 0000000..422e63f --- /dev/null +++ b/xsd/PACKAGE-README.md @@ -0,0 +1 @@ +../PACKAGE-README.md
\ No newline at end of file diff --git a/xsd/README.md b/xsd/README.md new file mode 100644 index 0000000..e2b2887 --- /dev/null +++ b/xsd/README.md @@ -0,0 +1,12 @@ +# xsd - XML Schema to C++ data binding compiler + +XSD is an open-source, cross-platform XML Schema to C++ data binding +compiler. Provided with an XML document specification (XML Schema), it +generates C++ classes that represent the given vocabulary as well as XML +parsing and serialization code. You can then access the data stored in XML +using types and functions that semantically correspond to your application +domain rather than dealing with generic elements/attributes and raw strings. + +For further information, including licensing conditions, documentation, and +binary packages, refer to the [XSD project +page](https://codesynthesis.com/products/xsd/). diff --git a/xsd/build/.gitignore b/xsd/build/.gitignore new file mode 100644 index 0000000..4a730a3 --- /dev/null +++ b/xsd/build/.gitignore @@ -0,0 +1,3 @@ +config.build +root/ +bootstrap/ diff --git a/xsd/build/bootstrap.build b/xsd/build/bootstrap.build new file mode 100644 index 0000000..6c0d4ab --- /dev/null +++ b/xsd/build/bootstrap.build @@ -0,0 +1,10 @@ +# file : build/bootstrap.build +# license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +project = xsd + +using version +using config +using test +using dist +using install diff --git a/xsd/build/export.build b/xsd/build/export.build new file mode 100644 index 0000000..68ffad0 --- /dev/null +++ b/xsd/build/export.build @@ -0,0 +1,9 @@ +# file : build/export.build +# license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +$out_root/ +{ + include xsd/ +} + +export $out_root/xsd/exe{xsd} diff --git a/xsd/build/root.build b/xsd/build/root.build new file mode 100644 index 0000000..cf9d6a6 --- /dev/null +++ b/xsd/build/root.build @@ -0,0 +1,37 @@ +# file : build/root.build +# license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +config [bool] config.xsd.develop ?= false + +develop = $config.xsd.develop + +define cli: file +cli{*}: extension = cli + +using in + +cxx.std = latest + +using cxx + +hxx{*}: extension = hxx +ixx{*}: extension = ixx +txx{*}: extension = txx +cxx{*}: extension = cxx + +if ($cxx.target.system == 'win32-msvc') + cxx.poptions += -D_CRT_SECURE_NO_WARNINGS -D_SCL_SECURE_NO_WARNINGS + +if ($cxx.class == 'msvc') + cxx.coptions += /wd4251 /wd4275 /wd4800 + +cxx.poptions =+ "-I$out_root" "-I$src_root" + +# Extract the copyright notice from the LICENSE file. +# +# Note that cat is a builtin which means this is both portable and fast. +# +if ($build.mode != 'skeleton') + copyright = $process.run_regex(cat $src_root/LICENSE, \ + 'Copyright \(c\) (.+)\.', \ + '\1') diff --git a/xsd/buildfile b/xsd/buildfile new file mode 100644 index 0000000..b0121dd --- /dev/null +++ b/xsd/buildfile @@ -0,0 +1,11 @@ +# file : buildfile +# license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +./: {*/ -build/} \ + doc{README.md PACKAGE-README.md NEWS} \ + legal{GPLv2 LICENSE FLOSSE} \ + manifest + +# Don't install tests. +# +tests/: install = false diff --git a/xsd/doc/.gitignore b/xsd/doc/.gitignore new file mode 100644 index 0000000..19b80b4 --- /dev/null +++ b/xsd/doc/.gitignore @@ -0,0 +1,5 @@ +/xsd.1 +/xsd.xhtml + +*.ps +*.pdf diff --git a/xsd/doc/buildfile b/xsd/doc/buildfile new file mode 100644 index 0000000..271d17e --- /dev/null +++ b/xsd/doc/buildfile @@ -0,0 +1,295 @@ +# file : doc/buildfile +# license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +define css: doc +css{*}: extension = css + +define xsd: doc +xsd{*}: extension = xsd + +define xhtml: doc +xhtml{*}: extension = xhtml + +define ps: doc +ps{*}: extension = ps + +define pdf: doc +pdf{*}: extension = pdf + +define html2ps: file +html2ps{*}: extension = html2ps + +define png: doc +png{*}: extension = png + +define svg: file +svg{*}: extension = svg + +./: css{default} xsd{custom-literals} {png svg}{**} + +# Note: doc_version is also used in the man pages and the manual. +# +doc_version = [string] "$version.major.$version.minor.$version.patch" +if $version.pre_release + doc_version += "-$version.pre_release_string" + +# Man pages. +# + +## Consumption build ($develop == false). +# + +# Use pregenerated versions in the consumption build. +# +./: pregenerated/{man1 xhtml}{*}: include = (!$develop) + +# Distribute pregenerated versions only in the consumption build. +# +pregenerated/{man1 xhtml}{*}: dist = (!$develop) + +# +## + +## Development build ($develop == true). +# + +./: {man1 xhtml}{xsd}: include = $develop + +if $develop +{ + # Let's take the last four-digit number to cover 2000-2021,2022. + # + doc_year = $regex.replace($copyright, '.+[-, ]([0-9][0-9][0-9][0-9]) .+', '\1') + + man_options = -v project="XSD" \ + -v version="$doc_version" \ + -v copyright="$copyright" \ + -I $src_root \ + --stdout \ + --suppress-undocumented \ + --exclude-base + + import! [metadata] cli = cli%exe{cli} +} + +# In the development build distribute regenerated versions, remapping their +# locations to the paths of the pregenerated versions (which are only +# distributed in the consumption build; see above). This way we make sure that +# the distributed files are always up-to-date. +# +{man1 xhtml}{xsd}: dist = ($develop ? pregenerated/ : false) + +ops = ../xsd/cli{options cxx/options cxx/tree/options cxx/parser/options} + +man1{xsd}: $ops \ + file{xsd-prologue.1 \ + xsd-tree-header.1 \ + xsd-parser-header.1 \ + xsd-epilogue.1} \ + $cli +% +if $develop +{{ + o = $path($>) + + # Use the copyright year to approximate the last authoring date. + # + $cli --generate-man $man_options \ + -v date="January $doc_year" \ + --class CXX::options \ + --class options \ + --man-prologue-file $path($<[4]) \ + $path($<[1]) >$o + + $cli --generate-man $man_options \ + -v date="January $doc_year" \ + --man-prologue-file $path($<[5]) \ + $path($<[2]) >>$o + + $cli --generate-man $man_options \ + -v date="January $doc_year" \ + --man-prologue-file $path($<[6]) \ + --man-epilogue-file $path($<[7]) \ + $path($<[3]) >>$o + + # If the result differs from the pregenerated version, copy it over. + # + if! diff $src_base/pregenerated/xsd.1 $o >- + cp $o $src_base/pregenerated/xsd.1 + end +}} + +xhtml{xsd}: $ops \ + file{xsd-prologue.xhtml \ + xsd-tree-header.xhtml \ + xsd-parser-header.xhtml \ + xsd-epilogue.xhtml} \ + $cli +% +if $develop +{{ + o = $path($>) + + $cli --generate-html $man_options \ + -v date="January $doc_year" \ + --class CXX::options \ + --class options \ + --html-prologue-file $path($<[4]) \ + $path($<[1]) >$o + + $cli --generate-html $man_options \ + -v date="January $doc_year" \ + --html-prologue-file $path($<[5]) \ + $path($<[2]) >>$o + + $cli --generate-html $man_options \ + -v date="January $doc_year" \ + --html-prologue-file $path($<[6]) \ + --html-epilogue-file $path($<[7]) \ + $path($<[3]) >>$o + + if! diff $src_base/pregenerated/xsd.xhtml $o >- + cp $o $src_base/pregenerated/xsd.xhtml + end +}} + +# +## + +# Manuals/guides. +# +# This case is slightly more involved because we make the generation of the +# manuals/guides ps/pdf files optional and also don't keep the result in the +# repository. Specifically: +# +# 1. In the consumption build we will install/redistribute ps/pdf if present. +# +# 2. In the development build we will generate ps/pdf if we are able to import +# the needed tools, issuing a warning otherwise. +# +# 3. We generate manuals/guides xhtml files from the templates and distribute +# them. + +manuals = cxx/parser/guide/index cxx/tree/guide/index cxx/tree/manual/index + +for m: $manuals +{ + ./: xhtml{$m}: in{$m} + { + in.symbol = '@' + + dist = true + clean = ($src_root != $out_root) + } +} + +## Consumption build ($develop == false). +# + +# Use pregenerated versions, if exist, in the consumption build. +# +./: pregenerated/{ps pdf}{**}: include = (!$develop) + +# Distribute pregenerated versions only in the consumption build. +# +pregenerated/{ps pdf}{*}: dist = (!$develop) + +# +## + +## Development build ($develop == true). +# + +html2pdf = false + +if $develop +{ + # Import the html2ps and ps2pdf programs from the system, if available. + # + import? html2ps = html2ps%exe{html2ps} + import? ps2pdf = ps2pdf14%exe{ps2pdf14} + + html2pdf = ($html2ps != [null] && $ps2pdf != [null]) + + if! $html2pdf + warn "html2ps and/or ps2pdf14 are not available, not generating .ps and .pdf documentation" +} + +for m: $manuals +{ + d = $directory($m) # cxx/parser/guide/, etc + p = "$leaf($directory($d))" # parser, tree + l = "$leaf($d)" # guide, manual + f = "cxx-$p-$l" # cxx-parser-guide, etc + + pf = $d/$f # cxx/parser/guide/cxx-parser-guide, etc + cf = $d/$l # cxx/parser/guide/guide, etc + + ./: {ps pdf}{$pf}: include = $html2pdf + + # In the development build distribute regenerated versions, remapping their + # locations to the paths of the pregenerated versions (which are only + # distributed in the consumption build; see above). This way we make sure + # that the distributed files are always up-to-date. + # + {ps pdf}{$pf}: \ + dist = ($html2pdf ? $relative([dir_path] "pregenerated/$d", $d) : false) + + pdf{$pf}: ps{$pf}: xhtml{$m} html2ps{$cf} + + html2ps{$cf}: in{$cf} + { + in.symbol = '@' + } +} + +# Note: the pregenerated file may not exist, thus --no-cleanup option is +# required for the mkdir and cp builtin calls. Strictly speaking we don't +# really need to copy them since they are not stored in the repository, but +# let's do that for consistency with the distributed source tree. +# +ps{~'/cxx-.+-(.+)/'}: xhtml{~'/index/'} html2ps{~'/\1/'} $html2ps +% +if $html2pdf +{{ + # cxx/parser/guide/, etc + # + d = [dir_path] $leaf($directory($path($>[0])), $out_base) + + # Note: --base must include trailing directory separator. + # + options = --base $src_base/$d + + diag html2ps ($<[0]) -> $> + $html2ps $options -f $path($<[1]) -o $path($>) $path($<[0]) + + # Note: must include trailing directory separator (see cp for details). + # + d = $src_base/pregenerated/$d + + mkdir -p --no-cleanup $d + cp --no-cleanup $path($>) $d +}} + +pdf{~'/(cxx-.+-.+)/'}: ps{~'/\1/'} $ps2pdf +% +if $html2pdf +{{ + options = -dOptimize=true -dEmbedAllFonts=true + + diag ps2pdf ($<[0]) -> $> + $ps2pdf $options $path($<[0]) $path($>) + + # Note: must include trailing directory separator (see cp for details). + # + d = $src_base/pregenerated/$leaf($directory($path($>[0])), $out_base) + + mkdir -p --no-cleanup $d + cp --no-cleanup $path($>) $d +}} + +# +## + +doc{*}: install.subdirs = true +pregenerated/doc{*}: install.subdirs = true diff --git a/xsd/doc/custom-literals.xsd b/xsd/doc/custom-literals.xsd new file mode 100644 index 0000000..c6f7613 --- /dev/null +++ b/xsd/doc/custom-literals.xsd @@ -0,0 +1,48 @@ +<?xml version="1.0"?> + +<!-- + +file : doc/custom-literals.xsd +copyright : not copyrighted - public domain + +This schema describes the XML format used to provide the custom string +to C++ string literal mapping with the -custom-literals XSD compiler +command line option. Here is a sample instance: + +<string-literal-map> + <entry> + <string>hello</string> + <literal>"hello"</literal> + </entry> + <entry> + <string>greeting</string> + <literal>"greeting"</literal> + </entry> +</string-literal-map> + +--> + +<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> + + <xsd:simpleType name="literal_t"> + <xsd:restriction base="xsd:string"> + <xsd:pattern value='".+"'/> + </xsd:restriction> + </xsd:simpleType> + + <xsd:complexType name="entry_t"> + <xsd:sequence> + <xsd:element name="string" type="xsd:string"/> + <xsd:element name="literal" type="literal_t"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:complexType name="string_literal_map_t"> + <xsd:sequence> + <xsd:element name="entry" type="entry_t" maxOccurs="unbounded"/> + </xsd:sequence> + </xsd:complexType> + + <xsd:element name="string-literal-map" type="string_literal_map_t"/> + +</xsd:schema> diff --git a/xsd/doc/cxx/.gitignore b/xsd/doc/cxx/.gitignore new file mode 100644 index 0000000..45f6b1e --- /dev/null +++ b/xsd/doc/cxx/.gitignore @@ -0,0 +1,2 @@ +*.xhtml +*.html2ps diff --git a/xsd/doc/cxx/parser/guide/figure-1.png b/xsd/doc/cxx/parser/guide/figure-1.png Binary files differnew file mode 100644 index 0000000..15d1723 --- /dev/null +++ b/xsd/doc/cxx/parser/guide/figure-1.png diff --git a/xsd/doc/cxx/parser/guide/figure-1.svg b/xsd/doc/cxx/parser/guide/figure-1.svg new file mode 100644 index 0000000..d994a79 --- /dev/null +++ b/xsd/doc/cxx/parser/guide/figure-1.svg @@ -0,0 +1,373 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://web.resource.org/cc/" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="744.09448819" + height="1052.3622047" + id="svg2" + sodipodi:version="0.32" + inkscape:version="0.44.1" + sodipodi:docbase="/tmp" + sodipodi:docname="figure-1.svg" + inkscape:export-filename="/home/boris/tmp/figure-1.png" + inkscape:export-xdpi="76.195885" + inkscape:export-ydpi="76.195885"> + <defs + id="defs4"> + <marker + inkscape:stockid="Arrow1Lend" + orient="auto" + refY="0.0" + refX="0.0" + id="Arrow1Lend" + style="overflow:visible;"> + <path + id="path2934" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;" + transform="scale(0.8) rotate(180) translate(12.5,0)" /> + </marker> + <marker + inkscape:stockid="Dot_l" + orient="auto" + refY="0.0" + refX="0.0" + id="Dot_l" + style="overflow:visible"> + <path + id="path2875" + d="M -2.5,-1.0 C -2.5,1.7600000 -4.7400000,4.0 -7.5,4.0 C -10.260000,4.0 -12.5,1.7600000 -12.5,-1.0 C -12.5,-3.7600000 -10.260000,-6.0 -7.5,-6.0 C -4.7400000,-6.0 -2.5,-3.7600000 -2.5,-1.0 z " + style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;marker-end:none" + transform="scale(0.8) translate(7.4, 1)" /> + </marker> + <marker + inkscape:stockid="Arrow1Mend" + orient="auto" + refY="0.0" + refX="0.0" + id="Arrow1Mend" + style="overflow:visible;"> + <path + id="path2928" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;" + transform="scale(0.4) rotate(180) translate(10,0)" /> + </marker> + <marker + inkscape:stockid="Dot_m" + orient="auto" + refY="0.0" + refX="0.0" + id="Dot_m" + style="overflow:visible"> + <path + id="path2872" + d="M -2.5,-1.0 C -2.5,1.7600000 -4.7400000,4.0 -7.5,4.0 C -10.260000,4.0 -12.5,1.7600000 -12.5,-1.0 C -12.5,-3.7600000 -10.260000,-6.0 -7.5,-6.0 C -4.7400000,-6.0 -2.5,-3.7600000 -2.5,-1.0 z " + style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;marker-end:none" + transform="scale(0.4) translate(7.4, 1)" /> + </marker> + <marker + inkscape:stockid="Arrow1Lstart" + orient="auto" + refY="0.0" + refX="0.0" + id="Arrow1Lstart" + style="overflow:visible"> + <path + id="path2937" + d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z " + style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none" + transform="scale(0.8) translate(12.5,0)" /> + </marker> + <marker + inkscape:stockid="Arrow2Mend" + orient="auto" + refY="0.0" + refX="0.0" + id="Arrow2Mend" + style="overflow:visible;"> + <path + id="path2910" + style="font-size:12.0;fill-rule:evenodd;stroke-width:0.62500000;stroke-linejoin:round;" + d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z " + transform="scale(0.6) rotate(180) translate(0,0)" /> + </marker> + </defs> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + gridtolerance="10000" + guidetolerance="10" + objecttolerance="10" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="0.98994949" + inkscape:cx="328.23027" + inkscape:cy="733.01096" + inkscape:document-units="px" + inkscape:current-layer="layer1" + inkscape:window-width="1280" + inkscape:window-height="991" + inkscape:window-x="154" + inkscape:window-y="44" /> + <metadata + id="metadata7"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1"> + <g + id="g3902"> + <rect + y="194.64178" + x="24.142784" + height="106.2678" + width="149.70432" + id="rect1872" + style="fill:#c5ddf8;fill-opacity:1;fill-rule:evenodd;stroke:#c5ddf8;stroke-width:5.29799986;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + <text + sodipodi:linespacing="125%" + id="text3038" + y="219.99649" + x="28.284279" + style="font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;color:black;fill:black;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;font-family:Monospace" + xml:space="preserve"><tspan + y="219.99649" + x="28.284279" + id="tspan3064" + sodipodi:role="line">class people_pimpl</tspan><tspan + y="236.24649" + x="28.284279" + id="tspan3066" + sodipodi:role="line">{</tspan><tspan + y="252.49649" + x="28.284279" + id="tspan3068" + sodipodi:role="line"> void </tspan><tspan + y="268.74649" + x="28.284279" + id="tspan3070" + sodipodi:role="line"> person ();</tspan><tspan + y="284.99649" + x="28.284279" + id="tspan3072" + sodipodi:role="line">};</tspan></text> + </g> + <g + id="g3881"> + <rect + y="124.93772" + x="252.43373" + height="245.67592" + width="180.01601" + id="rect5750" + style="fill:#c5ddf8;fill-opacity:1;fill-rule:evenodd;stroke:#c5ddf8;stroke-width:9.12976837;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + <text + sodipodi:linespacing="100%" + id="text5752" + y="148.27567" + x="257.5889" + style="font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;color:black;fill:black;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;font-family:Monospace" + xml:space="preserve"><tspan + y="148.27567" + x="257.5889" + id="tspan5900" + sodipodi:role="line">class person_pimpl</tspan><tspan + y="161.27567" + x="257.5889" + id="tspan5902" + sodipodi:role="line">{</tspan><tspan + y="174.27567" + x="257.5889" + id="tspan5904" + sodipodi:role="line"> void</tspan><tspan + y="187.27567" + x="257.5889" + id="tspan5906" + sodipodi:role="line"> first_name (string);</tspan><tspan + y="200.27567" + x="257.5889" + id="tspan5908" + sodipodi:role="line" /><tspan + y="213.27567" + x="257.5889" + id="tspan5910" + sodipodi:role="line"> void</tspan><tspan + y="226.27567" + x="257.5889" + id="tspan5912" + sodipodi:role="line"> last_name (string);</tspan><tspan + y="239.27567" + x="257.5889" + id="tspan5914" + sodipodi:role="line" /><tspan + y="252.27567" + x="257.5889" + id="tspan5916" + sodipodi:role="line"> void</tspan><tspan + y="265.27567" + x="257.5889" + id="tspan5918" + sodipodi:role="line"> gender ();</tspan><tspan + y="278.27567" + x="257.5889" + id="tspan5920" + sodipodi:role="line" /><tspan + y="291.27567" + x="257.5889" + id="tspan5922" + sodipodi:role="line"> void</tspan><tspan + y="304.27567" + x="257.5889" + id="tspan5924" + sodipodi:role="line"> age (short);</tspan><tspan + y="317.27567" + x="257.5889" + id="tspan5926" + sodipodi:role="line"> </tspan><tspan + y="330.27567" + x="257.5889" + id="tspan5928" + sodipodi:role="line"> void</tspan><tspan + y="343.27567" + x="257.5889" + id="tspan5930" + sodipodi:role="line"> post_person ();</tspan><tspan + y="356.27567" + x="257.5889" + id="tspan5932" + sodipodi:role="line">};</tspan></text> + </g> + <g + id="g3845"> + <rect + y="77.741814" + x="506.28357" + height="99.610825" + width="151.1286" + id="rect5955" + style="fill:#c5ddf8;fill-opacity:1;fill-rule:evenodd;stroke:#c5ddf8;stroke-width:5.69227886;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + <flowRoot + transform="translate(-5.050762,12.10153)" + style="font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Monospace" + id="flowRoot5957" + xml:space="preserve"><flowRegion + id="flowRegion5959"><rect + style="font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Monospace" + y="74.534515" + x="516.18793" + height="88.893425" + width="143.44167" + id="rect5961" /></flowRegion><flowPara + id="flowPara5965">class string_pimpl</flowPara><flowPara + id="flowPara5967">{</flowPara><flowPara + id="flowPara5969"> string</flowPara><flowPara + id="flowPara5971"> post_string ();</flowPara><flowPara + id="flowPara5973">};</flowPara><flowPara + id="flowPara5975" /></flowRoot> </g> + <g + id="g3857"> + <rect + style="fill:#c5ddf8;fill-opacity:1;fill-rule:evenodd;stroke:#c5ddf8;stroke-width:5.69227886;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect5977" + width="151.1286" + height="99.610825" + x="506.28357" + y="316.15808" /> + <flowRoot + xml:space="preserve" + id="flowRoot5979" + style="font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Monospace" + transform="translate(-5.050761,250.5178)" + inkscape:export-filename="/tmp/figure-1.png" + inkscape:export-xdpi="546.53815" + inkscape:export-ydpi="546.53815"><flowRegion + id="flowRegion5981"><rect + id="rect5983" + width="143.44167" + height="88.893425" + x="516.18793" + y="74.534515" + style="font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Monospace" /></flowRegion><flowPara + id="flowPara5985">class short_pimpl</flowPara><flowPara + id="flowPara5987">{</flowPara><flowPara + id="flowPara5989"> short</flowPara><flowPara + id="flowPara5991"> post_short ();</flowPara><flowPara + id="flowPara5993">};</flowPara><flowPara + id="flowPara5995" /></flowRoot> </g> + <g + id="g3869"> + <rect + style="fill:#c5ddf8;fill-opacity:1;fill-rule:evenodd;stroke:#c5ddf8;stroke-width:5.69227886;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" + id="rect6023" + width="151.1286" + height="99.610825" + x="505.7785" + y="196.93977" /> + <flowRoot + xml:space="preserve" + id="flowRoot6025" + style="font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Monospace" + transform="translate(-5.555838,129.2792)"><flowRegion + id="flowRegion6027"><rect + id="rect6029" + width="143.44167" + height="88.893425" + x="516.18793" + y="74.534515" + style="font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Monospace" /></flowRegion><flowPara + id="flowPara6031">class gender_pimpl</flowPara><flowPara + id="flowPara6033">{</flowPara><flowPara + id="flowPara6035"> void</flowPara><flowPara + id="flowPara6037"> post_gender ();</flowPara><flowPara + id="flowPara6039">};</flowPara><flowPara + id="flowPara6041" /></flowRoot> </g> + <path + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;marker-start:url(#Dot_l);marker-end:url(#Arrow1Lend)" + d="M 265.67011,339.69956 L 210.41811,339.34242 L 210.77124,264.14332 L 127.7843,264.4432" + id="path6051" + inkscape:connector-type="polyline" + sodipodi:nodetypes="cccs" /> + <path + sodipodi:nodetypes="cccc" + inkscape:connector-type="polyline" + id="path6077" + d="M 518.20825,383.6412 L 471.23616,384.14628 L 471.4887,300.55615 L 368.70568,300.80869" + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-start:url(#Dot_l);marker-end:url(#Arrow1Lend);stroke-opacity:1;display:inline" /> + <path + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-start:url(#Dot_l);marker-end:url(#Arrow1Lend);stroke-opacity:1;display:inline" + d="M 517.1981,262.42289 L 353.55339,262.42289" + id="path6081" + inkscape:connector-type="polyline" + sodipodi:nodetypes="cccs" /> + <path + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-start:url(#Dot_l);marker-end:url(#Arrow1Lend);stroke-opacity:1;display:inline" + d="M 518.57143,145.93361 L 470.35714,146.14281 L 470.53572,183.07646 L 431.42857,183.79075" + id="path6089" + inkscape:connector-type="polyline" + sodipodi:nodetypes="cccc" /> + <path + style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Lend);stroke-opacity:1;display:inline" + d="M 470.46175,178.43361 L 470.89286,222.36218 L 423.21428,222.71932" + id="path6091" + inkscape:connector-type="polyline" + sodipodi:nodetypes="ccc" /> + </g> +</svg> diff --git a/xsd/doc/cxx/parser/guide/guide.html2ps.in b/xsd/doc/cxx/parser/guide/guide.html2ps.in new file mode 100644 index 0000000..8131487 --- /dev/null +++ b/xsd/doc/cxx/parser/guide/guide.html2ps.in @@ -0,0 +1,65 @@ +@@html2ps { + option { + toc: hb; + colour: 1; + hyphenate: 1; + titlepage: 1; + } + + datefmt: "%B %Y"; + + titlepage { + content: " +<div align=center> + <h1><big>C++/Parser Mapping</big></h1> + <h1><big>Getting Started Guide</big></h1> + <h1> </h1> + <h1> </h1> + <h1> </h1> + <h1> </h1> + <h1> </h1> + <h1> </h1> +</div> + <p>Copyright © @copyright@.</p> + + <p>Permission is granted to copy, distribute and/or modify this + document under the terms of the + <a href='https://www.codesynthesis.com/licenses/fdl-1.2.txt'>GNU Free + Documentation License, version 1.2</a>; with no Invariant Sections, + no Front-Cover Texts and no Back-Cover Texts. + </p> + + <p>This document is available in the following formats: + <a href='https://www.codesynthesis.com/projects/xsd/documentation/cxx/parser/guide/index.xhtml'>XHTML</a>, + <a href='https://www.codesynthesis.com/projects/xsd/documentation/cxx/parser/guide/cxx-parser-guide.pdf'>PDF</a>, and + <a href='https://www.codesynthesis.com/projects/xsd/documentation/cxx/parser/guide/cxx-parser-guide.ps'>PostScript</a>.</p>"; + } + + toc { + indent: 2em; + } + + header { + odd-right: $H; + even-left: $H; + } + + footer { + odd-left: $D; + odd-center: $T; + odd-right: $N; + + even-left: $N; + even-center: $T; + even-right: $D; + } +} + +body { + font-size: 12pt; + text-align: justify; +} + +pre { + font-size: 10pt; +} diff --git a/xsd/doc/cxx/parser/guide/index.xhtml.in b/xsd/doc/cxx/parser/guide/index.xhtml.in new file mode 100644 index 0000000..119f421 --- /dev/null +++ b/xsd/doc/cxx/parser/guide/index.xhtml.in @@ -0,0 +1,4163 @@ +<?xml version="1.0" encoding="iso-8859-1"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"> + +<head> + <title>C++/Parser Mapping Getting Started Guide</title> + + <meta name="copyright" content="© @copyright@"/> + <meta name="keywords" content="xsd,xml,schema,c++,mapping,data,binding,parser,validation"/> + <meta name="description" content="C++/Parser Mapping Getting Started Guide"/> + + <link rel="stylesheet" type="text/css" href="../../../default.css" /> + +<style type="text/css"> + pre { + padding : 0 0 0 0em; + margin : 0em 0em 0em 0; + + font-size : 102% + } + + body { + min-width: 48em; + } + + h1 { + font-weight: bold; + font-size: 200%; + line-height: 1.2em; + } + + h2 { + font-weight : bold; + font-size : 150%; + + padding-top : 0.8em; + } + + h3 { + font-size : 140%; + padding-top : 0.8em; + } + + /* Adjust indentation for three levels. */ + #container { + max-width: 48em; + } + + #content { + padding: 0 0.1em 0 4em; + /*background-color: red;*/ + } + + #content h1 { + margin-left: -2.06em; + } + + #content h2 { + margin-left: -1.33em; + } + + /* Title page */ + + #titlepage { + padding: 2em 0 1em 0; + border-bottom: 1px solid black; + } + + #titlepage .title { + font-weight: bold; + font-size: 200%; + text-align: center; + } + + #titlepage #first-title { + padding: 1em 0 0.4em 0; + } + + #titlepage #second-title { + padding: 0.4em 0 2em 0; + } + + /* Lists */ + ul.list li { + padding-top : 0.3em; + padding-bottom : 0.3em; + } + + ol.steps { + padding-left : 1.8em; + } + + ol.steps li { + padding-top : 0.3em; + padding-bottom : 0.3em; + } + + + div.img { + text-align: center; + padding: 2em 0 2em 0; + } + + /* */ + dl dt { + padding : 0.8em 0 0 0; + } + + /* Built-in table */ + #builtin { + margin: 2em 0 2em 0; + + border-collapse : collapse; + border : 1px solid; + border-color : #000000; + + font-size : 11px; + line-height : 14px; + } + + #builtin th, #builtin td { + border: 1px solid; + padding : 0.9em 0.9em 0.7em 0.9em; + } + + #builtin th { + background : #cde8f6; + } + + #builtin td { + text-align: left; + } + + /* XML Schema features table. */ + #features { + margin: 2em 0 2em 0; + + border-collapse : collapse; + border : 1px solid; + border-color : #000000; + + font-size : 11px; + line-height : 14px; + } + + #features th, #features td { + border: 1px solid; + padding : 0.6em 0.6em 0.6em 0.6em; + } + + #features th { + background : #cde8f6; + } + + #features td { + text-align: left; + } + + + /* TOC */ + table.toc { + border-style : none; + border-collapse : separate; + border-spacing : 0; + + margin : 0.2em 0 0.2em 0; + padding : 0 0 0 0; + } + + table.toc tr { + padding : 0 0 0 0; + margin : 0 0 0 0; + } + + table.toc * td, table.toc * th { + border-style : none; + margin : 0 0 0 0; + vertical-align : top; + } + + table.toc * th { + font-weight : normal; + padding : 0em 0.1em 0em 0; + text-align : left; + white-space : nowrap; + } + + table.toc * table.toc th { + padding-left : 1em; + } + + table.toc * td { + padding : 0em 0 0em 0.7em; + text-align : left; + } +</style> + + +</head> + +<body> +<div id="container"> + <div id="content"> + + <div class="noprint"> + + <div id="titlepage"> + <div class="title" id="first-title">C++/Parser Mapping</div> + <div class="title" id="second-title">Getting Started Guide</div> + + <p>Copyright © @copyright@.</p> + + <p>Permission is granted to copy, distribute and/or modify this + document under the terms of the + <a href="https://www.codesynthesis.com/licenses/fdl-1.2.txt">GNU Free + Documentation License, version 1.2</a>; with no Invariant Sections, + no Front-Cover Texts and no Back-Cover Texts. + </p> + + <p>This document is available in the following formats: + <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/parser/guide/index.xhtml">XHTML</a>, + <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/parser/guide/cxx-parser-guide.pdf">PDF</a>, and + <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/parser/guide/cxx-parser-guide.ps">PostScript</a>.</p> + + </div> + + <h1>Table of Contents</h1> + + <table class="toc"> + <tr> + <th></th><td><a href="#0">Preface</a> + <table class="toc"> + <tr><th></th><td><a href="#0.1">About This Document</a></td></tr> + <tr><th></th><td><a href="#0.2">More Information</a></td></tr> + </table> + </td> + </tr> + + <tr> + <th>1</th><td><a href="#1">Introduction</a> + <table class="toc"> + <tr><th>1.1</th><td><a href="#1.1">Mapping Overview</a></td></tr> + <tr><th>1.2</th><td><a href="#1.2">Benefits</a></td></tr> + </table> + </td> + </tr> + + <tr> + <th>2</th><td><a href="#2">Hello World Example</a> + <table class="toc"> + <tr><th>2.1</th><td><a href="#2.1">Writing XML Document and Schema</a></td></tr> + <tr><th>2.2</th><td><a href="#2.2">Translating Schema to C++</a></td></tr> + <tr><th>2.3</th><td><a href="#2.3">Implementing Application Logic</a></td></tr> + <tr><th>2.4</th><td><a href="#2.4">Compiling and Running</a></td></tr> + </table> + </td> + </tr> + + <tr> + <th>3</th><td><a href="#3">Parser Skeletons</a> + <table class="toc"> + <tr><th>3.1</th><td><a href="#3.1">Implementing the Gender Parser</a></td></tr> + <tr><th>3.2</th><td><a href="#3.2">Implementing the Person Parser</a></td></tr> + <tr><th>3.3</th><td><a href="#3.3">Implementing the People Parser</a></td></tr> + <tr><th>3.4</th><td><a href="#3.4">Connecting the Parsers Together</a></td></tr> + </table> + </td> + </tr> + + <tr> + <th>4</th><td><a href="#4">Type Maps</a> + <table class="toc"> + <tr><th>4.1</th><td><a href="#4.1">Object Model</a></td></tr> + <tr><th>4.2</th><td><a href="#4.2">Type Map File Format</a></td></tr> + <tr><th>4.3</th><td><a href="#4.3">Parser Implementations</a></td></tr> + </table> + </td> + </tr> + + <tr> + <th>5</th><td><a href="#5">Mapping Configuration</a> + <table class="toc"> + <tr><th>5.1</th><td><a href="#5.1">C++ Standard</a></td></tr> + <tr><th>5.2</th><td><a href="#5.2">Character Type and Encoding</a></td></tr> + <tr><th>5.3</th><td><a href="#5.3">Underlying XML Parser</a></td></tr> + <tr><th>5.4</th><td><a href="#5.4">XML Schema Validation</a></td></tr> + <tr><th>5.5</th><td><a href="#5.5">Support for Polymorphism</a></td></tr> + </table> + </td> + </tr> + + <tr> + <th>6</th><td><a href="#6">Built-In XML Schema Type Parsers</a> + <table class="toc"> + <tr><th>6.1</th><td><a href="#6.1"><code>QName</code> Parser</a></td></tr> + <tr><th>6.2</th><td><a href="#6.2"><code>NMTOKENS</code> and <code>IDREFS</code> Parsers</a></td></tr> + <tr><th>6.3</th><td><a href="#6.3"><code>base64Binary</code> and <code>hexBinary</code> Parsers</a></td></tr> + <tr><th>6.4</th><td><a href="#6.4">Time Zone Representation</a></td></tr> + <tr><th>6.5</th><td><a href="#6.5"><code>date</code> Parser</a></td></tr> + <tr><th>6.6</th><td><a href="#6.6"><code>dateTime</code> Parser</a></td></tr> + <tr><th>6.7</th><td><a href="#6.7"><code>duration</code> Parser</a></td></tr> + <tr><th>6.8</th><td><a href="#6.8"><code>gDay</code> Parser</a></td></tr> + <tr><th>6.9</th><td><a href="#6.9"><code>gMonth</code> Parser</a></td></tr> + <tr><th>6.10</th><td><a href="#6.10"><code>gMonthDay</code> Parser</a></td></tr> + <tr><th>6.11</th><td><a href="#6.11"><code>gYear</code> Parser</a></td></tr> + <tr><th>6.12</th><td><a href="#6.12"><code>gYearMonth</code> Parser</a></td></tr> + <tr><th>6.13</th><td><a href="#6.13"><code>time</code> Parser</a></td></tr> + </table> + </td> + </tr> + + <tr> + <th>7</th><td><a href="#7">Document Parser and Error Handling</a> + <table class="toc"> + <tr><th>7.1</th><td><a href="#7.1">Xerces-C++ Document Parser</a></td></tr> + <tr><th>7.2</th><td><a href="#7.2">Expat Document Parser</a></td></tr> + <tr><th>7.3</th><td><a href="#7.3">Error Handling</a></td></tr> + </table> + </td> + </tr> + + <tr> + <th></th><td><a href="#A">Appendix A — Supported XML Schema Constructs</a></td> + </tr> + + </table> + </div> + + <h1><a name="0">Preface</a></h1> + + <h2><a name="0.1">About This Document</a></h2> + + <p>The goal of this document is to provide you with an understanding of + the C++/Parser programming model and allow you to efficiently evaluate + XSD against your project's technical requirements. As such, this + document is intended for C++ developers and software architects + who are looking for an XML processing solution. Prior experience + with XML and C++ is required to understand this document. Basic + understanding of XML Schema is advantageous but not expected + or required. + </p> + + + <h2><a name="0.2">More Information</a></h2> + + <p>Beyond this guide, you may also find the following sources of + information useful:</p> + + <ul class="list"> + <li><a href="https://www.codesynthesis.com/projects/xsd/documentation/xsd.xhtml">XSD + Compiler Command Line Manual</a></li> + + <li>The <code>cxx/parser/</code> directory in the + <a href="https://cppget.org/xsd-examples">xsd-examples</a> package + contains a collection of examples and a README file with an overview + of each example.</li> + + <li>The <code>README</code> file in the + <a href="https://cppget.org/xsd-examples">xsd-examples</a> package + explains how to build the examples.</li> + + <li>The <a href="https://www.codesynthesis.com/mailman/listinfo/xsd-users">xsd-users</a> + mailing list is the place to ask technical questions about XSD and the C++/Parser mapping. + Furthermore, the <a href="https://www.codesynthesis.com/pipermail/xsd-users/">archives</a> + may already have answers to some of your questions.</li> + + </ul> + + <!-- Introduction --> + + <h1><a name="1">1 Introduction</a></h1> + + <p>Welcome to CodeSynthesis XSD and the C++/Parser mapping. XSD is a + cross-platform W3C XML Schema to C++ data binding compiler. C++/Parser + is a W3C XML Schema to C++ mapping that represents an XML vocabulary + as a set of parser skeletons which you can implement to perform XML + processing as required by your application logic. + </p> + + <h2><a name="1.1">1.1 Mapping Overview</a></h2> + + <p>The C++/Parser mapping provides event-driven, stream-oriented + XML parsing, XML Schema validation, and C++ data binding. It was + specifically designed and optimized for high performance and + small footprint. Based on the static analysis of the schemas, XSD + generates compact, highly-optimized hierarchical state machines + that combine data extraction, validation, and even dispatching + in a single step. As a result, the generated code is typically + 2-10 times faster than general-purpose validating XML parsers + while maintaining the lowest static and dynamic memory footprints. + </p> + + <p>To speed up application development, the C++/Parser mapping + can be instructed to generate sample parser implementations + and a test driver which can then be filled with the application + logic code. The mapping also provides a wide range of + mechanisms for controlling and customizing the generated code.</p> + + <p>The next chapter shows how to create a simple application that uses + the C++/Parser mapping to parse, validate, and extract data from a + simple XML document. The following chapters show how to + use the C++/Parser mapping in more detail.</p> + + <h2><a name="1.2">1.2 Benefits</a></h2> + + <p>Traditional XML access APIs such as Document Object Model (DOM) + or Simple API for XML (SAX) have a number of drawbacks that + make them less suitable for creating robust and maintainable + XML processing applications. These drawbacks include: + </p> + + <ul class="list"> + <li>Generic representation of XML in terms of elements, attributes, + and text forces an application developer to write a substantial + amount of bridging code that identifies and transforms pieces + of information encoded in XML to a representation more suitable + for consumption by the application logic.</li> + + <li>String-based flow control defers error detection to runtime. + It also reduces code readability and maintainability.</li> + + <li>Lack of type safety because the data is represented + as text.</li> + + <li>Resulting applications are hard to debug, change, and + maintain.</li> + </ul> + + <p>In contrast, statically-typed, vocabulary-specific parser + skeletons produced by the C++/Parser mapping allow you to + operate in your domain terms instead of the generic elements, + attributes, and text. Static typing helps catch errors at + compile-time rather than at run-time. Automatic code generation + frees you for more interesting tasks (such as doing something + useful with the information stored in the XML documents) and + minimizes the effort needed to adapt your applications to + changes in the document structure. To summarize, the C++/Parser + mapping has the following key advantages over generic XML + access APIs:</p> + + <ul class="list"> + <li><b>Ease of use.</b> The generated code hides all the complexity + associated with recreating the document structure, maintaining the + dispatch state, and converting the data from the text representation + to data types suitable for manipulation by the application logic. + Parser skeletons also provide a convenient mechanism for building + custom in-memory representations.</li> + + <li><b>Natural representation.</b> The generated parser skeletons + implement parser callbacks as virtual functions with names + corresponding to elements and attributes in XML. As a result, + you process the XML data using your domain vocabulary instead + of generic elements, attributes, and text. + </li> + + <li><b>Concise code.</b> With a separate parser skeleton for each + XML Schema type, the application implementation is + simpler and thus easier to read and understand.</li> + + <li><b>Safety.</b> The XML data is delivered to parser callbacks as + statically typed objects. The parser callbacks themselves are virtual + functions. This helps catch programming errors at compile-time + rather than at runtime.</li> + + <li><b>Maintainability.</b> Automatic code generation minimizes the + effort needed to adapt the application to changes in the + document structure. With static typing, the C++ compiler + can pin-point the places in the application code that need to be + changed.</li> + + <li><b>Efficiency.</b> The generated parser skeletons combine + data extraction, validation, and even dispatching in a single + step. This makes them much more efficient than traditional + architectures with separate stages for validation and data + extraction/dispatch.</li> + </ul> + + <!-- Hello World Parser --> + + + <h1><a name="2">2 Hello World Example</a></h1> + + <p>In this chapter we will examine how to parse a very simple XML + document using the XSD-generated C++/Parser skeletons. + The code presented in this chapter is based on the <code>hello</code> + example which can be found in the <code>cxx/parser/</code> directory in + the <a href="https://cppget.org/xsd-examples">xsd-examples</a> + package.</p> + + <h2><a name="2.1">2.1 Writing XML Document and Schema</a></h2> + + <p>First, we need to get an idea about the structure + of the XML documents we are going to process. Our + <code>hello.xml</code>, for example, could look like this:</p> + + <pre class="xml"> +<?xml version="1.0"?> +<hello> + + <greeting>Hello</greeting> + + <name>sun</name> + <name>moon</name> + <name>world</name> + +</hello> + </pre> + + <p>Then we can write a description of the above XML in the + XML Schema language and save it into <code>hello.xsd</code>:</p> + + <pre class="xml"> +<?xml version="1.0"?> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> + + <xs:complexType name="hello"> + <xs:sequence> + <xs:element name="greeting" type="xs:string"/> + <xs:element name="name" type="xs:string" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + + <xs:element name="hello" type="hello"/> + +</xs:schema> + </pre> + + <p>Even if you are not familiar with XML Schema, it + should be easy to connect declarations in <code>hello.xsd</code> + to elements in <code>hello.xml</code>. The <code>hello</code> type + is defined as a sequence of the nested <code>greeting</code> and + <code>name</code> elements. Note that the term sequence in XML + Schema means that elements should appear in a particular order + as opposed to appearing multiple times. The <code>name</code> + element has its <code>maxOccurs</code> property set to + <code>unbounded</code> which means it can appear multiple times + in an XML document. Finally, the globally-defined <code>hello</code> + element prescribes the root element for our vocabulary. For an + easily-approachable introduction to XML Schema refer to + <a href="http://www.w3.org/TR/xmlschema-0/">XML Schema Part 0: + Primer</a>.</p> + + <p>The above schema is a specification of our XML vocabulary; it tells + everybody what valid documents of our XML-based language should look + like. The next step is to compile this schema to generate + the object model and parsing functions.</p> + + <h2><a name="2.2">2.2 Translating Schema to C++</a></h2> + + <p>Now we are ready to translate our <code>hello.xsd</code> to C++ parser + skeletons. To do this we invoke the XSD compiler from a terminal + (UNIX) or a command prompt (Windows): + </p> + + <pre class="terminal"> +$ xsd cxx-parser --xml-parser expat hello.xsd + </pre> + + <p>The <code>--xml-parser</code> option indicates that we want to + use Expat as the underlying XML parser (see <a href="#5.3">Section + 5.3, "Underlying XML Parser"</a>). The XSD compiler produces two + C++ files: <code>hello-pskel.hxx</code> and <code>hello-pskel.cxx</code>. + The following code fragment is taken from <code>hello-pskel.hxx</code>; + it should give you an idea about what gets generated: + </p> + + <pre class="c++"> +class hello_pskel +{ +public: + // Parser callbacks. Override them in your implementation. + // + virtual void + pre (); + + virtual void + greeting (const std::string&); + + virtual void + name (const std::string&); + + virtual void + post_hello (); + + // Parser construction API. + // + void + greeting_parser (xml_schema::string_pskel&); + + void + name_parser (xml_schema::string_pskel&); + + void + parsers (xml_schema::string_pskel& /* greeting */, + xml_schema::string_pskel& /* name */); + +private: + ... +}; + </pre> + + <p>The first four member functions shown above are called parser + callbacks. You would normally override them in your implementation + of the parser to do something useful. Let's go through all of + them one by one.</p> + + <p>The <code>pre()</code> function is an initialization callback. It is + called when a new element of type <code>hello</code> is about + to be parsed. You would normally use this function to allocate a new + instance of the resulting type or clear accumulators that are used + to gather information during parsing. The default implementation + of this function does nothing.</p> + + <p>The <code>post_hello()</code> function is a finalization callback. Its + name is constructed by adding the parser skeleton name to the + <code>post_</code> prefix. The finalization callback is called when + parsing of the element is complete and the result, if any, should + be returned. Note that in our case the return type of + <code>post_hello()</code> is <code>void</code> which means there + is nothing to return. More on parser return types later. + </p> + + <p>You may be wondering why the finalization callback is called + <code>post_hello()</code> instead of <code>post()</code> just + like <code>pre()</code>. The reason for this is that + finalization callbacks can have different return types and + result in function signature clashes across inheritance + hierarchies. To prevent this the signatures of finalization + callbacks are made unique by adding the type name to their names.</p> + + <p>The <code>greeting()</code> and <code>name()</code> functions are + called when the <code>greeting</code> and <code>name</code> elements + have been parsed, respectively. Their arguments are of type + <code>std::string</code> and contain the data extracted from XML.</p> + + <p>The last three functions are for connecting parsers to each other. + For example, there is a predefined parser for built-in XML Schema type + <code>string</code> in the XSD runtime. We will be using + it to parse the contents of <code>greeting</code> and + <code>name</code> elements, as shown in the next section.</p> + + <h2><a name="2.3">2.3 Implementing Application Logic</a></h2> + + <p>At this point we have all the parts we need to do something useful + with the information stored in our XML document. The first step is + to implement the parser: + </p> + + <pre class="c++"> +#include <iostream> +#include "hello-pskel.hxx" + +class hello_pimpl: public hello_pskel +{ +public: + virtual void + greeting (const std::string& g) + { + greeting_ = g; + } + + virtual void + name (const std::string& n) + { + std::cout << greeting_ << ", " << n << "!" << std::endl; + } + +private: + std::string greeting_; +}; + </pre> + + <p>We left both <code>pre()</code> and <code>post_hello()</code> with the + default implementations; we don't have anything to initialize or + return. The rest is pretty straightforward: we store the greeting + in a member variable and later, when parsing names, use it to + say hello.</p> + + <p>An observant reader my ask what happens if the <code>name</code> + element comes before <code>greeting</code>? Don't we need to + make sure <code>greeting_</code> was initialized and report + an error otherwise? The answer is no, we don't have to do + any of this. The <code>hello_pskel</code> parser skeleton + performs validation of XML according to the schema from which + it was generated. As a result, it will check the order + of the <code>greeting</code> and <code>name</code> elements + and report an error if it is violated.</p> + + <p>Now it is time to put this parser implementation to work:</p> + + <pre class="c++"> +using namespace std; + +int +main (int argc, char* argv[]) +{ + try + { + // Construct the parser. + // + xml_schema::string_pimpl string_p; + hello_pimpl hello_p; + + hello_p.greeting_parser (string_p); + hello_p.name_parser (string_p); + + // Parse the XML instance. + // + xml_schema::document doc_p (hello_p, "hello"); + + hello_p.pre (); + doc_p.parse (argv[1]); + hello_p.post_hello (); + } + catch (const xml_schema::exception& e) + { + cerr << e << endl; + return 1; + } +} + </pre> + + <p>The first part of this code snippet instantiates individual parsers + and assembles them into a complete vocabulary parser. + <code>xml_schema::string_pimpl</code> is an implementation of a parser + for built-in XML Schema type <code>string</code>. It is provided by + the XSD runtime along with parsers for other built-in types (for + more information on the built-in parsers see <a href="#6">Chapter 6, + "Built-In XML Schema Type Parsers"</a>). We use <code>string_pimpl</code> + to parse the <code>greeting</code> and <code>name</code> elements as + indicated by the calls to <code>greeting_parser()</code> and + <code>name_parser()</code>. + </p> + + <p>Then we instantiate a document parser (<code>doc_p</code>). The + first argument to its constructor is the parser for + the root element (<code>hello_p</code> in our case). The + second argument is the root element name. + </p> + + <p>The final piece is the calls to <code>pre()</code>, <code>parse()</code>, + and <code>post_hello()</code>. The call to <code>parse()</code> + perform the actual XML parsing while the calls to <code>pre()</code> and + <code>post_hello()</code> make sure that the parser for the root + element can perform proper initialization and cleanup.</p> + + <p>While our parser implementation and test driver are pretty small and + easy to write by hand, for bigger XML vocabularies it can be a + substantial effort. To help with this task XSD can automatically + generate sample parser implementations and a test driver from your + schemas. You can request the generation of a sample implementation with + empty function bodies by specifying the <code>--generate-noop-impl</code> + option. Or you can generate a sample implementation that prints the + data store in XML by using the <code>--generate-print-impl</code> + option. To request the generation of a test driver you can use the + <code>--generate-test-driver</code> option. For more information + on these options refer to the + <a href="https://www.codesynthesis.com/projects/xsd/documentation/xsd.xhtml">XSD + Compiler Command Line Manual</a>. The <code>'generated'</code> example + in the <a href="https://cppget.org/xsd-examples">xsd-examples</a> package + shows the sample implementation generation feature in action.</p> + + + <h2><a name="2.4">2.4 Compiling and Running</a></h2> + + <p>After saving all the parts from the previous section in + <code>driver.cxx</code>, we are ready to compile our first + application and run it on the test XML document. On a UNIX + system this can be done with the following commands: + </p> + + <pre class="terminal"> +$ c++ -std=c++11 -I.../libxsd -c driver.cxx hello-pskel.cxx +$ c++ -std=c++11 -o driver driver.o hello-pskel.o -lexpat +$ ./driver hello.xml +Hello, sun! +Hello, moon! +Hello, world! + </pre> + + <p>Here <code>.../libxsd</code> represents the path to the + <a href="https://cppget.org/libxsd">libxsd</a> package root + directory. We can also test the error handling. To test XML + well-formedness checking, we can try to parse + <code>hello-pskel.hxx</code>:</p> + + <pre class="terminal"> +$ ./driver hello-pskel.hxx +hello-pskel.hxx:1:0: not well-formed (invalid token) + </pre> + + <p>We can also try to parse a valid XML but not from our + vocabulary, for example <code>hello.xsd</code>:</p> + + <pre class="terminal"> +$ ./driver hello.xsd +hello.xsd:2:0: expected element 'hello' instead of +'http://www.w3.org/2001/XMLSchema#schema' + </pre> + + + <!-- Chapater 3 --> + + + <h1><a name="3">3 Parser Skeletons</a></h1> + + <p>As we have seen in the previous chapter, the XSD compiler generates + a parser skeleton class for each type defined in XML Schema. In + this chapter we will take a closer look at different functions + that comprise a parser skeleton as well as the way to connect + our implementations of these parser skeletons to create a complete + parser.</p> + + <p>In this and subsequent chapters we will use the following schema + that describes a collection of person records. We save it in + <code>people.xsd</code>:</p> + + <pre class="xml"> +<?xml version="1.0"?> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> + + <xs:simpleType name="gender"> + <xs:restriction base="xs:string"> + <xs:enumeration value="male"/> + <xs:enumeration value="female"/> + </xs:restriction> + </xs:simpleType> + + <xs:complexType name="person"> + <xs:sequence> + <xs:element name="first-name" type="xs:string"/> + <xs:element name="last-name" type="xs:string"/> + <xs:element name="gender" type="gender"/> + <xs:element name="age" type="xs:short"/> + </xs:sequence> + </xs:complexType> + + <xs:complexType name="people"> + <xs:sequence> + <xs:element name="person" type="person" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + + <xs:element name="people" type="people"/> + +</xs:schema> + </pre> + + <p>A sample XML instance to go along with this schema is saved + in <code>people.xml</code>:</p> + + <pre class="xml"> +<?xml version="1.0"?> +<people> + <person> + <first-name>John</first-name> + <last-name>Doe</last-name> + <gender>male</gender> + <age>32</age> + </person> + <person> + <first-name>Jane</first-name> + <last-name>Doe</last-name> + <gender>female</gender> + <age>28</age> + </person> +</people> + </pre> + + <p>Compiling <code>people.xsd</code> with the XSD compiler results + in three parser skeletons being generated: <code>gender_pskel</code>, + <code>person_pskel</code>, and <code>people_pskel</code>. We are going + to examine and implement each of them in the subsequent sections.</p> + + <h2><a name="3.1">3.1 Implementing the Gender Parser</a></h2> + + <p>The generated <code>gender_pskel</code> parser skeleton looks like + this:</p> + + <pre class="c++"> +class gender_pskel: public virtual xml_schema::string_pskel +{ +public: + // Parser callbacks. Override them in your implementation. + // + virtual void + pre (); + + virtual void + post_gender (); +}; + </pre> + + <p>Notice that <code>gender_pskel</code> inherits from + <code>xml_schema::string_skel</code> which is a parser skeleton + for built-in XML Schema type <code>string</code> and is + predefined in the XSD runtime library. This is an example + of the general rule that parser skeletons follow: if a type + in XML Schema inherits from another then there will be an + equivalent inheritance between the corresponding parser + skeleton classes.</p> + + <p>The <code>pre()</code> and <code>post_gender()</code> callbacks + should look familiar from the previous chapter. Let's now + implement the parser. Our implementation will simply print + the gender to <code>cout</code>:</p> + + + <pre class="c++"> +class gender_pimpl: public gender_pskel, + public xml_schema::string_pimpl +{ +public: + virtual void + post_gender () + { + std::string s = post_string (); + cout << "gender: " << s << endl; + } +}; + </pre> + + <p>While the code is quite short, there is a lot going on. First, + notice that we are inheriting from <code>gender_pskel</code> <em>and</em> + from <code>xml_schema::string_pimpl</code>. We've encountered + <code>xml_schema::string_pimpl</code> already; it is an + implementation of the <code>xml_schema::string_pskel</code> parser + skeleton for built-in XML Schema type <code>string</code>.</p> + + <p>This is another common theme in the C++/Parser programming model: + reusing implementations of the base parsers in the derived ones with + the C++ mixin idiom. In our case, <code>string_pimpl</code> will + do all the dirty work of extracting the data and we can just get + it at the end with the call to <code>post_string()</code>.</p> + + <p>In case you are curious, here is what + <code>xml_schema::string_pskel</code> and + <code>xml_schema::string_pimpl</code> look like:</p> + + <pre class="c++"> +namespace xml_schema +{ + class string_pskel: public simple_content + { + public: + virtual std::string + post_string () = 0; + }; + + class string_pimpl: public virtual string_pskel + { + public: + virtual void + _pre (); + + virtual void + _characters (const xml_schema::ro_string&); + + virtual std::string + post_string (); + + protected: + std::string str_; + }; +} + </pre> + + <p>There are three new pieces in this code that we haven't seen yet. + They are the <code>simple_content</code> class as well as + the <code>_pre()</code> and <code>_characters()</code> functions. + The <code>simple_content</code> class is defined in the XSD + runtime and is a base class for all parser skeletons that conform + to the simple content model in XML Schema. Types with the + simple content model cannot have nested elements—only text + and attributes. There is also the <code>complex_content</code> + class which corresponds to the complex content mode (types with + nested elements, for example, <code>person</code> from + <code>people.xsd</code>).</p> + + <p>The <code>_pre()</code> function is a parser callback. Remember we + talked about the <code>pre()</code> and <code>post_*()</code> callbacks + in the previous chapter? There are actually two more callbacks + with similar roles: <code>_pre()</code> and <code>_post ()</code>. + As a result, each parser skeleton has four special callbacks:</p> + + <pre class="c++"> + virtual void + pre (); + + virtual void + _pre (); + + virtual void + _post (); + + virtual void + post_name (); + </pre> + + <p><code>pre()</code> and <code>_pre()</code> are initialization + callbacks. They get called in that order before a new instance of the type + is about to be parsed. The difference between <code>pre()</code> and + <code>_pre()</code> is conventional: <code>pre()</code> can + be completely overridden by a derived parser. The derived + parser can also override <code>_pre()</code> but has to always call + the original version. This allows you to partition initialization + into customizable and required parts.</p> + + <p>Similarly, <code>_post()</code> and <code>post_name()</code> are + finalization callbacks with exactly the same semantics: + <code>post_name()</code> can be completely overridden by the derived + parser while the original <code>_post()</code> should always be called. + </p> + + <p>The final bit we need to discuss in this section is the + <code>_characters()</code> function. As you might have guessed, it + is also a callback. A low-level one that delivers raw character content + for the type being parsed. You will seldom need to use this callback + directly. Using implementations for the built-in parsers provided by + the XSD runtime is usually a simpler and more convenient + alternative.</p> + + <p>At this point you might be wondering why some <code>post_*()</code> + callbacks, for example <code>post_string()</code>, return some data + while others, for example <code>post_gender()</code>, have + <code>void</code> as a return type. This is a valid concern + and it will be addressed in the next chapter.</p> + + <h2><a name="3.2">3.2 Implementing the Person Parser</a></h2> + + <p>The generated <code>person_pskel</code> parser skeleton looks like + this:</p> + + <pre class="c++"> +class person_pskel: public xml_schema::complex_content +{ +public: + // Parser callbacks. Override them in your implementation. + // + virtual void + pre (); + + virtual void + first_name (const std::string&); + + virtual void + last_name (const std::string&); + + virtual void + gender (); + + virtual void + age (short); + + virtual void + post_person (); + + // Parser construction API. + // + void + first_name_parser (xml_schema::string_pskel&); + + void + last_name_parser (xml_schema::string_pskel&); + + void + gender_parser (gender_pskel&); + + void + age_parser (xml_schema::short_pskel&); + + void + parsers (xml_schema::string_pskel& /* first-name */, + xml_schema::string_pskel& /* last-name */, + gender_pskel& /* gender */, + xml_schema::short_pskel& /* age */); +}; + </pre> + + + <p>As you can see, we have a parser callback for each of the nested + elements found in the <code>person</code> XML Schema type. + The implementation of this parser is straightforward:</p> + + <pre class="c++"> +class person_pimpl: public person_pskel +{ +public: + virtual void + first_name (const std::string& n) + { + cout << "first: " << f << endl; + } + + virtual void + last_name (const std::string& l) + { + cout << "last: " << l << endl; + } + + virtual void + age (short a) + { + cout << "age: " << a << endl; + } +}; + </pre> + + <p>Notice that we didn't override the <code>gender()</code> callback + because all the printing is done by <code>gender_pimpl</code>.</p> + + + <h2><a name="3.3">3.3 Implementing the People Parser</a></h2> + + <p>The generated <code>people_pskel</code> parser skeleton looks like + this:</p> + + <pre class="c++"> +class people_pskel: public xml_schema::complex_content +{ +public: + // Parser callbacks. Override them in your implementation. + // + virtual void + pre (); + + virtual void + person (); + + virtual void + post_people (); + + // Parser construction API. + // + void + person_parser (person_pskel&); + + void + parsers (person_pskel& /* person */); +}; + </pre> + + <p>The <code>person()</code> callback will be called after parsing each + <code>person</code> element. While <code>person_pimpl</code> does + all the printing, one useful thing we can do in this callback is to + print an extra newline after each person record so that our + output is more readable:</p> + + <pre class="c++"> +class people_pimpl: public people_pskel +{ +public: + virtual void + person () + { + cout << endl; + } +}; + </pre> + + <p>Now it is time to put everything together.</p> + + + <h2><a name="3.4">3.4 Connecting the Parsers Together</a></h2> + + <p>At this point we have all the individual parsers implemented + and can proceed to assemble them into a complete parser + for our XML vocabulary. The first step is to instantiate + all the individual parsers that we will need:</p> + + <pre class="c++"> +xml_schema::short_pimpl short_p; +xml_schema::string_pimpl string_p; + +gender_pimpl gender_p; +person_pimpl person_p; +people_pimpl people_p; + </pre> + + <p>Notice that our schema uses two built-in XML Schema types: + <code>string</code> for the <code>first-name</code> and + <code>last-name</code> elements as well as <code>short</code> + for <code>age</code>. We will use predefined parsers that + come with the XSD runtime to handle these types. The next + step is to connect all the individual parsers. We do this + with the help of functions defined in the parser + skeletons and marked with the "Parser Construction API" + comment. One way to do it is to connect each individual + parser by calling the <code>*_parser()</code> functions:</p> + + <pre class="c++"> +person_p.first_name_parser (string_p); +person_p.last_name_parser (string_p); +person_p.gender_parser (gender_p); +person_p.age_parser (short_p); + +people_p.person_parser (person_p); + </pre> + + <p>You might be wondering what happens if you do not provide + a parser by not calling one of the <code>*_parser()</code> functions. + In that case the corresponding XML content will be skipped, + including validation. This is an efficient way to ignore parts + of the document that you are not interested in.</p> + + + <p>An alternative, shorter, way to connect the parsers is by using + the <code>parsers()</code> functions which connects all the parsers + for a given type at once:</p> + + <pre class="c++"> +person_p.parsers (string_p, string_p, gender_p, short_p); +people_p.parsers (person_p); + </pre> + + <p>The following figure illustrates the resulting connections. Notice + the correspondence between return types of the <code>post_*()</code> + functions and argument types of element callbacks that are connected + by the arrows.</p> + + <!-- align=center is needed for html2ps --> + <div class="img" align="center"><img src="figure-1.png"/></div> + + <p>The last step is the construction of the document parser and + invocation of the complete parser on our sample XML instance:</p> + + <pre class="c++"> +xml_schema::document doc_p (people_p, "people"); + +people_p.pre (); +doc_p.parse ("people.xml"); +people_p.post_people (); + </pre> + + <p>Let's consider <code>xml_schema::document</code> in + more detail. While the exact definition of this class + varies depending on the underlying parser selected, + here is the common part:</p> + + <pre class="c++"> +namespace xml_schema +{ + class document + { + public: + document (xml_schema::parser_base&, + const std::string& root_element_name, + bool polymorphic = false); + + document (xml_schema::parser_base&, + const std::string& root_element_namespace, + const std::string& root_element_name, + bool polymorphic = false); + + void + parse (const std::string& file); + + void + parse (std::istream&); + + ... + + }; +} + </pre> + + <p><code>xml_schema::document</code> is a root parser for + the vocabulary. The first argument to its constructors is the + parser for the type of the root element (<code>people_impl</code> + in our case). Because a type parser is only concerned with + the element's content and not with the element's name, we need + to specify the root element's name somewhere. That's + what is passed as the second and third arguments to the + <code>document</code>'s constructors.</p> + + <p>There are also two overloaded <code>parse()</code> functions + defined in the <code>document</code> class (there are actually + more but the others are specific to the underlying XML parser). + The first version parses a local file identified by a name. The + second version reads the data from an input stream. For more + information on the <code>xml_schema::document</code> class + refer to <a href="#7">Chapter 7, "Document Parser and Error + Handling"</a>.</p> + + <p>Let's now consider a step-by-step list of actions that happen + as we parse through <code>people.xml</code>. The content of + <code>people.xml</code> is repeated below for convenience.</p> + + <pre class="xml"> +<?xml version="1.0"?> +<people> + <person> + <first-name>John</first-name> + <last-name>Doe</last-name> + <gender>male</gender> + <age>32</age> + </person> + <person> + <first-name>Jane</first-name> + <last-name>Doe</last-name> + <gender>female</gender> + <age>28</age> + </person> +</people> + </pre> + + + <ol class="steps"> + <li><code>people_p.pre()</code> is called from + <code>main()</code>. We did not provide any implementation + for this callback so this call is a no-op.</li> + + <li><code>doc_p.parse("people.xml")</code> is called from + <code>main()</code>. The parser opens the file and starts + parsing its content.</li> + + <li>The parser encounters the root element. <code>doc_p</code> + verifies that the root element is correct and calls + <code>_pre()</code> on <code>people_p</code> which is also + a no-op. Parsing is now delegated to <code>people_p</code>.</li> + + <li>The parser encounters the <code>person</code> element. + <code>people_p</code> determines that <code>person_p</code> + is responsible for parsing this element. <code>pre()</code> + and <code>_pre()</code> callbacks are called on <code>person_p</code>. + Parsing is now delegated to <code>person_p</code>.</li> + + <li>The parser encounters the <code>first-name</code> element. + <code>person_p</code> determines that <code>string_p</code> + is responsible for parsing this element. <code>pre()</code> + and <code>_pre()</code> callbacks are called on <code>string_p</code>. + Parsing is now delegated to <code>string_p</code>.</li> + + <li>The parser encounters character content consisting of + <code>"John"</code>. The <code>_characters()</code> callback is + called on <code>string_p</code>.</li> + + <li>The parser encounters the end of <code>first-name</code> + element. The <code>_post()</code> and <code>post_string()</code> + callbacks are called on <code>string_p</code>. The + <code>first_name()</code> callback is called on <code>person_p</code> + with the return value of <code>post_string()</code>. The + <code>first_name()</code> implementation prints + <code>"first: John"</code> to <code>cout</code>. + Parsing is now returned to <code>person_p</code>.</li> + + <li>Steps analogous to 5-7 are performed for the <code>last-name</code>, + <code>gender</code>, and <code>age</code> elements.</li> + + <li>The parser encounters the end of <code>person</code> + element. The <code>_post()</code> and <code>post_person()</code> + callbacks are called on <code>person_p</code>. The + <code>person()</code> callback is called on <code>people_p</code>. + The <code>person()</code> implementation prints a new line + to <code>cout</code>. Parsing is now returned to + <code>people_p</code>.</li> + + <li>Steps 4-9 are performed for the second <code>person</code> + element.</li> + + <li>The parser encounters the end of <code>people</code> + element. The <code>_post()</code> callback is called on + <code>people_p</code>. The <code>doc_p.parse("people.xml")</code> + call returns to <code>main()</code>.</li> + + <li><code>people_p.post_people()</code> is called from + <code>main()</code> which is a no-op.</li> + + </ol> + + + <!-- Chpater 4 --> + + + <h1><a name="4">4 Type Maps</a></h1> + + <p>There are many useful things you can do inside parser callbacks as they + are right now. There are, however, times when you want to propagate + some information from one parser to another or to the caller of the + parser. One common task that would greatly benefit from such a + possibility is building a tree-like in-memory object model of the + data stored in XML. During execution, each individual sub-parser + would create a sub-tree and return it to its <em>parent</em> parser + which can then incorporate this sub-tree into the whole tree.</p> + + <p>In this chapter we will discuss the mechanisms offered by the + C++/Parser mapping for returning information from individual + parsers and see how to use them to build an object model + of our people vocabulary.</p> + + <h2><a name="4.1">4.1 Object Model</a></h2> + + <p>An object model for our person record example could + look like this (saved in the <code>people.hxx</code> file):</p> + + <pre class="c++"> +#include <string> +#include <vector> + +enum gender +{ + male, + female +}; + +class person +{ +public: + person (const std::string& first, + const std::string& last, + ::gender gender, + short age) + : first_ (first), last_ (last), + gender_ (gender), age_ (age) + { + } + + const std::string& + first () const + { + return first_; + } + + const std::string& + last () const + { + return last_; + } + + ::gender + gender () const + { + return gender_; + } + + short + age () const + { + return age_; + } + +private: + std::string first_; + std::string last_; + ::gender gender_; + short age_; +}; + +typedef std::vector<person> people; + </pre> + + <p>While it is clear which parser is responsible for which part of + the object model, it is not exactly clear how, for + example, <code>gender_pimpl</code> will deliver <code>gender</code> + to <code>person_pimpl</code>. You might have noticed that + <code>string_pimpl</code> manages to deliver its value to the + <code>first_name()</code> callback of <code>person_pimpl</code>. Let's + see how we can utilize the same mechanism to propagate our + own data.</p> + + <p>There is a way to tell the XSD compiler that you want to + exchange data between parsers. More precisely, for each + type defined in XML Schema, you can tell the compiler two things. + First, the return type of the <code>post_*()</code> callback + in the parser skeleton generated for this type. And, second, + the argument type for callbacks corresponding to elements and + attributes of this type. For example, for XML Schema type + <code>gender</code> we can specify the return type for + <code>post_gender()</code> in the <code>gender_pskel</code> + skeleton and the argument type for the <code>gender()</code> callback + in the <code>person_pskel</code> skeleton. As you might have guessed, + the generated code will then pass the return value from the + <code>post_*()</code> callback as an argument to the element or + attribute callback.</p> + + <p>The way to tell the XSD compiler about these XML Schema to + C++ mappings is with type map files. Here is a simple type + map for the <code>gender</code> type from the previous paragraph:</p> + + <pre class="type-map"> +include "people.hxx"; +gender ::gender ::gender; + </pre> + + <p>The first line indicates that the generated code must include + <code>people.hxx</code> in order to get the definition for the + <code>gender</code> type. The second line specifies that both + argument and return types for the <code>gender</code> + XML Schema type should be the <code>::gender</code> C++ enum + (we use fully-qualified C++ names to avoid name clashes). + The next section will describe the type map format in detail. + We save this type map in <code>people.map</code> and + then translate our schemas with the <code>--type-map</code> + option to let the XSD compiler know about our type map:</p> + + <pre class="terminal"> +$ xsd cxx-parser --type-map people.map people.xsd + </pre> + + <p>If we now look at the generated <code>people-pskel.hxx</code>, + we will see the following changes in the <code>gender_pskel</code> and + <code>person_pskel</code> skeletons:</p> + + <pre class="c++"> +#include "people.hxx" + +class gender_pskel: public virtual xml_schema::string_pskel +{ + virtual ::gender + post_gender () = 0; + + ... +}; + +class person_pskel: public xml_schema::complex_content +{ + virtual void + gender (::gender); + + ... +}; + </pre> + + <p>Notice that <code>#include "people.hxx"</code> was added to + the generated header file from the type map to provide the + definition for the <code>gender</code> enum.</p> + + <h2><a name="4.2">4.2 Type Map File Format</a></h2> + + <p>Type map files are used to define a mapping between XML Schema + and C++ types. The compiler uses this information + to determine return types of <code>post_*()</code> + callbacks in parser skeletons corresponding to XML Schema + types as well as argument types for callbacks corresponding + to elements and attributes of these types.</p> + + <p>The compiler has a set of predefined mapping rules that map + the built-in XML Schema types to suitable C++ types (discussed + below) and all other types to <code>void</code>. + By providing your own type maps you can override these predefined + rules. The format of the type map file is presented below: + </p> + + <pre class="type-map"> +namespace <schema-namespace> [<cxx-namespace>] +{ + (include <file-name>;)* + ([type] <schema-type> <cxx-ret-type> [<cxx-arg-type>];)* +} + </pre> + + <p>Both <code><i><schema-namespace></i></code> and + <code><i><schema-type></i></code> are regex patterns while + <code><i><cxx-namespace></i></code>, + <code><i><cxx-ret-type></i></code>, and + <code><i><cxx-arg-type></i></code> are regex pattern + substitutions. All names can be optionally enclosed in + <code>" "</code>, for example, to include white-spaces.</p> + + <p><code><i><schema-namespace></i></code> determines XML + Schema namespace. Optional <code><i><cxx-namespace></i></code> + is prefixed to every C++ type name in this namespace declaration. + <code><i><cxx-ret-type></i></code> is a C++ type name that is + used as a return type for the <code>post_*()</code> callback. + Optional <code><i><cxx-arg-type></i></code> is an argument + type for callbacks corresponding to elements and attributes + of this type. If <code><i><cxx-arg-type></i></code> is not + specified, it defaults to <code><i><cxx-ret-type></i></code> + if <code><i><cxx-ret-type></i></code> ends with <code>*</code> or + <code>&</code> (that is, it is a pointer or a reference) and + <code>const <i><cxx-ret-type></i>&</code> + otherwise. + <code><i><file-name></i></code> is a file name either in the + <code>" "</code> or <code>< ></code> format + and is added with the <code>#include</code> directive to + the generated code.</p> + + <p>The <code><b>#</b></code> character starts a comment that ends + with a new line or end of file. To specify a name that contains + <code><b>#</b></code> enclose it in <code><b>" "</b></code>. + For example:</p> + + <pre> +namespace http://www.example.com/xmlns/my my +{ + include "my.hxx"; + + # Pass apples by value. + # + apple apple; + + # Pass oranges as pointers. + # + orange orange_t*; +} + </pre> + + <p>In the example above, for the + <code>http://www.example.com/xmlns/my#orange</code> + XML Schema type, the <code>my::orange_t*</code> C++ type will + be used as both return and argument types.</p> + + <p>Several namespace declarations can be specified in a single + file. The namespace declaration can also be completely + omitted to map types in a schema without a namespace. For + instance:</p> + + <pre class="type-map"> +include "my.hxx"; +apple apple; + +namespace http://www.example.com/xmlns/my +{ + orange "const orange_t*"; +} + </pre> + + <p>The compiler has a number of predefined mapping rules for + the built-in XML Schema types which can be presented as the + following map files. The string-based XML Schema types are + mapped to either <code>std::string</code> or + <code>std::wstring</code> depending on the character type + selected (see <a href="#5.2"> Section 5.2, "Character Type and + Encoding"</a> for more information). The binary XML Schema + types are mapped to either <code>std::unique_ptr<xml_schema::buffer></code> + or <code>std::auto_ptr<xml_schema::buffer></code> + depending on the C++ standard selected (C++11 or C++98, + respectively; refer to the <code>--std</code> XSD compiler + command line option for details).</p> + + <pre class="type-map"> +namespace http://www.w3.org/2001/XMLSchema +{ + boolean bool bool; + + byte "signed char" "signed char"; + unsignedByte "unsigned char" "unsigned char"; + + short short short; + unsignedShort "unsigned short" "unsigned short"; + + int int int; + unsignedInt "unsigned int" "unsigned int"; + + long "long long" "long long"; + unsignedLong "unsigned long long" "unsigned long long"; + + integer "long long" "long long"; + + negativeInteger "long long" "long long"; + nonPositiveInteger "long long" "long long"; + + positiveInteger "unsigned long long" "unsigned long long"; + nonNegativeInteger "unsigned long long" "unsigned long long"; + + float float float; + double double double; + decimal double double; + + string std::string; + normalizedString std::string; + token std::string; + Name std::string; + NMTOKEN std::string; + NCName std::string; + ID std::string; + IDREF std::string; + language std::string; + anyURI std::string; + + NMTOKENS xml_schema::string_sequence; + IDREFS xml_schema::string_sequence; + + QName xml_schema::qname; + + base64Binary std::[unique|auto]_ptr<xml_schema::buffer> + std::[unique|auto]_ptr<xml_schema::buffer>; + hexBinary std::[unique|auto]_ptr<xml_schema::buffer> + std::[unique|auto]_ptr<xml_schema::buffer>; + + date xml_schema::date; + dateTime xml_schema::date_time; + duration xml_schema::duration; + gDay xml_schema::gday; + gMonth xml_schema::gmonth; + gMonthDay xml_schema::gmonth_day; + gYear xml_schema::gyear; + gYearMonth xml_schema::gyear_month; + time xml_schema::time; +} + </pre> + + <p>For more information about the mapping of the built-in XML Schema types + to C++ types refer to <a href="#6">Chapter 6, "Built-In XML Schema Type + Parsers"</a>. The last predefined rule maps anything that wasn't + mapped by previous rules to <code>void</code>:</p> + + <pre class="type-map"> +namespace .* +{ + .* void void; +} + </pre> + + + <p>When you provide your own type maps with the + <code>--type-map</code> option, they are evaluated first. This + allows you to selectively override any of the predefined rules. + Note also that if you change the mapping + of a built-in XML Schema type then it becomes your responsibility + to provide the corresponding parser skeleton and implementation + in the <code>xml_schema</code> namespace. You can include the + custom definitions into the generated header file using the + <code>--hxx-prologue-*</code> options.</p> + + <h2><a name="4.3">4.3 Parser Implementations</a></h2> + + <p>With the knowledge from the previous section, we can proceed + with creating a type map that maps types in the <code>people.xsd</code> + schema to our object model classes in + <code>people.hxx</code>. In fact, we already have the beginning + of our type map file in <code>people.map</code>. Let's extend + it with the rest of the types:</p> + + <pre class="type-map"> +include "people.hxx"; + +gender ::gender ::gender; +person ::person; +people ::people; + </pre> + + <p>There are a few things to note about this type map. We did not + provide the argument types for <code>person</code> and + <code>people</code> because the default constant reference is + exactly what we need. We also did not provide any mappings + for built-in XML Schema types <code>string</code> and + <code>short</code> because they are handled by the predefined + rules and we are happy with the result. Note also that + all C++ types are fully qualified. This is done to avoid + potential name conflicts in the generated code. Now we can + recompile our schema and move on to implementing the parsers:</p> + + <pre class="terminal"> +$ xsd cxx-parser --xml-parser expat --type-map people.map people.xsd + </pre> + + <p>Here is the implementation of our three parsers in full. One + way to save typing when implementing your own parsers is + to open the generated code and copy the signatures of parser + callbacks into your code. Or you could always auto generate the + sample implementations and fill them with your code.</p> + + + <pre class="c++"> +#include "people-pskel.hxx" + +class gender_pimpl: public gender_pskel, + public xml_schema::string_pimpl +{ +public: + virtual ::gender + post_gender () + { + return post_string () == "male" ? male : female; + } +}; + +class person_pimpl: public person_pskel +{ +public: + virtual void + first_name (const std::string& f) + { + first_ = f; + } + + virtual void + last_name (const std::string& l) + { + last_ = l; + } + + virtual void + gender (::gender g) + { + gender_ = g; + } + + virtual void + age (short a) + { + age_ = a; + } + + virtual ::person + post_person () + { + return ::person (first_, last_, gender_, age_); + } + +private: + std::string first_; + std::string last_; + ::gender gender_; + short age_; +}; + +class people_pimpl: public people_pskel +{ +public: + virtual void + person (const ::person& p) + { + people_.push_back (p); + } + + virtual ::people + post_people () + { + ::people r; + r.swap (people_); + return r; + } + +private: + ::people people_; +}; + </pre> + + <p>This code fragment should look familiar by now. Just note that + all the <code>post_*()</code> callbacks now have return types instead + of <code>void</code>. Here is the implementation of the test + driver for this example:</p> + + <pre class="c++"> +#include <iostream> + +using namespace std; + +int +main (int argc, char* argv[]) +{ + // Construct the parser. + // + xml_schema::short_pimpl short_p; + xml_schema::string_pimpl string_p; + + gender_pimpl gender_p; + person_pimpl person_p; + people_pimpl people_p; + + person_p.parsers (string_p, string_p, gender_p, short_p); + people_p.parsers (person_p); + + // Parse the document to obtain the object model. + // + xml_schema::document doc_p (people_p, "people"); + + people_p.pre (); + doc_p.parse (argv[1]); + people ppl = people_p.post_people (); + + // Print the object model. + // + for (people::iterator i (ppl.begin ()); i != ppl.end (); ++i) + { + cout << "first: " << i->first () << endl + << "last: " << i->last () << endl + << "gender: " << (i->gender () == male ? "male" : "female") << endl + << "age: " << i->age () << endl + << endl; + } +} + </pre> + + <p>The parser creation and assembly part is exactly the same as in + the previous chapter. The parsing part is a bit different: + <code>post_people()</code> now has a return value which is the + complete object model. We store it in the + <code>ppl</code> variable. The last bit of the code simply iterates + over the <code>people</code> vector and prints the information + for each person. We save the last two code fragments to + <code>driver.cxx</code> and proceed to compile and test + our new application:</p> + + + <pre class="terminal"> +$ c++ -std=c++11 -I.../libxsd -c driver.cxx people-pskel.cxx +$ c++ -std=c++11 -o driver driver.o people-pskel.o -lexpat +$ ./driver people.xml +first: John +last: Doe +gender: male +age: 32 + +first: Jane +last: Doe +gender: female +age: 28 + </pre> + + + <!-- Mapping Configuration --> + + + <h1><a name="5">5 Mapping Configuration</a></h1> + + <p>The C++/Parser mapping has a number of configuration parameters that + determine the overall properties and behavior of the generated code. + Configuration parameters are specified with the XSD command line + options and include the C++ standard, the character type that is used + by the generated code, the underlying XML parser, whether the XML Schema + validation is performed in the generated code, and support for XML Schema + polymorphism. This chapter describes these configuration + parameters in more detail. For more ways to configure the generated + code refer to the + <a href="https://www.codesynthesis.com/projects/xsd/documentation/xsd.xhtml">XSD + Compiler Command Line Manual</a>. + </p> + + <h2><a name="5.1">5.1 C++ Standard</a></h2> + + <p>The C++/Parser mapping provides support for ISO/IEC C++ 2011 (C++11) + and ISO/IEC C++ 1998/2003 (C++98). To select the C++ standard for the + generated code we use the <code>--std</code> XSD compiler command + line option. While the majority of the examples in this guide use + C++11, the document explains the C++11/98 usage difference and so + they can easily be converted to C++98.</p> + + <h2><a name="5.2">5.2 Character Type and Encoding</a></h2> + + <p>The C++/Parser mapping has built-in support for two character types: + <code>char</code> and <code>wchar_t</code>. You can select the + character type with the <code>--char-type</code> command line + option. The default character type is <code>char</code>. The + string-based built-in XML Schema types are returned as either + <code>std::string</code> or <code>std::wstring</code> depending + on the character type selected.</p> + + <p>Another aspect of the mapping that depends on the character type + is character encoding. For the <code>char</code> character type + the default encoding is UTF-8. Other supported encodings are + ISO-8859-1, Xerces-C++ Local Code Page (LPC), as well as + custom encodings. You can select which encoding should be used + in the object model with the <code>--char-encoding</code> command + line option.</p> + + <p>For the <code>wchar_t</code> character type the encoding is + automatically selected between UTF-16 and UTF-32/UCS-4 depending + on the size of the <code>wchar_t</code> type. On some platforms + (for example, Windows with Visual C++ and AIX with IBM XL C++) + <code>wchar_t</code> is 2 bytes long. For these platforms the + encoding is UTF-16. On other platforms <code>wchar_t</code> is 4 bytes + long and UTF-32/UCS-4 is used.</p> + + <p>Note also that the character encoding that is used in the object model + is independent of the encodings used in input and output XML. In fact, + all three (object mode, input XML, and output XML) can have different + encodings.</p> + + <h2><a name="5.3">5.3 Underlying XML Parser</a></h2> + + <p>The C++/Parser mapping can be used with either Xerces-C++ or Expat + as the underlying XML parser. You can select the XML parser with + the <code>--xml-parser</code> command line option. Valid values + for this option are <code>xerces</code> and <code>expat</code>. + The default XML parser is Xerces-C++.</p> + + <p>The generated code is identical for both parsers except for the + <code>xml_schema::document</code> class in which some of the + <code>parse()</code> functions are parser-specific as described + in <a href="#7">Chapter 7, "Document Parser and Error Handling"</a>.</p> + + + <h2><a name="5.4">5.4 XML Schema Validation</a></h2> + + <p>The C++/Parser mapping provides support for validating a + commonly-used subset of W3C XML Schema in the generated code. + For the list of supported XML Schema constructs refer to + <a href="#A">Appendix A, "Supported XML Schema Constructs"</a>.</p> + + <p>By default validation in the generated code is disabled if + the underlying XML parser is validating (Xerces-C++) and + enabled otherwise (Expat). See <a href="#5.3">Section 5.3, + "Underlying XML Parser"</a> for more information about + the underlying XML parser. You can override the default + behavior with the <code>--generate-validation</code> + and <code>--suppress-validation</code> command line options.</p> + + + <h2><a name="5.5">5.5 Support for Polymorphism</a></h2> + + <p>By default the XSD compiler generates non-polymorphic code. If your + vocabulary uses XML Schema polymorphism in the form of <code>xsi:type</code> + and/or substitution groups, then you will need to compile your schemas + with the <code>--generate-polymorphic</code> option to produce + polymorphism-aware code as well as pass <code>true</code> as the last + argument to the <code>xml_schema::document</code>'s constructors.</p> + + <p>When using the polymorphism-aware generated code, you can specify + several parsers for a single element by passing a parser map + instead of an individual parser to the parser connection function + for the element. One of the parsers will then be looked up and used + depending on the <code>xsi:type</code> attribute value or an element + name from a substitution group. Consider the following schema as an + example:</p> + + <pre class="xml"> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> + + <xs:complexType name="person"> + <xs:sequence> + <xs:element name="name" type="xs:string"/> + </xs:sequence> + </xs:complexType> + + <!-- substitution group root --> + <xs:element name="person" type="person"/> + + <xs:complexType name="superman"> + <xs:complexContent> + <xs:extension base="person"> + <xs:attribute name="can-fly" type="xs:boolean"/> + </xs:extension> + </xs:complexContent> + </xs:complexType> + + <xs:element name="superman" + type="superman" + substitutionGroup="person"/> + + <xs:complexType name="batman"> + <xs:complexContent> + <xs:extension base="superman"> + <xs:attribute name="wing-span" type="xs:unsignedInt"/> + </xs:extension> + </xs:complexContent> + </xs:complexType> + + <xs:element name="batman" + type="batman" + substitutionGroup="superman"/> + + <xs:complexType name="supermen"> + <xs:sequence> + <xs:element ref="person" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + + <xs:element name="supermen" type="supermen"/> + +</xs:schema> + </pre> + + <p>Conforming XML documents can use the <code>superman</code> + and <code>batman</code> types in place of the <code>person</code> + type either by specifying the type with the <code>xsi:type</code> + attributes or by using the elements from the substitution + group, for instance:</p> + + + <pre class="xml"> +<supermen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + + <person> + <name>John Doe</name> + </person> + + <superman can-fly="false"> + <name>James "007" Bond</name> + </superman> + + <superman can-fly="true" wing-span="10" xsi:type="batman"> + <name>Bruce Wayne</name> + </superman> + +</supermen> + </pre> + + <p>To print the data stored in such XML documents we can implement + the parsers as follows:</p> + + <pre class="c++"> +class person_pimpl: public virtual person_pskel +{ +public: + virtual void + pre () + { + cout << "starting to parse person" << endl; + } + + virtual void + name (const std::string& v) + { + cout << "name: " << v << endl; + } + + virtual void + post_person () + { + cout << "finished parsing person" << endl; + } +}; + +class superman_pimpl: public virtual superman_pskel, + public person_pimpl +{ +public: + virtual void + pre () + { + cout << "starting to parse superman" << endl; + } + + virtual void + can_fly (bool v) + { + cout << "can-fly: " << v << endl; + } + + virtual void + post_person () + { + post_superman (); + } + + virtual void + post_superman () + { + cout << "finished parsing superman" << endl + } +}; + +class batman_pimpl: public virtual batman_pskel, + public superman_pimpl +{ +public: + virtual void + pre () + { + cout << "starting to parse batman" << endl; + } + + virtual void + wing_span (unsigned int v) + { + cout << "wing-span: " << v << endl; + } + + virtual void + post_superman () + { + post_batman (); + } + + virtual void + post_batman () + { + cout << "finished parsing batman" << endl; + } +}; + </pre> + + <p>Note that because the derived type parsers (<code>superman_pskel</code> + and <code>batman_pskel</code>) are called via the <code>person_pskel</code> + interface, we have to override the <code>post_person()</code> + virtual function in <code>superman_pimpl</code> to call + <code>post_superman()</code> and the <code>post_superman()</code> + virtual function in <code>batman_pimpl</code> to call + <code>post_batman()</code>.</p> + + <p>The following code fragment shows how to connect the parsers together. + Notice that for the <code>person</code> element in the <code>supermen_p</code> + parser we specify a parser map instead of a specific parser and we pass + <code>true</code> as the last argument to the document parser constructor + to indicate that we are parsing potentially-polymorphic XML documents:</p> + + <pre class="c++"> +int +main (int argc, char* argv[]) +{ + // Construct the parser. + // + xml_schema::string_pimpl string_p; + xml_schema::boolean_pimpl boolean_p; + xml_schema::unsigned_int_pimpl unsigned_int_p; + + person_pimpl person_p; + superman_pimpl superman_p; + batman_pimpl batman_p; + + xml_schema::parser_map_impl person_map; + supermen_pimpl supermen_p; + + person_p.parsers (string_p); + superman_p.parsers (string_p, boolean_p); + batman_p.parsers (string_p, boolean_p, unsigned_int_p); + + // Here we are specifying a parser map which containes several + // parsers that can be used to parse the person element. + // + person_map.insert (person_p); + person_map.insert (superman_p); + person_map.insert (batman_p); + + supermen_p.person_parser (person_map); + + // Parse the XML document. The last argument to the document's + // constructor indicates that we are parsing polymorphic XML + // documents. + // + xml_schema::document doc_p (supermen_p, "supermen", true); + + supermen_p.pre (); + doc_p.parse (argv[1]); + supermen_p.post_supermen (); +} + </pre> + + <p>When polymorphism-aware code is generated, each element's + <code>*_parser()</code> function is overloaded to also accept + an object of the <code>xml_schema::parser_map</code> type. + For example, the <code>supermen_pskel</code> class from the + above example looks like this:</p> + + <pre class="c++"> +class supermen_pskel: public xml_schema::parser_complex_content +{ +public: + + ... + + // Parser construction API. + // + void + parsers (person_pskel&); + + // Individual element parsers. + // + void + person_parser (person_pskel&); + + void + person_parser (const xml_schema::parser_map&); + + ... +}; + </pre> + + <p>Note that you can specify both the individual (static) parser and + the parser map. The individual parser will be used when the static + element type and the dynamic type of the object being parsed are + the same. This is the case, for example, when there is no + <code>xsi:type</code> attribute and the element hasn't been + substituted. Because the individual parser for an element is + cached and no map lookup is necessary, it makes sense to specify + both the individual parser and the parser map when most of the + objects being parsed are of the static type and optimal + performance is important. The following code fragment shows + how to change the above example to set both the individual + parser and the parser map:</p> + + <pre class="c++"> +int +main (int argc, char* argv[]) +{ + ... + + person_map.insert (superman_p); + person_map.insert (batman_p); + + supermen_p.person_parser (person_p); + supermen_p.person_parser (person_map); + + ... +} + </pre> + + + <p>The <code>xml_schema::parser_map</code> interface and the + <code>xml_schema::parser_map_impl</code> default implementation + are presented below:</p> + + <pre class="c++"> +namespace xml_schema +{ + class parser_map + { + public: + virtual parser_base* + find (const ro_string* type) const = 0; + }; + + class parser_map_impl: public parser_map + { + public: + void + insert (parser_base&); + + virtual parser_base* + find (const ro_string* type) const; + + private: + parser_map_impl (const parser_map_impl&); + + parser_map_impl& + operator= (const parser_map_impl&); + + ... + }; +} + </pre> + + <p>The <code>type</code> argument in the <code>find()</code> virtual + function is the type name and namespace from the xsi:type attribute + (the namespace prefix is resolved to the actual XML namespace) + or the type of an element from the substitution group in the form + <code>"<name> <namespace>"</code> with the space and the + namespace part absent if the type does not have a namespace. + You can obtain a parser's dynamic type in the same format + using the <code>_dynamic_type()</code> function. The static + type can be obtained by calling the static <code>_static_type()</code> + function, for example <code>person_pskel::_static_type()</code>. + Both functions return a C string (<code>const char*</code> or + <code>const wchar_t*</code>, depending on the character type + used) which is valid for as long as the application is running. + The following example shows how we can implement our own parser + map using <code>std::map</code>:</p> + + + <pre class="c++"> +#include <map> +#include <string> + +class parser_map: public xml_schema::parser_map +{ +public: + void + insert (xml_schema::parser_base& p) + { + map_[p._dynamic_type ()] = &p; + } + + virtual xml_schema::parser_base* + find (const xml_schema::ro_string* type) const + { + map::const_iterator i = map_.find (type); + return i != map_.end () ? i->second : 0; + } + +private: + typedef std::map<std::string, xml_schema::parser_base*> map; + map map_; +}; + </pre> + + <p>Most of code presented in this section is taken from the + <code>polymorphism</code> example which can be found in the + <code>cxx/parser/</code> directory in the + <a href="https://cppget.org/xsd-examples">xsd-examples</a> package. + Handling of <code>xsi:type</code> and substitution groups when used on + root elements requires a number of special actions as shown in + the <code>polyroot</code> example.</p> + + + <!-- Built-in XML Schema Type Parsers --> + + + <h1><a name="6">6 Built-In XML Schema Type Parsers</a></h1> + + <p>The XSD runtime provides parser implementations for all built-in + XML Schema types as summarized in the following table. Declarations + for these types are automatically included into each generated + header file. As a result you don't need to include any headers + to gain access to these parser implementations. Note that some + parsers return either <code>std::string</code> or + <code>std::wstring</code> depending on the character type selected.</p> + + <!-- border="1" is necessary for html2ps --> + <table id="builtin" border="1"> + <tr> + <th>XML Schema type</th> + <th>Parser implementation in the <code>xml_schema</code> namespace</th> + <th>Parser return type</th> + </tr> + + <tr> + <th colspan="3">anyType and anySimpleType types</th> + </tr> + <tr> + <td><code>anyType</code></td> + <td><code>any_type_pimpl</code></td> + <td><code>void</code></td> + </tr> + <tr> + <td><code>anySimpleType</code></td> + <td><code>any_simple_type_pimpl</code></td> + <td><code>void</code></td> + </tr> + + <tr> + <th colspan="3">fixed-length integral types</th> + </tr> + <!-- 8-bit --> + <tr> + <td><code>byte</code></td> + <td><code>byte_pimpl</code></td> + <td><code>signed char</code></td> + </tr> + <tr> + <td><code>unsignedByte</code></td> + <td><code>unsigned_byte_pimpl</code></td> + <td><code>unsigned char</code></td> + </tr> + + <!-- 16-bit --> + <tr> + <td><code>short</code></td> + <td><code>short_pimpl</code></td> + <td><code>short</code></td> + </tr> + <tr> + <td><code>unsignedShort</code></td> + <td><code>unsigned_short_pimpl</code></td> + <td><code>unsigned short</code></td> + </tr> + + <!-- 32-bit --> + <tr> + <td><code>int</code></td> + <td><code>int_pimpl</code></td> + <td><code>int</code></td> + </tr> + <tr> + <td><code>unsignedInt</code></td> + <td><code>unsigned_int_pimpl</code></td> + <td><code>unsigned int</code></td> + </tr> + + <!-- 64-bit --> + <tr> + <td><code>long</code></td> + <td><code>long_pimpl</code></td> + <td><code>long long</code></td> + </tr> + <tr> + <td><code>unsignedLong</code></td> + <td><code>unsigned_long_pimpl</code></td> + <td><code>unsigned long long</code></td> + </tr> + + <tr> + <th colspan="3">arbitrary-length integral types</th> + </tr> + <tr> + <td><code>integer</code></td> + <td><code>integer_pimpl</code></td> + <td><code>long long</code></td> + </tr> + <tr> + <td><code>nonPositiveInteger</code></td> + <td><code>non_positive_integer_pimpl</code></td> + <td><code>long long</code></td> + </tr> + <tr> + <td><code>nonNegativeInteger</code></td> + <td><code>non_negative_integer_pimpl</code></td> + <td><code>unsigned long long</code></td> + </tr> + <tr> + <td><code>positiveInteger</code></td> + <td><code>positive_integer_pimpl</code></td> + <td><code>unsigned long long</code></td> + </tr> + <tr> + <td><code>negativeInteger</code></td> + <td><code>negative_integer_pimpl</code></td> + <td><code>long long</code></td> + </tr> + + <tr> + <th colspan="3">boolean types</th> + </tr> + <tr> + <td><code>boolean</code></td> + <td><code>boolean_pimpl</code></td> + <td><code>bool</code></td> + </tr> + + <tr> + <th colspan="3">fixed-precision floating-point types</th> + </tr> + <tr> + <td><code>float</code></td> + <td><code>float_pimpl</code></td> + <td><code>float</code></td> + </tr> + <tr> + <td><code>double</code></td> + <td><code>double_pimpl</code></td> + <td><code>double</code></td> + </tr> + + <tr> + <th colspan="3">arbitrary-precision floating-point types</th> + </tr> + <tr> + <td><code>decimal</code></td> + <td><code>decimal_pimpl</code></td> + <td><code>double</code></td> + </tr> + + <tr> + <th colspan="3">string-based types</th> + </tr> + <tr> + <td><code>string</code></td> + <td><code>string_pimpl</code></td> + <td><code>std::string</code> or <code>std::wstring</code></td> + </tr> + <tr> + <td><code>normalizedString</code></td> + <td><code>normalized_string_pimpl</code></td> + <td><code>std::string</code> or <code>std::wstring</code></td> + </tr> + <tr> + <td><code>token</code></td> + <td><code>token_pimpl</code></td> + <td><code>std::string</code> or <code>std::wstring</code></td> + </tr> + <tr> + <td><code>Name</code></td> + <td><code>name_pimpl</code></td> + <td><code>std::string</code> or <code>std::wstring</code></td> + </tr> + <tr> + <td><code>NMTOKEN</code></td> + <td><code>nmtoken_pimpl</code></td> + <td><code>std::string</code> or <code>std::wstring</code></td> + </tr> + <tr> + <td><code>NCName</code></td> + <td><code>ncname_pimpl</code></td> + <td><code>std::string</code> or <code>std::wstring</code></td> + </tr> + + <tr> + <td><code>language</code></td> + <td><code>language_pimpl</code></td> + <td><code>std::string</code> or <code>std::wstring</code></td> + </tr> + + <tr> + <th colspan="3">qualified name</th> + </tr> + <tr> + <td><code>QName</code></td> + <td><code>qname_pimpl</code></td> + <td><code>xml_schema::qname</code><br/><a href="#6.1">Section 6.1, + "<code>QName</code> Parser"</a></td> + </tr> + + <tr> + <th colspan="3">ID/IDREF types</th> + </tr> + <tr> + <td><code>ID</code></td> + <td><code>id_pimpl</code></td> + <td><code>std::string</code> or <code>std::wstring</code></td> + </tr> + <tr> + <td><code>IDREF</code></td> + <td><code>idref_pimpl</code></td> + <td><code>std::string</code> or <code>std::wstring</code></td> + </tr> + + <tr> + <th colspan="3">list types</th> + </tr> + <tr> + <td><code>NMTOKENS</code></td> + <td><code>nmtokens_pimpl</code></td> + <td><code>xml_schema::string_sequence</code><br/><a href="#6.2">Section + 6.2, "<code>NMTOKENS</code> and <code>IDREFS</code> Parsers"</a></td> + </tr> + <tr> + <td><code>IDREFS</code></td> + <td><code>idrefs_pimpl</code></td> + <td><code>xml_schema::string_sequence</code><br/><a href="#6.2">Section + 6.2, "<code>NMTOKENS</code> and <code>IDREFS</code> Parsers"</a></td> + </tr> + + <tr> + <th colspan="3">URI types</th> + </tr> + <tr> + <td><code>anyURI</code></td> + <td><code>uri_pimpl</code></td> + <td><code>std::string</code> or <code>std::wstring</code></td> + </tr> + + <tr> + <th colspan="3">binary types</th> + </tr> + <tr> + <td><code>base64Binary</code></td> + <td><code>base64_binary_pimpl</code></td> + <td><code>std::[unique|auto]_ptr< xml_schema::buffer></code><br/> + <a href="#6.3">Section 6.3, "<code>base64Binary</code> and + <code>hexBinary</code> Parsers"</a></td> + </tr> + <tr> + <td><code>hexBinary</code></td> + <td><code>hex_binary_pimpl</code></td> + <td><code>std::[unique|auto]_ptr< xml_schema::buffer></code><br/> + <a href="#6.3">Section 6.3, "<code>base64Binary</code> and + <code>hexBinary</code> Parsers"</a></td> + </tr> + + <tr> + <th colspan="3">date/time types</th> + </tr> + <tr> + <td><code>date</code></td> + <td><code>date_pimpl</code></td> + <td><code>xml_schema::date</code><br/><a href="#6.5">Section 6.5, + "<code>date</code> Parser"</a></td> + </tr> + <tr> + <td><code>dateTime</code></td> + <td><code>date_time_pimpl</code></td> + <td><code>xml_schema::date_time</code><br/><a href="#6.6">Section 6.6, + "<code>dateTime</code> Parser"</a></td> + </tr> + <tr> + <td><code>duration</code></td> + <td><code>duration_pimpl</code></td> + <td><code>xml_schema::duration</code><br/><a href="#6.7">Section 6.7, + "<code>duration</code> Parser"</a></td> + </tr> + <tr> + <td><code>gDay</code></td> + <td><code>gday_pimpl</code></td> + <td><code>xml_schema::gday</code><br/><a href="#6.8">Section 6.8, + "<code>gDay</code> Parser"</a></td> + </tr> + <tr> + <td><code>gMonth</code></td> + <td><code>gmonth_pimpl</code></td> + <td><code>xml_schema::gmonth</code><br/><a href="#6.9">Section 6.9, + "<code>gMonth</code> Parser"</a></td> + </tr> + <tr> + <td><code>gMonthDay</code></td> + <td><code>gmonth_day_pimpl</code></td> + <td><code>xml_schema::gmonth_day</code><br/><a href="#6.10">Section 6.10, + "<code>gMonthDay</code> Parser"</a></td> + </tr> + <tr> + <td><code>gYear</code></td> + <td><code>gyear_pimpl</code></td> + <td><code>xml_schema::gyear</code><br/><a href="#6.11">Section 6.11, + "<code>gYear</code> Parser"</a></td> + </tr> + <tr> + <td><code>gYearMonth</code></td> + <td><code>gyear_month_pimpl</code></td> + <td><code>xml_schema::gyear_month</code><br/><a href="#6.12">Section + 6.12, "<code>gYearMonth</code> Parser"</a></td> + </tr> + <tr> + <td><code>time</code></td> + <td><code>time_pimpl</code></td> + <td><code>xml_schema::time</code><br/><a href="#6.13">Section 6.13, + "<code>time</code> Parser"</a></td> + </tr> + + </table> + + <h2><a name="6.1">6.1 <code>QName</code> Parser</a></h2> + + <p>The return type of the <code>qname_pimpl</code> parser implementation + is <code>xml_schema::qname</code> which represents an XML qualified + name. Its interface is presented below. + Note that the <code>std::string</code> type in the interface becomes + <code>std::wstring</code> if the selected character type is + <code>wchar_t</code>.</p> + + <pre class="c++"> +namespace xml_schema +{ + class qname + { + public: + explicit + qname (const std::string& name); + qname (const std::string& prefix, const std::string& name); + + const std::string& + prefix () const; + + void + prefix (const std::string&); + + const std::string& + name () const; + + void + name (const std::string&); + }; + + bool + operator== (const qname&, const qname&); + + bool + operator!= (const qname&, const qname&); +} + </pre> + + + <h2><a name="6.2">6.2 <code>NMTOKENS</code> and <code>IDREFS</code> Parsers</a></h2> + + <p>The return type of the <code>nmtokens_pimpl</code> and + <code>idrefs_pimpl</code> parser implementations is + <code>xml_schema::string_sequence</code> which represents a + sequence of strings. Its interface is presented below. + Note that the <code>std::string</code> type in the interface becomes + <code>std::wstring</code> if the selected character type is + <code>wchar_t</code>.</p> + + <pre class="c++"> +namespace xml_schema +{ + class string_sequence: public std::vector<std::string> + { + public: + string_sequence (); + + explicit + string_sequence (std::vector<std::string>::size_type n, + const std::string& x = std::string ()); + + template <typename I> + string_sequence (const I& begin, const I& end); + }; + + bool + operator== (const string_sequence&, const string_sequence&); + + bool + operator!= (const string_sequence&, const string_sequence&); +} + </pre> + + + <h2><a name="6.3">6.3 <code>base64Binary</code> and <code>hexBinary</code> Parsers</a></h2> + + <p>The return type of the <code>base64_binary_pimpl</code> and + <code>hex_binary_pimpl</code> parser implementations is either + <code>std::unique_ptr<xml_schema::buffer></code> (C++11) or + <code>std::auto_ptr<xml_schema::buffer></code> (C++98), + depending on the C++ standard selected (<code>--std</code> XSD + compiler option). The <code>xml_schema::buffer</code> type + represents a binary buffer and its interface is presented below.</p> + + <pre class="c++"> +namespace xml_schema +{ + class buffer + { + public: + typedef std::size_t size_t; + + class bounds {}; // Out of bounds exception. + + public: + explicit + buffer (size_t size = 0); + buffer (size_t size, size_t capacity); + buffer (const void* data, size_t size); + buffer (const void* data, size_t size, size_t capacity); + buffer (void* data, + size_t size, + size_t capacity, + bool assume_ownership); + + public: + buffer (const buffer&); + + buffer& + operator= (const buffer&); + + void + swap (buffer&); + + public: + size_t + capacity () const; + + bool + capacity (size_t); + + public: + size_t + size () const; + + bool + size (size_t); + + public: + const char* + data () const; + + char* + data (); + + const char* + begin () const; + + char* + begin (); + + const char* + end () const; + + char* + end (); + }; + + bool + operator== (const buffer&, const buffer&); + + bool + operator!= (const buffer&, const buffer&); +} + </pre> + + <p>If the <code>assume_ownership</code> argument to the constructor + is <code>true</code>, the instance assumes the ownership of the + memory block pointed to by the <code>data</code> argument and will + eventually release it by calling <code>operator delete()</code>. The + <code>capacity()</code> and <code>size()</code> modifier functions + return <code>true</code> if the underlying buffer has moved. + </p> + + <p>The <code>bounds</code> exception is thrown if the constructor + arguments violate the <code>(size <= capacity)</code> + constraint.</p> + + + <h2><a name="6.4">6.4 Time Zone Representation</a></h2> + + <p>The <code>date</code>, <code>dateTime</code>, <code>gDay</code>, + <code>gMonth</code>, <code>gMonthDay</code>, <code>gYear</code>, + <code>gYearMonth</code>, and <code>time</code> XML Schema built-in + types all include an optional time zone component. The following + <code>xml_schema::time_zone</code> base class is used to represent + this information:</p> + + <pre class="c++"> +namespace xml_schema +{ + class time_zone + { + public: + time_zone (); + time_zone (short hours, short minutes); + + bool + zone_present () const; + + void + zone_reset (); + + short + zone_hours () const; + + void + zone_hours (short); + + short + zone_minutes () const; + + void + zone_minutes (short); + }; + + bool + operator== (const time_zone&, const time_zone&); + + bool + operator!= (const time_zone&, const time_zone&); +} + </pre> + + <p>The <code>zone_present()</code> accessor function returns <code>true</code> + if the time zone is specified. The <code>zone_reset()</code> modifier + function resets the time zone object to the <em>not specified</em> + state. If the time zone offset is negative then both hours and + minutes components are represented as negative integers.</p> + + + <h2><a name="6.5">6.5 <code>date</code> Parser</a></h2> + + <p>The return type of the <code>date_pimpl</code> parser implementation + is <code>xml_schema::date</code> which represents a year, a day, and a month + with an optional time zone. Its interface is presented below. + For more information on the base <code>xml_schema::time_zone</code> + class refer to <a href="#6.4">Section 6.4, "Time Zone + Representation"</a>.</p> + + <pre class="c++"> +namespace xml_schema +{ + class date + { + public: + date (int year, unsigned short month, unsigned short day); + date (int year, unsigned short month, unsigned short day, + short zone_hours, short zone_minutes); + + int + year () const; + + void + year (int); + + unsigned short + month () const; + + void + month (unsigned short); + + unsigned short + day () const; + + void + day (unsigned short); + }; + + bool + operator== (const date&, const date&); + + bool + operator!= (const date&, const date&); +} + </pre> + + <h2><a name="6.6">6.6 <code>dateTime</code> Parser</a></h2> + + <p>The return type of the <code>date_time_pimpl</code> parser implementation + is <code>xml_schema::date_time</code> which represents a year, a month, a day, + hours, minutes, and seconds with an optional time zone. Its interface + is presented below. + For more information on the base <code>xml_schema::time_zone</code> + class refer to <a href="#6.4">Section 6.4, "Time Zone + Representation"</a>.</p> + + <pre class="c++"> +namespace xml_schema +{ + class date_time + { + public: + date_time (int year, unsigned short month, unsigned short day, + unsigned short hours, unsigned short minutes, + double seconds); + + date_time (int year, unsigned short month, unsigned short day, + unsigned short hours, unsigned short minutes, + double seconds, short zone_hours, short zone_minutes); + + int + year () const; + + void + year (int); + + unsigned short + month () const; + + void + month (unsigned short); + + unsigned short + day () const; + + void + day (unsigned short); + + unsigned short + hours () const; + + void + hours (unsigned short); + + unsigned short + minutes () const; + + void + minutes (unsigned short); + + double + seconds () const; + + void + seconds (double); + }; + + bool + operator== (const date_time&, const date_time&); + + bool + operator!= (const date_time&, const date_time&); +} + </pre> + + <h2><a name="6.7">6.7 <code>duration</code> Parser</a></h2> + + <p>The return type of the <code>duration_pimpl</code> parser implementation + is <code>xml_schema::duration</code> which represents a potentially + negative duration in the form of years, months, days, hours, minutes, + and seconds. Its interface is presented below.</p> + + <pre class="c++"> +namespace xml_schema +{ + class duration + { + public: + duration (bool negative, + unsigned int years, unsigned int months, unsigned int days, + unsigned int hours, unsigned int minutes, double seconds); + + bool + negative () const; + + void + negative (bool); + + unsigned int + years () const; + + void + years (unsigned int); + + unsigned int + months () const; + + void + months (unsigned int); + + unsigned int + days () const; + + void + days (unsigned int); + + unsigned int + hours () const; + + void + hours (unsigned int); + + unsigned int + minutes () const; + + void + minutes (unsigned int); + + double + seconds () const; + + void + seconds (double); + }; + + bool + operator== (const duration&, const duration&); + + bool + operator!= (const duration&, const duration&); +} + </pre> + + + <h2><a name="6.8">6.8 <code>gDay</code> Parser</a></h2> + + <p>The return type of the <code>gday_pimpl</code> parser implementation + is <code>xml_schema::gday</code> which represents a day of the month with + an optional time zone. Its interface is presented below. + For more information on the base <code>xml_schema::time_zone</code> + class refer to <a href="#6.4">Section 6.4, "Time Zone + Representation"</a>.</p> + + <pre class="c++"> +namespace xml_schema +{ + class gday + { + public: + explicit + gday (unsigned short day); + gday (unsigned short day, short zone_hours, short zone_minutes); + + unsigned short + day () const; + + void + day (unsigned short); + }; + + bool + operator== (const gday&, const gday&); + + bool + operator!= (const gday&, const gday&); +} + </pre> + + <h2><a name="6.9">6.9 <code>gMonth</code> Parser</a></h2> + + <p>The return type of the <code>gmonth_pimpl</code> parser implementation + is <code>xml_schema::gmonth</code> which represents a month of the year + with an optional time zone. Its interface is presented below. + For more information on the base <code>xml_schema::time_zone</code> + class refer to <a href="#6.4">Section 6.4, "Time Zone + Representation"</a>.</p> + + <pre class="c++"> +namespace xml_schema +{ + class gmonth + { + public: + explicit + gmonth (unsigned short month); + gmonth (unsigned short month, short zone_hours, short zone_minutes); + + unsigned short + month () const; + + void + month (unsigned short); + }; + + bool + operator== (const gmonth&, const gmonth&); + + bool + operator!= (const gmonth&, const gmonth&); +} + </pre> + + <h2><a name="6.10">6.10 <code>gMonthDay</code> Parser</a></h2> + + <p>The return type of the <code>gmonth_day_pimpl</code> parser implementation + is <code>xml_schema::gmonth_day</code> which represents a day and a month + of the year with an optional time zone. Its interface is presented below. + For more information on the base <code>xml_schema::time_zone</code> + class refer to <a href="#6.4">Section 6.4, "Time Zone + Representation"</a>.</p> + + <pre class="c++"> +namespace xml_schema +{ + class gmonth_day + { + public: + gmonth_day (unsigned short month, unsigned short day); + gmonth_day (unsigned short month, unsigned short day, + short zone_hours, short zone_minutes); + + unsigned short + month () const; + + void + month (unsigned short); + + unsigned short + day () const; + + void + day (unsigned short); + }; + + bool + operator== (const gmonth_day&, const gmonth_day&); + + bool + operator!= (const gmonth_day&, const gmonth_day&); +} + </pre> + + <h2><a name="6.11">6.11 <code>gYear</code> Parser</a></h2> + + <p>The return type of the <code>gyear_pimpl</code> parser implementation + is <code>xml_schema::gyear</code> which represents a year with + an optional time zone. Its interface is presented below. + For more information on the base <code>xml_schema::time_zone</code> + class refer to <a href="#6.4">Section 6.4, "Time Zone + Representation"</a>.</p> + + <pre class="c++"> +namespace xml_schema +{ + class gyear + { + public: + explicit + gyear (int year); + gyear (int year, short zone_hours, short zone_minutes); + + int + year () const; + + void + year (int); + }; + + bool + operator== (const gyear&, const gyear&); + + bool + operator!= (const gyear&, const gyear&); +} + </pre> + + <h2><a name="6.12">6.12 <code>gYearMonth</code> Parser</a></h2> + + <p>The return type of the <code>gyear_month_pimpl</code> parser implementation + is <code>xml_schema::gyear_month</code> which represents a year and a month + with an optional time zone. Its interface is presented below. + For more information on the base <code>xml_schema::time_zone</code> + class refer to <a href="#6.4">Section 6.4, "Time Zone + Representation"</a>.</p> + + <pre class="c++"> +namespace xml_schema +{ + class gyear_month + { + public: + gyear_month (int year, unsigned short month); + gyear_month (int year, unsigned short month, + short zone_hours, short zone_minutes); + + int + year () const; + + void + year (int); + + unsigned short + month () const; + + void + month (unsigned short); + }; + + bool + operator== (const gyear_month&, const gyear_month&); + + bool + operator!= (const gyear_month&, const gyear_month&); +} + </pre> + + + <h2><a name="6.13">6.13 <code>time</code> Parser</a></h2> + + <p>The return type of the <code>time_pimpl</code> parser implementation + is <code>xml_schema::time</code> which represents hours, minutes, + and seconds with an optional time zone. Its interface is presented below. + For more information on the base <code>xml_schema::time_zone</code> + class refer to <a href="#6.4">Section 6.4, "Time Zone + Representation"</a>.</p> + + <pre class="c++"> +namespace xml_schema +{ + class time + { + public: + time (unsigned short hours, unsigned short minutes, double seconds); + time (unsigned short hours, unsigned short minutes, double seconds, + short zone_hours, short zone_minutes); + + unsigned short + hours () const; + + void + hours (unsigned short); + + unsigned short + minutes () const; + + void + minutes (unsigned short); + + double + seconds () const; + + void + seconds (double); + }; + + bool + operator== (const time&, const time&); + + bool + operator!= (const time&, const time&); +} + </pre> + + + <!-- Error Handling --> + + + <h1><a name="7">7 Document Parser and Error Handling</a></h1> + + <p>In this chapter we will discuss the <code>xml_schema::document</code> + type as well as the error handling mechanisms provided by the mapping + in more detail. As mentioned in <a href="#3.4">Section 3.4, + "Connecting the Parsers Together"</a>, the interface of + <code>xml_schema::document</code> depends on the underlying XML + parser selected (<a href="#5.3">Section 5.3, "Underlying XML + Parser"</a>). The following sections describe the + <code>document</code> type interface for Xerces-C++ and + Expat as underlying parsers.</p> + + <h2><a name="7.1">7.1 Xerces-C++ Document Parser</a></h2> + + <p>When Xerces-C++ is used as the underlying XML parser, the + <code>document</code> type has the following interface. Note that + if the character type is <code>wchar_t</code>, then the string type + in the interface becomes <code>std::wstring</code> + (see <a href="#5.2">Section 5.2, "Character Type and Encoding"</a>).</p> + + <pre class="c++"> +namespace xml_schema +{ + class parser_base; + class error_handler; + + class flags + { + public: + // Do not validate XML documents with the Xerces-C++ validator. + // + static const unsigned long dont_validate; + + // Do not initialize the Xerces-C++ runtime. + // + static const unsigned long dont_initialize; + + // Disable handling of subsequent imports for the same namespace + // in Xerces-C++ 3.1.0 and later. + // + static const unsigned long no_multiple_imports; + }; + + class properties + { + public: + // Add a location for a schema with a target namespace. + // + void + schema_location (const std::string& namespace_, + const std::string& location); + + // Add a location for a schema without a target namespace. + // + void + no_namespace_schema_location (const std::string& location); + }; + + class document + { + public: + document (parser_base& root, + const std::string& root_element_name, + bool polymorphic = false); + + document (parser_base& root, + const std::string& root_element_namespace, + const std::string& root_element_name, + bool polymorphic = false); + + public: + // Parse URI or a local file. + // + void + parse (const std::string& uri, + flags = 0, + const properties& = properties ()); + + // Parse URI or a local file with a user-provided error_handler + // object. + // + void + parse (const std::string& uri, + error_handler&, + flags = 0, + const properties& = properties ()); + + // Parse URI or a local file with a user-provided ErrorHandler + // object. Note that you must initialize the Xerces-C++ runtime + // before calling this function. + // + void + parse (const std::string& uri, + xercesc::ErrorHandler&, + flags = 0, + const properties& = properties ()); + + // Parse URI or a local file using a user-provided SAX2XMLReader + // object. Note that you must initialize the Xerces-C++ runtime + // before calling this function. + // + void + parse (const std::string& uri, + xercesc::SAX2XMLReader&, + flags = 0, + const properties& = properties ()); + + public: + // Parse std::istream. + // + void + parse (std::istream&, + flags = 0, + const properties& = properties ()); + + // Parse std::istream with a user-provided error_handler object. + // + void + parse (std::istream&, + error_handler&, + flags = 0, + const properties& = properties ()); + + // Parse std::istream with a user-provided ErrorHandler object. + // Note that you must initialize the Xerces-C++ runtime before + // calling this function. + // + void + parse (std::istream&, + xercesc::ErrorHandler&, + flags = 0, + const properties& = properties ()); + + // Parse std::istream using a user-provided SAX2XMLReader object. + // Note that you must initialize the Xerces-C++ runtime before + // calling this function. + // + void + parse (std::istream&, + xercesc::SAX2XMLReader&, + flags = 0, + const properties& = properties ()); + + public: + // Parse std::istream with a system id. + // + void + parse (std::istream&, + const std::string& system_id, + flags = 0, + const properties& = properties ()); + + // Parse std::istream with a system id and a user-provided + // error_handler object. + // + void + parse (std::istream&, + const std::string& system_id, + error_handler&, + flags = 0, + const properties& = properties ()); + + // Parse std::istream with a system id and a user-provided + // ErrorHandler object. Note that you must initialize the + // Xerces-C++ runtime before calling this function. + // + void + parse (std::istream&, + const std::string& system_id, + xercesc::ErrorHandler&, + flags = 0, + const properties& = properties ()); + + // Parse std::istream with a system id using a user-provided + // SAX2XMLReader object. Note that you must initialize the + // Xerces-C++ runtime before calling this function. + // + void + parse (std::istream&, + const std::string& system_id, + xercesc::SAX2XMLReader&, + flags = 0, + const properties& = properties ()); + + public: + // Parse std::istream with system and public ids. + // + void + parse (std::istream&, + const std::string& system_id, + const std::string& public_id, + flags = 0, + const properties& = properties ()); + + // Parse std::istream with system and public ids and a user-provided + // error_handler object. + // + void + parse (std::istream&, + const std::string& system_id, + const std::string& public_id, + error_handler&, + flags = 0, + const properties& = properties ()); + + // Parse std::istream with system and public ids and a user-provided + // ErrorHandler object. Note that you must initialize the Xerces-C++ + // runtime before calling this function. + // + void + parse (std::istream&, + const std::string& system_id, + const std::string& public_id, + xercesc::ErrorHandler&, + flags = 0, + const properties& = properties ()); + + // Parse std::istream with system and public ids using a user- + // provided SAX2XMLReader object. Note that you must initialize + // the Xerces-C++ runtime before calling this function. + // + void + parse (std::istream&, + const std::string& system_id, + const std::string& public_id, + xercesc::SAX2XMLReader&, + flags = 0, + const properties& = properties ()); + + public: + // Parse InputSource. Note that you must initialize the Xerces-C++ + // runtime before calling this function. + // + void + parse (const xercesc::InputSource&, + flags = 0, + const properties& = properties ()); + + // Parse InputSource with a user-provided error_handler object. + // Note that you must initialize the Xerces-C++ runtime before + // calling this function. + // + void + parse (const xercesc::InputSource&, + error_handler&, + flags = 0, + const properties& = properties ()); + + // Parse InputSource with a user-provided ErrorHandler object. + // Note that you must initialize the Xerces-C++ runtime before + // calling this function. + // + void + parse (const xercesc::InputSource&, + xercesc::ErrorHandler&, + flags = 0, + const properties& = properties ()); + + // Parse InputSource using a user-provided SAX2XMLReader object. + // Note that you must initialize the Xerces-C++ runtime before + // calling this function. + // + void + parse (const xercesc::InputSource&, + xercesc::SAX2XMLReader&, + flags = 0, + const properties& = properties ()); + }; +} + </pre> + + <p>The <code>document</code> class is a root parser for + the vocabulary. The first argument to its constructors is the + parser for the type of the root element. The <code>parser_base</code> + class is the base type for all parser skeletons. The second and + third arguments to the <code>document</code>'s constructors are + the root element's name and namespace. The last argument, + <code>polymorphic</code>, specifies whether the XML documents + being parsed use polymorphism. For more information on support + for XML Schema polymorphism in the C++/Parser mapping refer + to <a href="#5.5">Section 5.5, "Support for Polymorphism"</a>.</p> + + <p>The rest of the <code>document</code> interface consists of overloaded + <code>parse()</code> functions. The last two arguments in each of these + functions are <code>flags</code> and <code>properties</code>. The + <code>flags</code> argument allows you to modify the default behavior + of the parsing functions. The <code>properties</code> argument allows + you to override the schema location attributes specified in XML + documents. Note that the schema location paths are relative to an + XML document unless they are complete URIs. For example if you want + to use a local schema file then you will need to use a URI in the + form <code>file:///absolute/path/to/your/schema</code>.</p> + + <p>A number of overloaded <code>parse()</code> functions have the + <code>system_id</code> and <code>public_id</code> arguments. The + system id is a <em>system</em> identifier of the resources being + parsed (for example, URI or a full file path). The public id is a + <em>public</em> identifier of the resource (for example, an + application-specific name or a relative file path). The system id + is used to resolve relative paths (for example, schema paths). In + diagnostics messages the public id is used if it is available. + Otherwise the system id is used.</p> + + <p>The error handling mechanisms employed by the <code>document</code> + parser are described in <a href="#7.3">Section 7.3, "Error + Handling"</a>.</p> + + <h2><a name="7.2">7.2 Expat Document Parser</a></h2> + + <p>When Expat is used as the underlying XML parser, the + <code>document</code> type has the following interface. Note that + if the character type is <code>wchar_t</code>, then the string type + in the interface becomes <code>std::wstring</code> + (see <a href="#5.2">Section 5.2, "Character Type and Encoding"</a>).</p> + + <pre class="c++"> +namespace xml_schema +{ + class parser_base; + class error_handler; + + class document + { + public: + document (parser_base&, + const std::string& root_element_name, + bool polymorphic = false); + + document (parser_base&, + const std::string& root_element_namespace, + const std::string& root_element_name, + bool polymorphic = false); + + public: + // Parse a local file. The file is accessed with std::ifstream + // in binary mode. The std::ios_base::failure exception is used + // to report io errors (badbit and failbit). + void + parse (const std::string& file); + + // Parse a local file with a user-provided error_handler + // object. The file is accessed with std::ifstream in binary + // mode. The std::ios_base::failure exception is used to report + // io errors (badbit and failbit). + // + void + parse (const std::string& file, error_handler&); + + public: + // Parse std::istream. + // + void + parse (std::istream&); + + // Parse std::istream with a user-provided error_handler object. + // + void + parse (std::istream&, error_handler&); + + // Parse std::istream with a system id. + // + void + parse (std::istream&, const std::string& system_id); + + // Parse std::istream with a system id and a user-provided + // error_handler object. + // + void + parse (std::istream&, + const std::string& system_id, + error_handler&); + + // Parse std::istream with system and public ids. + // + void + parse (std::istream&, + const std::string& system_id, + const std::string& public_id); + + // Parse std::istream with system and public ids and a user-provided + // error_handler object. + // + void + parse (std::istream&, + const std::string& system_id, + const std::string& public_id, + error_handler&); + + public: + // Parse a chunk of input. You can call these functions multiple + // times with the last call having the last argument true. + // + void + parse (const void* data, std::size_t size, bool last); + + void + parse (const void* data, std::size_t size, bool last, + error_handler&); + + void + parse (const void* data, std::size_t size, bool last, + const std::string& system_id); + + void + parse (const void* data, std::size_t size, bool last, + const std::string& system_id, + error_handler&); + + void + parse (const void* data, std::size_t size, bool last, + const std::string& system_id, + const std::string& public_id); + + void + parse (const void* data, std::size_t size, bool last, + const std::string& system_id, + const std::string& public_id, + error_handler&); + + public: + // Low-level Expat-specific parsing API. + // + void + parse_begin (XML_Parser); + + void + parse_begin (XML_Parser, const std::string& public_id); + + void + parse_begin (XML_Parser, error_handler&); + + void + parse_begin (XML_Parser, + const std::string& public_id, + error_handler&); + void + parse_end (); + }; +} + </pre> + + <p>The <code>document</code> class is a root parser for + the vocabulary. The first argument to its constructors is the + parser for the type of the root element. The <code>parser_base</code> + class is the base type for all parser skeletons. The second and + third arguments to the <code>document</code>'s constructors are + the root element's name and namespace. The last argument, + <code>polymorphic</code>, specifies whether the XML documents + being parsed use polymorphism. For more information on support + for XML Schema polymorphism in the C++/Parser mapping refer + to <a href="#5.5">Section 5.5, "Support for Polymorphism"</a>.</p> + + <p>A number of overloaded <code>parse()</code> functions have the + <code>system_id</code> and <code>public_id</code> arguments. The + system id is a <em>system</em> identifier of the resources being + parsed (for example, URI or a full file path). The public id is a + <em>public</em> identifier of the resource (for example, an + application-specific name or a relative file path). The system id + is used to resolve relative paths. In diagnostics messages the + public id is used if it is available. Otherwise the system id + is used.</p> + + <p>The <code>parse_begin()</code> and <code>parse_end()</code> functions + present a low-level, Expat-specific parsing API for maximum control. + A typical use-case would look like this (pseudo-code):</p> + + <pre class="c++"> +xxx_pimpl root_p; +document doc_p (root_p, "root"); + +root_p.pre (); +doc_p.parse_begin (xml_parser, "file.xml"); + +while (more_data_to_parse) +{ + // Call XML_Parse or XML_ParseBuffer. + + if (status == XML_STATUS_ERROR) + break; +} + +// Call parse_end even in case of an error to translate +// XML and Schema errors to exceptions or error_handler +// calls. +// +doc.parse_end (); +result_type result (root_p.post_xxx ()); + </pre> + + <p>Note that if your vocabulary uses XML namespaces, the + <code>XML_ParserCreateNS()</code> functions should be used to create + the XML parser. Space (<code>XML_Char (' ')</code>) should be used + as a separator (the second argument to <code>XML_ParserCreateNS()</code>). + </p> + + <p>The error handling mechanisms employed by the <code>document</code> + parser are described in <a href="#7.3">Section 7.3, "Error + Handling"</a>.</p> + + + <h2><a name="7.3">7.3 Error Handling</a></h2> + + <p>There are three categories of errors that can result from running + a parser on an XML document: System, XML, and Application. + The System category contains memory allocation and file/stream + operation errors. The XML category covers XML parsing and + well-formedness checking as well as XML Schema validation errors. + Finally, the Application category is for application logic errors + that you may want to propagate from parser implementations to the + caller of the parser. + </p> + + <p>The System errors are mapped to the standard exceptions. The + out of memory condition is indicated by throwing an instance + of <code>std::bad_alloc</code>. The stream operation errors + are reported either by throwing an instance of + <code>std::ios_base::failure</code> if exceptions are enabled + or by setting the stream state.</p> + + <p>Note that if you are parsing <code>std::istream</code> on + which exceptions are not enabled, then you will need to + check the stream state before calling the <code>post()</code> + callback, as shown in the following example:</p> + + <pre class="c++"> +int +main (int argc, char* argv[]) +{ + ... + + std::ifstream ifs (argv[1]); + + if (ifs.fail ()) + { + cerr << argv[1] << ": unable to open" << endl; + return 1; + } + + root_p.pre (); + doc_p.parse (ifs); + + if (ifs.fail ()) + { + cerr << argv[1] << ": io failure" << endl; + return 1; + } + + result_type result (root_p.post_xxx ()); +} + </pre> + + <p>The above example can be rewritten to use exceptions + as shown below:</p> + + <pre class="c++"> +int +main (int argc, char* argv[]) +{ + try + { + ... + + std::ifstream ifs; + ifs.exceptions (std::ifstream::badbit | std::ifstream::failbit); + ifs.open (argv[1]); + + root_p.pre (); + doc_p.parse (ifs); + result_type result (root_p.post_xxx ()); + } + catch (const std::ifstream::failure&) + { + cerr << argv[1] << ": unable to open or io failure" << endl; + return 1; + } +} + </pre> + + + <p>For reporting application errors from parsing callbacks, you + can throw any exceptions of your choice. They are propagated to + the caller of the parser without any alterations.</p> + + <p>The XML errors can be reported either by throwing the + <code>xml_schema::parsing</code> exception or by a callback + to the <code>xml_schema::error_handler</code> object (and + <code>xercesc::ErrorHandler</code> object in case of Xerces-C++).</p> + + <p>The <code>xml_schema::parsing</code> exception contains + a list of warnings and errors that were accumulated during + parsing. Note that this exception is thrown only if there + was an error. This makes it impossible to obtain warnings + from an otherwise successful parsing using this mechanism. + The following listing shows the definition of + <code>xml_schema::parsing</code> exception. Note that if the + character type is <code>wchar_t</code>, then the string type + and output stream type in the definition become + <code>std::wstring</code> and <code>std::wostream</code>, + respectively (see <a href="#5.2">Section 5.2, "Character Type + and Encoding"</a>).</p> + + <pre class="c++"> +namespace xml_schema +{ + class exception: public std::exception + { + protected: + virtual void + print (std::ostream&) const = 0; + }; + + inline std::ostream& + operator<< (std::ostream& os, const exception& e) + { + e.print (os); + return os; + } + + + class severity + { + public: + enum value + { + warning, + error + }; + }; + + + class error + { + public: + error (xml_schema::severity, + const std::string& id, + unsigned long line, + unsigned long column, + const std::string& message); + + xml_schema::severity + severity () const; + + const std::string& + id () const; + + unsigned long + line () const; + + unsigned long + column () const; + + const std::string& + message () const; + }; + + std::ostream& + operator<< (std::ostream&, const error&); + + + class diagnostics: public std::vector<error> + { + }; + + std::ostream& + operator<< (std::ostream&, const diagnostics&); + + + class parsing: public exception + { + public: + parsing (); + parsing (const xml_schema::diagnostics&); + + const xml_schema::diagnostics& + diagnostics () const; + + virtual const char* + what () const throw (); + + protected: + virtual void + print (std::ostream&) const; + }; +} + </pre> + + <p>The following example shows how we can catch and print this + exception. The code will print diagnostics messages one per line + in case of an error.</p> + + <pre class="c++"> +int +main (int argc, char* argv[]) +{ + try + { + // Parse. + } + catch (const xml_schema::parsing& e) + { + cerr << e << endl; + return 1; + } +} + </pre> + + <p>With the <code>error_handler</code> approach the diagnostics + messages are delivered as parsing progresses. The following + listing presents the definition of the <code>error_handler</code> + interface. Note that if the character type is <code>wchar_t</code>, + then the string type in the interface becomes <code>std::wstring</code> + (see <a href="#5.2">Section 5.2, "Character Type and Encoding"</a>).</p> + + <pre class="c++"> +namespace xml_schema +{ + class error_handler + { + public: + class severity + { + public: + enum value + { + warning, + error, + fatal + }; + }; + + virtual bool + handle (const std::string& id, + unsigned long line, + unsigned long column, + severity, + const std::string& message) = 0; + }; +} + </pre> + + <p>The return value of the <code>handle()</code> function indicates whether + parsing should continue if possible. The error with the fatal severity + level terminates the parsing process regardless of the returned value. + At the end of the parsing process with an error that was reported via + the <code>error_handler</code> object, an empty + <code>xml_schema::parsing</code> exception is thrown to indicate + the failure to the caller. You can alter this behavior by throwing + your own exception from the <code>handle()</code> function.</p> + + + <!-- Appendix A --> + + + <h1><a name="A">Appendix A — Supported XML Schema Constructs</a></h1> + + <p>The C++/Parser mapping supports validation of the following W3C XML + Schema constructs in the generated code.</p> + + <!-- border="1" is necessary for html2ps --> + <table id="features" border="1"> + <tr><th>Construct</th><th>Notes</th></tr> + <tr><th colspan="2">Structure</th></tr> + + <tr><td>element</td><td></td></tr> + <tr><td>attribute</td><td></td></tr> + + <tr><td>any</td><td></td></tr> + <tr><td>anyAttribute</td><td></td></tr> + + <tr><td>all</td><td></td></tr> + <tr><td>sequence</td><td></td></tr> + <tr><td>choice</td><td></td></tr> + + <tr><td>complex type, empty content</td><td></td></tr> + <tr><td>complex type, mixed content</td><td></td></tr> + <tr><td>complex type, simple content extension</td><td></td></tr> + <tr><td>complex type, simple content restriction</td> + <td>Simple type facets are not validated.</td></tr> + <tr><td>complex type, complex content extension</td><td></td></tr> + <tr><td>complex type, complex content restriction</td><td></td></tr> + + <tr><td>list</td><td></td></tr> + + <tr><th colspan="2">Datatypes</th></tr> + + <tr><td>byte</td><td></td></tr> + <tr><td>unsignedByte</td><td></td></tr> + <tr><td>short</td><td></td></tr> + <tr><td>unsignedShort</td><td></td></tr> + <tr><td>int</td><td></td></tr> + <tr><td>unsignedInt</td><td></td></tr> + <tr><td>long</td><td></td></tr> + <tr><td>unsignedLong</td><td></td></tr> + <tr><td>integer</td><td></td></tr> + <tr><td>nonPositiveInteger</td><td></td></tr> + <tr><td>nonNegativeInteger</td><td></td></tr> + <tr><td>positiveInteger</td><td></td></tr> + <tr><td>negativeInteger</td><td></td></tr> + + <tr><td>boolean</td><td></td></tr> + + <tr><td>float</td><td></td></tr> + <tr><td>double</td><td></td></tr> + <tr><td>decimal</td><td></td></tr> + + <tr><td>string</td><td></td></tr> + <tr><td>normalizedString</td><td></td></tr> + <tr><td>token</td><td></td></tr> + <tr><td>Name</td><td></td></tr> + <tr><td>NMTOKEN</td><td></td></tr> + <tr><td>NCName</td><td></td></tr> + <tr><td>language</td><td></td></tr> + <tr><td>anyURI</td><td></td></tr> + + <tr><td>ID</td><td>Identity constraint is not enforced.</td></tr> + <tr><td>IDREF</td><td>Identity constraint is not enforced.</td></tr> + + <tr><td>NMTOKENS</td><td></td></tr> + <tr><td>IDREFS</td><td>Identity constraint is not enforced.</td></tr> + + <tr><td>QName</td><td></td></tr> + + <tr><td>base64Binary</td><td></td></tr> + <tr><td>hexBinary</td><td></td></tr> + + <tr><td>date</td><td></td></tr> + <tr><td>dateTime</td><td></td></tr> + <tr><td>duration</td><td></td></tr> + <tr><td>gDay</td><td></td></tr> + <tr><td>gMonth</td><td></td></tr> + <tr><td>gMonthDay</td><td></td></tr> + <tr><td>gYear</td><td></td></tr> + <tr><td>gYearMonth</td><td></td></tr> + <tr><td>time</td><td></td></tr> + </table> + + + </div> +</div> + +</body> +</html> diff --git a/xsd/doc/cxx/tree/guide/guide.html2ps.in b/xsd/doc/cxx/tree/guide/guide.html2ps.in new file mode 100644 index 0000000..461ffde --- /dev/null +++ b/xsd/doc/cxx/tree/guide/guide.html2ps.in @@ -0,0 +1,65 @@ +@@html2ps { + option { + toc: hb; + colour: 1; + hyphenate: 1; + titlepage: 1; + } + + datefmt: "%B %Y"; + + titlepage { + content: " +<div align=center> + <h1><big>C++/Tree Mapping</big></h1> + <h1><big>Getting Started Guide</big></h1> + <h1> </h1> + <h1> </h1> + <h1> </h1> + <h1> </h1> + <h1> </h1> + <h1> </h1> +</div> + <p>Copyright © @copyright@.</p> + + <p>Permission is granted to copy, distribute and/or modify this + document under the terms of the + <a href='https://www.codesynthesis.com/licenses/fdl-1.2.txt'>GNU Free + Documentation License, version 1.2</a>; with no Invariant Sections, + no Front-Cover Texts and no Back-Cover Texts. + </p> + + <p>This document is available in the following formats: + <a href='https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/guide/index.xhtml'>XHTML</a>, + <a href='https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/guide/cxx-parser-guide.pdf'>PDF</a>, and + <a href='https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/guide/cxx-parser-guide.ps'>PostScript</a>.</p>"; + } + + toc { + indent: 2em; + } + + header { + odd-right: $H; + even-left: $H; + } + + footer { + odd-left: $D; + odd-center: $T; + odd-right: $N; + + even-left: $N; + even-center: $T; + even-right: $D; + } +} + +body { + font-size: 12pt; + text-align: justify; +} + +pre { + font-size: 10pt; +} diff --git a/xsd/doc/cxx/tree/guide/index.xhtml.in b/xsd/doc/cxx/tree/guide/index.xhtml.in new file mode 100644 index 0000000..2f7f1e2 --- /dev/null +++ b/xsd/doc/cxx/tree/guide/index.xhtml.in @@ -0,0 +1,2736 @@ +<?xml version="1.0" encoding="iso-8859-1"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"> + +<head> + <title>C++/Tree Mapping Getting Started Guide</title> + + <meta name="copyright" content="© @copyright@"/> + <meta name="keywords" content="xsd,xml,schema,c++,mapping,data,binding,parsing,serialization,validation"/> + <meta name="description" content="C++/Tree Mapping Getting Started Guide"/> + + <link rel="stylesheet" type="text/css" href="../../../default.css" /> + +<style type="text/css"> + pre { + padding : 0 0 0 0em; + margin : 0em 0em 0em 0; + + font-size : 102% + } + + body { + min-width: 48em; + } + + h1 { + font-weight: bold; + font-size: 200%; + line-height: 1.2em; + } + + h2 { + font-weight : bold; + font-size : 150%; + + padding-top : 0.8em; + } + + h3 { + font-size : 140%; + padding-top : 0.8em; + } + + /* Adjust indentation for three levels. */ + #container { + max-width: 48em; + } + + #content { + padding: 0 0.1em 0 4em; + /*background-color: red;*/ + } + + #content h1 { + margin-left: -2.06em; + } + + #content h2 { + margin-left: -1.33em; + } + + /* Title page */ + + #titlepage { + padding: 2em 0 1em 0; + border-bottom: 1px solid black; + } + + #titlepage .title { + font-weight: bold; + font-size: 200%; + text-align: center; + } + + #titlepage #first-title { + padding: 1em 0 0.4em 0; + } + + #titlepage #second-title { + padding: 0.4em 0 2em 0; + } + + /* Lists */ + ul.list li { + padding-top : 0.3em; + padding-bottom : 0.3em; + } + + div.img { + text-align: center; + padding: 2em 0 2em 0; + } + + /* */ + dl dt { + padding : 0.8em 0 0 0; + } + + /* Built-in table */ + #builtin { + margin: 2em 0 2em 0; + + border-collapse : collapse; + border : 1px solid; + border-color : #000000; + + font-size : 11px; + line-height : 14px; + } + + #builtin th, #builtin td { + border: 1px solid; + padding : 0.9em 0.9em 0.7em 0.9em; + } + + #builtin th { + background : #cde8f6; + } + + #builtin td { + text-align: left; + } + + /* TOC */ + table.toc { + border-style : none; + border-collapse : separate; + border-spacing : 0; + + margin : 0.2em 0 0.2em 0; + padding : 0 0 0 0; + } + + table.toc tr { + padding : 0 0 0 0; + margin : 0 0 0 0; + } + + table.toc * td, table.toc * th { + border-style : none; + margin : 0 0 0 0; + vertical-align : top; + } + + table.toc * th { + font-weight : normal; + padding : 0em 0.1em 0em 0; + text-align : left; + white-space : nowrap; + } + + table.toc * table.toc th { + padding-left : 1em; + } + + table.toc * td { + padding : 0em 0 0em 0.7em; + text-align : left; + } +</style> + + +</head> + +<body> +<div id="container"> + <div id="content"> + + <div class="noprint"> + + <div id="titlepage"> + <div class="title" id="first-title">C++/Tree Mapping</div> + <div class="title" id="second-title">Getting Started Guide</div> + + <p>Copyright © @copyright@.</p> + + <p>Permission is granted to copy, distribute and/or modify this + document under the terms of the + <a href="https://www.codesynthesis.com/licenses/fdl-1.2.txt">GNU Free + Documentation License, version 1.2</a>; with no Invariant Sections, + no Front-Cover Texts and no Back-Cover Texts. + </p> + + <p>This document is available in the following formats: + <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/guide/index.xhtml">XHTML</a>, + <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/guide/cxx-tree-guide.pdf">PDF</a>, and + <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/guide/cxx-tree-guide.ps">PostScript</a>.</p> + + </div> + + <h1>Table of Contents</h1> + + <table class="toc"> + <tr> + <th></th><td><a href="#0">Preface</a> + <table class="toc"> + <tr><th></th><td><a href="#0.1">About This Document</a></td></tr> + <tr><th></th><td><a href="#0.2">More Information</a></td></tr> + </table> + </td> + </tr> + + <tr> + <th>1</th><td><a href="#1">Introduction</a> + <table class="toc"> + <tr><th>1.1</th><td><a href="#1.1">Mapping Overview</a></td></tr> + <tr><th>1.2</th><td><a href="#1.2">Benefits</a></td></tr> + </table> + </td> + </tr> + + <tr> + <th>2</th><td><a href="#2">Hello World Example</a> + <table class="toc"> + <tr><th>2.1</th><td><a href="#2.1">Writing XML Document and Schema</a></td></tr> + <tr><th>2.2</th><td><a href="#2.2">Translating Schema to C++</a></td></tr> + <tr><th>2.3</th><td><a href="#2.3">Implementing Application Logic</a></td></tr> + <tr><th>2.4</th><td><a href="#2.4">Compiling and Running</a></td></tr> + <tr><th>2.5</th><td><a href="#2.5">Adding Serialization</a></td></tr> + <tr><th>2.6</th><td><a href="#2.6">Selecting Naming Convention</a></td></tr> + <tr><th>2.7</th><td><a href="#2.7">Generating Documentation</a></td></tr> + </table> + </td> + </tr> + + <tr> + <th>3</th><td><a href="#3">Overall Mapping Configuration</a> + <table class="toc"> + <tr><th>3.1</th><td><a href="#3.1">C++ Standard</a></td></tr> + <tr><th>3.2</th><td><a href="#3.2">Character Type and Encoding</a></td></tr> + <tr><th>3.3</th><td><a href="#3.3">Support for Polymorphism </a></td></tr> + <tr><th>3.4</th><td><a href="#3.4">Namespace Mapping</a></td></tr> + <tr><th>3.5</th><td><a href="#3.5">Thread Safety</a></td></tr> + </table> + </td> + </tr> + + <tr> + <th>4</th><td><a href="#4">Working with Object Models</a> + <table class="toc"> + <tr><th>4.1</th><td><a href="#4.1">Attribute and Element Cardinalities</a></td></tr> + <tr><th>4.2</th><td><a href="#4.2">Accessing the Object Model</a></td></tr> + <tr><th>4.3</th><td><a href="#4.3">Modifying the Object Model</a></td></tr> + <tr><th>4.4</th><td><a href="#4.4">Creating the Object Model from Scratch</a></td></tr> + <tr><th>4.5</th><td><a href="#4.5">Mapping for the Built-in XML Schema Types</a></td></tr> + </table> + </td> + </tr> + + <tr> + <th>5</th><td><a href="#5">Parsing</a> + <table class="toc"> + <tr><th>5.1</th><td><a href="#5.1">XML Schema Validation and Searching</a></td></tr> + <tr><th>5.2</th><td><a href="#5.2">Error Handling</a></td></tr> + </table> + </td> + </tr> + + <tr> + <th>6</th><td><a href="#6">Serialization</a> + <table class="toc"> + <tr><th>6.1</th><td><a href="#6.1">Namespace and Schema Information</a></td></tr> + <tr><th>6.2</th><td><a href="#6.2">Error Handling</a></td></tr> + </table> + </td> + </tr> + + </table> + </div> + + <h1><a name="0">Preface</a></h1> + + <h2><a name="0.1">About This Document</a></h2> + + <p>The goal of this document is to provide you with an understanding of + the C++/Tree programming model and allow you to efficiently evaluate + XSD against your project's technical requirements. As such, this + document is intended for C++ developers and software architects + who are looking for an XML processing solution. For a more in-depth + description of the C++/Tree mapping refer to the + <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/">C++/Tree + Mapping User Manual</a>.</p> + + <p>Prior experience with XML and C++ is required to understand this + document. Basic understanding of XML Schema is advantageous but + not expected or required. + </p> + + + <h2><a name="0.2">More Information</a></h2> + + <p>Beyond this guide, you may also find the following sources of + information useful:</p> + + <ul class="list"> + <li><a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/">C++/Tree + Mapping User Manual</a></li> + + <li><a href="http://wiki.codesynthesis.com/Tree/Customization_guide">C++/Tree + Mapping Customization Guide</a></li> + + <li><a href="http://wiki.codesynthesis.com/Tree/FAQ">C++/Tree + Mapping Frequently Asked Questions (FAQ)</a></li> + + <li><a href="https://www.codesynthesis.com/projects/xsd/documentation/xsd.xhtml">XSD + Compiler Command Line Manual</a></li> + + <li>The <code>cxx/tree/</code> directory in the + <a href="https://cppget.org/xsd-examples">xsd-examples</a> package + contains a collection of examples and a README file with an overview + of each example.</li> + + <li>The <code>README</code> file in the + <a href="https://cppget.org/xsd-examples">xsd-examples</a> package + explains how to build the examples.</li> + + <li>The <a href="https://www.codesynthesis.com/mailman/listinfo/xsd-users">xsd-users</a> + mailing list is the place to ask technical questions about XSD and the C++/Parser mapping. + Furthermore, the <a href="https://www.codesynthesis.com/pipermail/xsd-users/">archives</a> + may already have answers to some of your questions.</li> + </ul> + + <!-- Introduction --> + + <h1><a name="1">1 Introduction</a></h1> + + <p>Welcome to CodeSynthesis XSD and the C++/Tree mapping. XSD is a + cross-platform W3C XML Schema to C++ data binding compiler. C++/Tree + is a W3C XML Schema to C++ mapping that represents the data stored + in XML as a statically-typed, vocabulary-specific object model. + </p> + + <h2><a name="1.1">1.1 Mapping Overview</a></h2> + + <p>Based on a formal description of an XML vocabulary (schema), the + C++/Tree mapping produces a tree-like data structure suitable for + in-memory processing. The core of the mapping consists of C++ + classes that constitute the object model and are derived from + types defined in XML Schema as well as XML parsing and + serialization code.</p> + + <p>Besides the core features, C++/Tree provide a number of additional + mapping elements that can be useful in some applications. These + include serialization and extraction to/from formats others than + XML, such as unstructured text (useful for debugging) and binary + representations such as XDR and CDR for high-speed data processing + as well as automatic documentation generation. The C++/Tree mapping + also provides a wide range of mechanisms for controlling and + customizing the generated code.</p> + + <p>A typical application that uses C++/Tree for XML processing usually + performs the following three steps: it first reads (parses) an XML + document to an in-memory object model, it then performs some useful + computations on that object model which may involve modification + of the model, and finally it may write (serialize) the modified + object model back to XML.</p> + + <p>The next chapter presents a simple application that performs these + three steps. The following chapters show how to use the C++/Tree + mapping in more detail.</p> + + <h2><a name="1.2">1.2 Benefits</a></h2> + + <p>Traditional XML access APIs such as Document Object Model (DOM) + or Simple API for XML (SAX) have a number of drawbacks that + make them less suitable for creating robust and maintainable + XML processing applications. These drawbacks include: + </p> + + <ul class="list"> + <li>Generic representation of XML in terms of elements, attributes, + and text forces an application developer to write a substantial + amount of bridging code that identifies and transforms pieces + of information encoded in XML to a representation more suitable + for consumption by the application logic.</li> + + <li>String-based flow control defers error detection to runtime. + It also reduces code readability and maintainability.</li> + + <li>Lack of type safety because the data is represented as text.</li> + + <li>Resulting applications are hard to debug, change, and + maintain.</li> + </ul> + + <p>In contrast, statically-typed, vocabulary-specific object model + produced by the C++/Tree mapping allows you to operate in your + domain terms instead of the generic elements, attributes, and + text. Static typing helps catch errors at compile-time rather + than at run-time. Automatic code generation frees you for more + interesting tasks (such as doing something useful with the + information stored in the XML documents) and minimizes the + effort needed to adapt your applications to changes in the + document structure. To summarize, the C++/Tree object model has + the following key advantages over generic XML access APIs:</p> + + <ul class="list"> + <li><b>Ease of use.</b> The generated code hides all the complexity + associated with parsing and serializing XML. This includes navigating + the structure and converting between the text representation and + data types suitable for manipulation by the application + logic.</li> + + <li><b>Natural representation.</b> The object representation allows + you to access the XML data using your domain vocabulary instead + of generic elements, attributes, and text.</li> + + <li><b>Concise code.</b> With the object representation the + application implementation is simpler and thus easier + to read and understand.</li> + + <li><b>Safety.</b> The generated object model is statically + typed and uses functions instead of strings to access the + information. This helps catch programming errors at compile-time + rather than at runtime.</li> + + <li><b>Maintainability.</b> Automatic code generation minimizes the + effort needed to adapt the application to changes in the + document structure. With static typing, the C++ compiler + can pin-point the places in the client code that need to be + changed.</li> + + <li><b>Compatibility.</b> Sequences of elements are represented in + the object model as containers conforming to the standard C++ + sequence requirements. This makes it possible to use standard + C++ algorithms on the object representation and frees you from + learning yet another container interface, as is the case with + DOM.</li> + + <li><b>Efficiency.</b> If the application makes repetitive use + of the data extracted from XML, then the C++/Tree object model + is more efficient because the navigation is performed using + function calls rather than string comparisons and the XML + data is extracted only once. Furthermore, the runtime memory + usage is reduced due to more efficient data storage + (for instance, storing numeric data as integers instead of + strings) as well as the static knowledge of cardinality + constraints.</li> + </ul> + + + <!-- Hello World Parser --> + + + <h1><a name="2">2 Hello World Example</a></h1> + + <p>In this chapter we will examine how to parse, access, modify, and + serialize a very simple XML document using the XSD-generated + C++/Tree object model. The code presented in this chapter is + based on the <code>hello</code> example which can be found in + the <code>cxx/tree/</code> directory in the + <a href="https://cppget.org/xsd-examples">xsd-examples</a> package.</p> + + <h2><a name="2.1">2.1 Writing XML Document and Schema</a></h2> + + <p>First, we need to get an idea about the structure + of the XML documents we are going to process. Our + <code>hello.xml</code>, for example, could look like this:</p> + + <pre class="xml"> +<?xml version="1.0"?> +<hello> + + <greeting>Hello</greeting> + + <name>sun</name> + <name>moon</name> + <name>world</name> + +</hello> + </pre> + + <p>Then we can write a description of the above XML in the + XML Schema language and save it into <code>hello.xsd</code>:</p> + + <pre class="xml"> +<?xml version="1.0"?> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> + + <xs:complexType name="hello_t"> + <xs:sequence> + <xs:element name="greeting" type="xs:string"/> + <xs:element name="name" type="xs:string" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + + <xs:element name="hello" type="hello_t"/> + +</xs:schema> + </pre> + + <p>Even if you are not familiar with XML Schema, it + should be easy to connect declarations in <code>hello.xsd</code> + to elements in <code>hello.xml</code>. The <code>hello_t</code> type + is defined as a sequence of the nested <code>greeting</code> and + <code>name</code> elements. Note that the term sequence in XML + Schema means that elements should appear in a particular order + as opposed to appearing multiple times. The <code>name</code> + element has its <code>maxOccurs</code> property set to + <code>unbounded</code> which means it can appear multiple times + in an XML document. Finally, the globally-defined <code>hello</code> + element prescribes the root element for our vocabulary. For an + easily-approachable introduction to XML Schema refer to + <a href="http://www.w3.org/TR/xmlschema-0/">XML Schema Part 0: + Primer</a>.</p> + + <p>The above schema is a specification of our XML vocabulary; it tells + everybody what valid documents of our XML-based language should look + like. We can also update our <code>hello.xml</code> to include the + information about the schema so that XML parsers can validate + our document:</p> + + <pre class="xml"> +<?xml version="1.0"?> +<hello xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="hello.xsd"> + + <greeting>Hello</greeting> + + <name>sun</name> + <name>moon</name> + <name>world</name> + +</hello> + </pre> + + + <p>The next step is to compile the schema to generate the object + model and parsing functions.</p> + + <h2><a name="2.2">2.2 Translating Schema to C++</a></h2> + + <p>Now we are ready to translate our <code>hello.xsd</code> to C++. + To do this we invoke the XSD compiler from a terminal (UNIX) or + a command prompt (Windows): + </p> + + <pre class="terminal"> +$ xsd cxx-tree hello.xsd + </pre> + + <p>The XSD compiler produces two C++ files: <code>hello.hxx</code> and + <code>hello.cxx</code>. The following code fragment is taken from + <code>hello.hxx</code>; it should give you an idea about what gets + generated: + </p> + + <pre class="c++"> +class hello_t +{ +public: + // greeting + // + typedef xml_schema::string greeting_type; + + const greeting_type& + greeting () const; + + greeting_type& + greeting (); + + void + greeting (const greeting_type& x); + + // name + // + typedef xml_schema::string name_type; + typedef xsd::sequence<name_type> name_sequence; + typedef name_sequence::iterator name_iterator; + typedef name_sequence::const_iterator name_const_iterator; + + const name_sequence& + name () const; + + name_sequence& + name (); + + void + name (const name_sequence& s); + + // Constructor. + // + hello_t (const greeting_type&); + + ... + +}; + +std::unique_ptr<hello_t> +hello (const std::string& uri); + +std::unique_ptr<hello_t> +hello (std::istream&); + </pre> + + <p>The <code>hello_t</code> C++ class corresponds to the + <code>hello_t</code> XML Schema type. For each element + in this type a set of C++ type definitions as well as + accessor and modifier functions are generated inside the + <code>hello_t</code> class. Note that the type definitions + and member functions for the <code>greeting</code> and + <code>name</code> elements are different because of the + cardinality differences between these two elements + (<code>greeting</code> is a required single element and + <code>name</code> is a sequence of elements).</p> + + <p>The <code>xml_schema::string</code> type used in the type + definitions is a C++ class provided by the XSD runtime + that corresponds to built-in XML Schema type + <code>string</code>. The <code>xml_schema::string</code> + is based on <code>std::string</code> and can be used as + such. Similarly, the <code>sequence</code> class template + that is used in the <code>name_sequence</code> type + definition is based on and has the same interface as + <code>std::vector</code>. The mapping between the built-in + XML Schema types and C++ types is described in more detail in + <a href="#4.5">Section 4.5, "Mapping for the Built-in XML Schema + Types"</a>. The <code>hello_t</code> class also includes a + constructor with an initializer for the required + <code>greeting</code> element as its argument.</p> + + <p>The <code>hello</code> overloaded global functions correspond + to the <code>hello</code> global element in XML Schema. A + global element in XML Schema is a valid document root. + By default XSD generated a set of parsing functions for each + global element defined in XML Schema (this can be overridden + with the <code>--root-element-*</code> options). Parsing + functions return a dynamically allocated object model as an + automatic pointer. The actual pointer used depends on the + C++ standard selected. For C++11 it is <code>std::unique_ptr</code> + as shown above. For C++98 it is <code>std::auto_ptr</code>. + For example, if we modify our XSD compiler invocation to + select C++98:</p> + + <pre class="terminal"> +$ xsd cxx-tree --std c++98 hello.xsd + </pre> + + <p>Then the parsing function signatures will become:</p> + + <pre class="c++"> +std::auto_ptr<hello_t> +hello (const std::string& uri); + +std::auto_ptr<hello_t> +hello (std::istream&); + </pre> + + <p>For more information on parsing functions see <a href="#5">Chapter 5, + "Parsing"</a>.</p> + + <h2><a name="2.3">2.3 Implementing Application Logic</a></h2> + + <p>At this point we have all the parts we need to do something useful + with the information stored in our XML document: + </p> + + <pre class="c++"> +#include <iostream> +#include "hello.hxx" + +using namespace std; + +int +main (int argc, char* argv[]) +{ + try + { + unique_ptr<hello_t> h (hello (argv[1])); + + for (hello_t::name_const_iterator i (h->name ().begin ()); + i != h->name ().end (); + ++i) + { + cerr << h->greeting () << ", " << *i << "!" << endl; + } + } + catch (const xml_schema::exception& e) + { + cerr << e << endl; + return 1; + } +} + </pre> + + <p>The first part of our application calls one of the parsing + functions to parser an XML file specified in the command line. + We then use the returned object model to iterate over names + and print a greeting line for each of them. Finally, we + catch and print the <code>xml_schema::exception</code> + exception in case something goes wrong. This exception + is the root of the exception hierarchy used by the + XSD-generated code. + </p> + + + <h2><a name="2.4">2.4 Compiling and Running</a></h2> + + <p>After saving our application from the previous section in + <code>driver.cxx</code>, we are ready to compile our first + program and run it on the test XML document. On a UNIX + system this can be done with the following commands: + </p> + + <pre class="terminal"> +$ c++ -std=c++11 -I.../libxsd -c driver.cxx hello.cxx +$ c++ -std=c++11 -o driver driver.o hello.o -lxerces-c +$ ./driver hello.xml +Hello, sun! +Hello, moon! +Hello, world! + </pre> + + <p>Here <code>.../libxsd</code> represents the path to the + <a href="https://cppget.org/libxsd">libxsd</a> package root + directory. Note also that we are required to link our + application with the Xerces-C++ library because the generated + code uses it as the underlying XML parser.</p> + + <h2><a name="2.5">2.5 Adding Serialization</a></h2> + + <p>While parsing and accessing the XML data may be everything + you need, there are applications that require creating new + or modifying existing XML documents. By default XSD does + not produce serialization code. We will need to request + it with the <code>--generate-serialization</code> options:</p> + + <pre class="terminal"> +$ xsd cxx-tree --generate-serialization hello.xsd + </pre> + + <p>If we now examine the generated <code>hello.hxx</code> file, + we will find a set of overloaded serialization functions, + including the following version:</p> + + <pre class="c++"> +void +hello (std::ostream&, + const hello_t&, + const xml_schema::namespace_infomap& = + xml_schema::namespace_infomap ()); + + </pre> + + <p>Just like with parsing functions, XSD generates serialization + functions for each global element unless instructed otherwise + with one of the <code>--root-element-*</code> options. For more + information on serialization functions see <a href="#6">Chapter 6, + "Serialization"</a>.</p> + + <p>We first examine an application that modifies an existing + object model and serializes it back to XML:</p> + + <pre class="c++"> +#include <iostream> +#include "hello.hxx" + +using namespace std; + +int +main (int argc, char* argv[]) +{ + try + { + unique_ptr<hello_t> h (hello (argv[1])); + + // Change the greeting phrase. + // + h->greeting ("Hi"); + + // Add another entry to the name sequence. + // + h->name ().push_back ("mars"); + + // Serialize the modified object model to XML. + // + xml_schema::namespace_infomap map; + map[""].name = ""; + map[""].schema = "hello.xsd"; + + hello (cout, *h, map); + } + catch (const xml_schema::exception& e) + { + cerr << e << endl; + return 1; + } +} + </pre> + + <p>First, our application parses an XML document and obtains its + object model as in the previous example. Then it changes the + greeting string and adds another entry to the list of names. + Finally, it serializes the object model back to XML by calling + the serialization function.</p> + + <p>The first argument we pass to the serialization function is + <code>cout</code> which results in the XML being written to + the standard output for us to inspect. We could have also + written the result to a file or memory buffer by creating an + instance of <code>std::ofstream</code> or <code>std::ostringstream</code> + and passing it instead of <code>cout</code>. The second argument is the + object model we want to serialize. The final argument is an optional + namespace information map for our vocabulary. It captures information + such as namespaces, namespace prefixes to which they should be mapped, + and schemas associated with these namespaces. If we don't provide + this argument then generic namespace prefixes (<code>p1</code>, + <code>p2</code>, etc.) will be automatically assigned to XML namespaces + and no schema information will be added to the resulting document + (see <a href="#6">Chapter 6, "Serialization"</a> for details). + In our case, the prefix (map key) and namespace name are empty + because our vocabulary does not use XML namespaces.</p> + + <p>If we now compile and run this application we will see the + output as shown in the following listing:</p> + + <pre class="xml"> +<?xml version="1.0"?> +<hello xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="hello.xsd"> + + <greeting>Hi</greeting> + + <name>sun</name> + <name>moon</name> + <name>world</name> + <name>mars</name> + +</hello> + </pre> + + <p>We can also create and serialize an object model from scratch + as shown in the following example:</p> + + <pre class="c++"> +#include <iostream> +#include <fstream> +#include "hello.hxx" + +using namespace std; + +int +main (int argc, char* argv[]) +{ + try + { + hello_t h ("Hi"); + + hello_t::name_sequence& ns (h.name ()); + + ns.push_back ("Jane"); + ns.push_back ("John"); + + // Serialize the object model to XML. + // + xml_schema::namespace_infomap map; + map[""].name = ""; + map[""].schema = "hello.xsd"; + + std::ofstream ofs (argv[1]); + hello (ofs, h, map); + } + catch (const xml_schema::exception& e) + { + cerr << e << endl; + return 1; + } +} + </pre> + + <p>In this example we used the generated constructor to create + an instance of type <code>hello_t</code>. To reduce typing, + we obtained a reference to the name sequence which we then + used to add a few names. The serialization part is identical + to the previous example except this time we are writing to + a file. If we compile and run this program, it produces the + following XML file:</p> + + <pre class="xml"> +<?xml version="1.0"?> +<hello xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="hello.xsd"> + + <greeting>Hi</greeting> + + <name>Jane</name> + <name>John</name> + +</hello> + </pre> + + <h2><a name="2.6">2.6 Selecting Naming Convention</a></h2> + + <p>By default XSD uses the so-called K&R (Kernighan and Ritchie) + identifier naming convention in the generated code. In this + convention both type and function names are in lower case and + words are separated by underscores. If your application code or + schemas use a different notation, you may want to change the + naming convention used in the generated code for consistency. + XSD supports a set of widely-used naming conventions + that you can select with the <code>--type-naming</code> and + <code>--function-naming</code> options. You can also further + refine one of the predefined conventions or create a completely + custom naming scheme by using the <code>--*-regex</code> options.</p> + + <p>As an example, let's assume that our "Hello World" application + uses the so-called upper-camel-case naming convention for types + (that is, each word in a type name is capitalized) and the K&R + convention for function names. Since K&R is the default + convention for both type and function names, we only need to + change the type naming scheme:</p> + + <pre class="terminal"> +$ xsd cxx-tree --type-naming ucc hello.xsd + </pre> + + <p>The <code>ucc</code> argument to the <code>--type-naming</code> + options stands for upper-camel-case. If we now examine the + generated <code>hello.hxx</code>, we will see the following + changes compared to the declarations shown in the previous + sections:</p> + + <pre class="c++"> +class Hello_t +{ +public: + // greeting + // + typedef xml_schema::String GreetingType; + + const GreetingType& + greeting () const; + + GreetingType& + greeting (); + + void + greeting (const GreetingType& x); + + // name + // + typedef xml_schema::String NameType; + typedef xsd::sequence<NameType> NameSequence; + typedef NameSequence::iterator NameIterator; + typedef NameSequence::const_iterator NameConstIterator; + + const NameSequence& + name () const; + + NameSequence& + name (); + + void + name (const NameSequence& s); + + // Constructor. + // + Hello_t (const GreetingType&); + + ... + +}; + +std::unique_ptr<Hello_t> +hello (const std::string& uri); + +std::unique_ptr<Hello_t> +hello (std::istream&); + </pre> + + <p>Notice that the type names in the <code>xml_schema</code> namespace, + for example <code>xml_schema::String</code>, now also use the + upper-camel-case naming convention. The only thing that we may + be unhappy about in the above code is the <code>_t</code> + suffix in <code>Hello_t</code>. If we are not in a position + to change the schema, we can <em>touch-up</em> the <code>ucc</code> + convention with a custom translation rule using the + <code>--type-regex</code> option:</p> + + <pre class="terminal"> +$ xsd cxx-tree --type-naming ucc --type-regex '/ (.+)_t/\u$1/' hello.xsd + </pre> + + <p>This results in the following changes to the generated code:</p> + + <pre class="c++"> +class Hello +{ +public: + // greeting + // + typedef xml_schema::String GreetingType; + + const GreetingType& + greeting () const; + + GreetingType& + greeting (); + + void + greeting (const GreetingType& x); + + // name + // + typedef xml_schema::String NameType; + typedef xsd::sequence<NameType> NameSequence; + typedef NameSequence::iterator NameIterator; + typedef NameSequence::const_iterator NameConstIterator; + + const NameSequence& + name () const; + + NameSequence& + name (); + + void + name (const NameSequence& s); + + // Constructor. + // + Hello (const GreetingType&); + + ... + +}; + +std::unique_ptr<Hello> +hello (const std::string& uri); + +std::unique_ptr<Hello> +hello (std::istream&); + </pre> + + <p>For more detailed information on the <code>--type-naming</code>, + <code>--function-naming</code>, <code>--type-regex</code>, and + other <code>--*-regex</code> options refer to the NAMING + CONVENTION section in the <a href="https://www.codesynthesis.com/projects/xsd/documentation/xsd.xhtml">XSD + Compiler Command Line Manual</a>.</p> + + <h2><a name="2.7">2.7 Generating Documentation</a></h2> + + <p>While our object model is quite simple, real-world vocabularies + can be quite complex with hundreds of types, elements, and + attributes. For such vocabularies figuring out which types + provide which member functions by studying the generated + source code or schemas can be a daunting task. To provide + application developers with a more accessible way of + understanding the generated object models, the XSD compiler + can be instructed to produce source code with documentation + comments in the Doxygen format. Then the source code can be + processed with the <a href="http://www.doxygen.org">Doxygen</a> + documentation system to extract this information and produce + documentation in various formats. + </p> + + <p>In this section we will see how to generate documentation + for our "Hello World" vocabulary. To showcase the full power + of the XSD documentation facilities, we will first document + our schema. The XSD compiler will then transfer + this information from the schema to the generated code and + then to the object model documentation. Note that the + documentation in the schema is not required for XSD to + generate useful documentation. Below you will find + our <code>hello.xsd</code> with added documentation:</p> + + <pre class="xml"> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> + + <xs:complexType name="hello_t"> + + <xs:annotation> + <xs:documentation> + The hello_t type consists of a greeting phrase and a + collection of names to which this greeting applies. + </xs:documentation> + </xs:annotation> + + <xs:sequence> + + <xs:element name="greeting" type="xs:string"> + <xs:annotation> + <xs:documentation> + The greeting element contains the greeting phrase + for this hello object. + </xs:documentation> + </xs:annotation> + </xs:element> + + <xs:element name="name" type="xs:string" maxOccurs="unbounded"> + <xs:annotation> + <xs:documentation> + The name elements contains names to be greeted. + </xs:documentation> + </xs:annotation> + </xs:element> + + </xs:sequence> + </xs:complexType> + + <xs:element name="hello" type="hello_t"> + <xs:annotation> + <xs:documentation> + The hello element is a root of the Hello XML vocabulary. + Every conforming document should start with this element. + </xs:documentation> + </xs:annotation> + </xs:element> + +</xs:schema> + </pre> + + <p>The first step in obtaining the documentation is to recompile + our schema with the <code>--generate-doxygen</code> option:</p> + + <pre class="terminal"> +$ xsd cxx-tree --generate-serialization --generate-doxygen hello.xsd + </pre> + + <p>Now the generated <code>hello.hxx</code> file contains comments + in the Doxygen format. The next step is to process this file + with the Doxygen documentation system. If your project does + not use Doxygen then you first need to create a configuration + file for your project:</p> + + <pre class="terminal"> +$ doxygen -g hello.doxygen + </pre> + + <p>You only need to perform this step once. Now we can generate + the documentation by executing the following command in the + directory with the generated source code:</p> + + <pre class="terminal"> +$ doxygen hello.doxygen + </pre> + + <p>While the generated documentation can be useful as is, we can + go one step further and link (using the Doxygen tags mechanism) + the documentation for our object model with the documentation + for the XSD runtime library which defines C++ classes for the + built-in XML Schema types. This way we can seamlessly browse + between documentation for the <code>hello_t</code> class which + is generated by the XSD compiler and the <code>xml_schema::string</code> + class which is defined in the XSD runtime library. The Doxygen + configuration file for the XSD runtime is provided with the XSD + distribution.</p> + + <p>You can view the result of the steps described in this section + on the <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/hello/html/annotated.html">Hello + Example Documentation</a> page.</p> + + <!-- Chapater 3 --> + + + <h1><a name="3">3 Overall Mapping Configuration</a></h1> + + <p>The C++/Tree mapping has a number of configuration parameters that + determine the overall properties and behavior of the generated code. + Configuration parameters are specified with the XSD command line + options. This chapter describes configuration aspects that are most + commonly encountered by application developers. These include: the + C++ standard, the character type that is used by the generated code, + handling of vocabularies that use XML Schema polymorphism, XML Schema + to C++ namespace mapping, and thread safety. For more ways to configure + the generated code refer to the + <a href="https://www.codesynthesis.com/projects/xsd/documentation/xsd.xhtml">XSD + Compiler Command Line Manual</a>. + </p> + + <h2><a name="3.1">3.1 C++ Standard</a></h2> + + <p>The C++/Tree mapping provides support for ISO/IEC C++ 2011 (C++11) + and ISO/IEC C++ 1998/2003 (C++98). To select the C++ standard for the + generated code we use the <code>--std</code> XSD compiler command + line option. While the majority of the examples in this guide use + C++11, the document explains the C++11/98 usage difference and so + they can easily be converted to C++98.</p> + + <h2><a name="3.2">3.2 Character Type and Encoding</a></h2> + + <p>The C++/Tree mapping has built-in support for two character types: + <code>char</code> and <code>wchar_t</code>. You can select the + character type with the <code>--char-type</code> command line + option. The default character type is <code>char</code>. The + character type affects all string and string-based types that + are used in the mapping. These include the string-based built-in + XML Schema types, exception types, stream types, etc.</p> + + <p>Another aspect of the mapping that depends on the character type + is character encoding. For the <code>char</code> character type + the default encoding is UTF-8. Other supported encodings are + ISO-8859-1, Xerces-C++ Local Code Page (LPC), as well as + custom encodings. You can select which encoding should be used + in the object model with the <code>--char-encoding</code> command + line option.</p> + + <p>For the <code>wchar_t</code> character type the encoding is + automatically selected between UTF-16 and UTF-32/UCS-4 depending + on the size of the <code>wchar_t</code> type. On some platforms + (for example, Windows with Visual C++ and AIX with IBM XL C++) + <code>wchar_t</code> is 2 bytes long. For these platforms the + encoding is UTF-16. On other platforms <code>wchar_t</code> is 4 bytes + long and UTF-32/UCS-4 is used.</p> + + <p>Note also that the character encoding that is used in the object model + is independent of the encodings used in input and output XML. In fact, + all three (object mode, input XML, and output XML) can have different + encodings.</p> + + <h2><a name="3.3">3.3 Support for Polymorphism</a></h2> + + <p>By default XSD generates non-polymorphic code. If your vocabulary + uses XML Schema polymorphism in the form of <code>xsi:type</code> + and/or substitution groups, then you will need to compile + your schemas with the <code>--generate-polymorphic</code> option + to produce polymorphism-aware code. For more information on + working with polymorphic object models, refer to + <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/#2.11">Section 2.11, + "Mapping for <code>xsi:type</code> and Substitution Groups"</a> in + the C++/Tree Mapping User Manual.</p> + + <h2><a name="3.4">3.4 Namespace Mapping</a></h2> + + <p>XSD maps XML namespaces specified in the <code>targetNamespace</code> + attribute in XML Schema to one or more nested C++ namespaces. By + default, a namespace URI is mapped to a sequence of C++ namespace + names by removing the protocol and host parts and splitting the + rest into a sequence of names with <code>'/'</code> as the name + separator.</p> + + <p>The default mapping of namespace URIs to C++ namespaces + can be altered using the <code>--namespace-map</code> and + <code>--namespace-regex</code> compiler options. For example, + to map namespace URI <code>https://www.codesynthesis.com/my</code> to + C++ namespace <code>cs::my</code>, we can use the following option:</p> + + <pre class="terminal"> +--namespace-map https://www.codesynthesis.com/my=cs::my + </pre> + + <p>A vocabulary without a namespace is mapped to the global scope. This + also can be altered with the above options by using an empty name + for the XML namespace:</p> + + <pre class="terminal"> +--namespace-map =cs + </pre> + + <h2><a name="3.5">3.5 Thread Safety</a></h2> + + <p>XSD-generated code is thread-safe in the sense that you can + use different instantiations of the object model in several + threads concurrently. This is possible due to the generated + code not relying on any writable global variables. If you need + to share the same object between several threads then you will + need to provide some form of synchronization. One approach would + be to use the generated code customization mechanisms to embed + synchronization primitives into the generated C++ classes. For more + information on generated code customization refer to the + <a href="http://wiki.codesynthesis.com/Tree/Customization_guide">C++/Tree + Mapping Customization Guide</a>.</p> + + <p>If you also would like to call parsing and/or serialization + functions from several threads potentially concurrently, then + you will need to make sure the Xerces-C++ runtime is initialized + and terminated only once. The easiest way to do this is to + initialize/terminate Xerces-C++ from <code>main()</code> when + there are no threads yet/anymore:</p> + + <pre class="c++"> +#include <xercesc/util/PlatformUtils.hpp> + +int +main () +{ + xercesc::XMLPlatformUtils::Initialize (); + + { + // Start/terminate threads and parse/serialize here. + } + + xercesc::XMLPlatformUtils::Terminate (); +} + </pre> + + <p>Because you initialize the Xerces-C++ runtime yourself you should + also pass the <code>xml_schema::flags::dont_initialize</code> flag + to parsing and serialization functions. See <a href="#5">Chapter 5, + "Parsing"</a> and <a href="#6">Chapter 6, "Serialization"</a> for + more information.</p> + + + <!-- Chapater 4 --> + + + <h1><a name="4">4 Working with Object Models</a></h1> + + <p>As we have seen in the previous chapters, the XSD compiler generates + a C++ class for each type defined in XML Schema. Together these classes + constitute an object model for an XML vocabulary. In this chapter we + will take a closer look at different elements that comprise an + object model class as well as how to create, access, and modify + object models.</p> + + <p>In this and subsequent chapters we will use the following schema + that describes a collection of person records. We save it in + <code>people.xsd</code>:</p> + + <pre class="xml"> +<?xml version="1.0"?> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> + + <xs:simpleType name="gender_t"> + <xs:restriction base="xs:string"> + <xs:enumeration value="male"/> + <xs:enumeration value="female"/> + </xs:restriction> + </xs:simpleType> + + <xs:complexType name="person_t"> + <xs:sequence> + <xs:element name="first-name" type="xs:string"/> + <xs:element name="middle-name" type="xs:string" minOccurs="0"/> + <xs:element name="last-name" type="xs:string"/> + <xs:element name="gender" type="gender_t"/> + <xs:element name="age" type="xs:short"/> + </xs:sequence> + <xs:attribute name="id" type="xs:unsignedInt" use="required"/> + </xs:complexType> + + <xs:complexType name="people_t"> + <xs:sequence> + <xs:element name="person" type="person_t" maxOccurs="unbounded"/> + </xs:sequence> + </xs:complexType> + + <xs:element name="people" type="people_t"/> + +</xs:schema> + </pre> + + <p>A sample XML instance to go along with this schema is saved + in <code>people.xml</code>:</p> + + <pre class="xml"> +<?xml version="1.0"?> +<people xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="people.xsd"> + + <person id="1"> + <first-name>John</first-name> + <last-name>Doe</last-name> + <gender>male</gender> + <age>32</age> + </person> + + <person id="2"> + <first-name>Jane</first-name> + <middle-name>Mary</middle-name> + <last-name>Doe</last-name> + <gender>female</gender> + <age>28</age> + </person> + +</people> + </pre> + + <p>Compiling <code>people.xsd</code> with the XSD compiler results + in three generated C++ classes: <code>gender_t</code>, + <code>person_t</code>, and <code>people_t</code>. + The <code>gender_t</code> class is modelled after the C++ + <code>enum</code> type. Its definition is presented below:</p> + + <pre class="c++"> +class gender_t: public xml_schema::string +{ +public: + enum value + { + male, + female + }; + + gender_t (value); + gender_t (const xml_schema::string&); + + gender_t& + operator= (value); + + operator value () const; +}; + </pre> + + <p>The following listing shows how we can use this type:</p> + + <pre class="c++"> +gender_t m (gender_t::male); +gender_t f ("female"); + +if (m == "female" || f == gender_t::male) +{ + ... +} + +switch (m) +{ +case gender_t::male: + { + ... + } +case gender_t::female: + { + ... + } +} + </pre> + + <p>The other two classes will be examined in detail in the subsequent + sections.</p> + + <h2><a name="4.1">4.1 Attribute and Element Cardinalities</a></h2> + + <p>As we have seen in the previous chapters, XSD generates a different + set of type definitions and member functions for elements with + different cardinalities. The C++/Tree mapping divides all the possible + element and attribute cardinalities into three cardinality classes: + <em>one</em>, <em>optional</em>, and <em>sequence</em>.</p> + + <p>The <em>one</em> cardinality class covers all elements that should + occur exactly once as well as required attributes. In our + example, the <code>first-name</code>, <code>last-name</code>, + <code>gender</code>, and <code>age</code> elements as well as + the <code>id</code> attribute belong to this cardinality class. + The following code fragment shows type definitions as well as the + accessor and modifier functions that are generated for the + <code>gender</code> element in the <code>person_t</code> class:</p> + + <pre class="c++"> +class person_t +{ + // gender + // + typedef gender_t gender_type; + + const gender_type& + gender () const; + + gender_type& + gender (); + + void + gender (const gender_type&); +}; + </pre> + + <p>The <code>gender_type</code> type is an alias for the element's type. + The first two accessor functions return read-only (constant) and + read-write references to the element's value, respectively. The + modifier function sets the new value for the element.</p> + + <p>The <em>optional</em> cardinality class covers all elements that + can occur zero or one time as well as optional attributes. In our + example, the <code>middle-name</code> element belongs to this + cardinality class. The following code fragment shows the type + definitions as well as the accessor and modifier functions that + are generated for this element in the <code>person_t</code> class:</p> + + <pre class="c++"> +class person_t +{ + // middle-name + // + typedef xml_schema::string middle_name_type; + typedef xsd::optional<middle_name_type> middle_name_optional; + + const middle_name_optional& + middle_name () const; + + middle_name_optional& + middle_name (); + + void + middle_name (const middle_name_type&); + + void + middle_name (const middle_name_optional&); +}; + </pre> + + <p>As with the <code>gender</code> element, <code>middle_name_type</code> + is an alias for the element's type. The <code>middle_name_optional</code> + type is a container for the element's optional value. It can be queried + for the presence of the value using the <code>present()</code> function. + The value itself can be retrieved using the <code>get()</code> + accessor and set using the <code>set()</code> modifier. The container + can be reverted to the value not present state with the call to the + <code>reset()</code> function. The following example shows how we + can use this container:</p> + + <pre class="c++"> +person_t::middle_name_optional n ("John"); + +if (n.present ()) +{ + cout << n.get () << endl; +} + +n.set ("Jane"); +n.reset (); + </pre> + + + <p>Unlike the <em>one</em> cardinality class, the accessor functions + for the <em>optional</em> class return read-only (constant) and + read-write references to the container instead of the element's + value directly. The modifier functions set the new value for the + element.</p> + + <p>Finally, the <em>sequence</em> cardinality class covers all elements + that can occur more than once. In our example, the + <code>person</code> element in the <code>people_t</code> type + belongs to this cardinality class. The following code fragment shows + the type definitions as well as the accessor and modifier functions + that are generated for this element in the <code>people_t</code> + class:</p> + + <pre class="c++"> +class people_t +{ + // person + // + typedef person_t person_type; + typedef xsd::sequence<person_type> person_sequence; + typedef person_sequence::iterator person_iterator; + typedef person_sequence::const_iterator person_const_iterator; + + const person_sequence& + person () const; + + person_sequence& + person (); + + void + person (const person_sequence&); +}; + </pre> + + <p>Identical to the other cardinality classes, <code>person_type</code> + is an alias for the element's type. The <code>person_sequence</code> + type is a sequence container for the element's values. It is based + on and has the same interface as <code>std::vector</code> and + therefore can be used in similar ways. The <code>person_iterator</code> + and <code>person_const_iterator</code> types are read-only + (constant) and read-write iterators for the <code>person_sequence</code> + container.</p> + + <p>Similar to the <em>optional</em> cardinality class, the + accessor functions for the <em>sequence</em> class return + read-only (constant) and read-write references to the sequence + container. The modifier functions copies the entries from + the passed sequence.</p> + + <p>C++/Tree is a "flattening" mapping in a sense that many levels of + nested compositors (<code>choice</code> and <code>sequence</code>), + all potentially with their own cardinalities, are in the end mapped + to a flat set of elements with one of the three cardinality classes + discussed above. While this results in a simple and easy to use API + for most types, in certain cases, the order of elements in the actual + XML documents is not preserved once parsed into the object model. To + overcome this limitation we can mark certain schema types, for which + content order is not sufficiently preserved, as ordered. For more + information on this functionality refer to + <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/#2.8.4">Section + 2.8.4, "Element Order"</a> in the C++/Tree Mapping User Manual.</p> + + <p>For complex schemas with many levels of nested compositors + (<code>choice</code> and <code>sequence</code>) it can also + be hard to deduce the cardinality class of a particular element. + The generated Doxygen documentation can greatly help with + this task. For each element and attribute the documentation + clearly identifies its cardinality class. Alternatively, you + can study the generated header files to find out the cardinality + class of a particular attribute or element.</p> + + <p>In the next sections we will examine how to access and modify + information stored in an object model using accessor and modifier + functions described in this section.</p> + + <h2><a name="4.2">4.2 Accessing the Object Model</a></h2> + + <p>In this section we will learn how to get to the information + stored in the object model for our person records vocabulary. + The following application accesses and prints the contents + of the <code>people.xml</code> file:</p> + + <pre class="c++"> +#include <iostream> +#include "people.hxx" + +using namespace std; + +int +main () +{ + unique_ptr<people_t> ppl (people ("people.xml")); + + // Iterate over individual person records. + // + people_t::person_sequence& ps (ppl->person ()); + + for (people_t::person_iterator i (ps.begin ()); i != ps.end (); ++i) + { + person_t& p (*i); + + // Print names: first-name and last-name are required elements, + // middle-name is optional. + // + cout << "name: " << p.first_name () << " "; + + if (p.middle_name ().present ()) + cout << p.middle_name ().get () << " "; + + cout << p.last_name () << endl; + + // Print gender, age, and id which are all required. + // + cout << "gender: " << p.gender () << endl + << "age: " << p.age () << endl + << "id: " << p.id () << endl + << endl; + } +} + </pre> + + <p>This code shows common patterns of accessing elements and attributes + with different cardinality classes. For the sequence element + (<code>person</code> in <code>people_t</code>) we first obtain a + reference to the container and then iterate over individual + records. The values of elements and attributes with the + <em>one</em> cardinality class (<code>first-name</code>, + <code>last-name</code>, <code>gender</code>, <code>age</code>, + and <code>id</code>) can be obtained directly by calling the + corresponding accessor functions. For the optional element + <code>middle-name</code> we first check if the value is present + and only then call <code>get()</code> to retrieve it.</p> + + <p>Note that when we want to reduce typing by creating a variable + representing a fragment of the object model that we are currently + working with (<code>ps</code> and <code>p</code> above), we obtain + a reference to that fragment instead of making a potentially + expensive copy. This is generally a good rule to follow when + creating high-performance applications.</p> + + <p>If we run the above application on our sample + <code>people.xml</code>, the output looks as follows:</p> + + <pre class="terminal"> +name: John Doe +gender: male +age: 32 +id: 1 + +name: Jane Mary Doe +gender: female +age: 28 +id: 2 + </pre> + + + <h2><a name="4.3">4.3 Modifying the Object Model</a></h2> + + <p>In this section we will learn how to modify the information + stored in the object model for our person records vocabulary. + The following application changes the contents of the + <code>people.xml</code> file:</p> + + <pre class="c++"> +#include <iostream> +#include "people.hxx" + +using namespace std; + +int +main () +{ + unique_ptr<people_t> ppl (people ("people.xml")); + + // Iterate over individual person records and increment + // the age. + // + people_t::person_sequence& ps (ppl->person ()); + + for (people_t::person_iterator i (ps.begin ()); i != ps.end (); ++i) + { + // Alternative way: i->age ()++; + // + i->age (i->age () + 1); + } + + // Add middle-name to the first record and remove it from + // the second. + // + person_t& john (ps[0]); + person_t& jane (ps[1]); + + john.middle_name ("Mary"); + jane.middle_name ().reset (); + + // Add another John record. + // + ps.push_back (john); + + // Serialize the modified object model to XML. + // + xml_schema::namespace_infomap map; + map[""].name = ""; + map[""].schema = "people.xsd"; + + people (cout, *ppl, map); +} + </pre> + + <p>The first modification the above application performs is iterating + over person records and incrementing the age value. This code + fragment shows how to modify the value of a required attribute + or element. The next modification shows how to set a new value + for the optional <code>middle-name</code> element as well + as clear its value. Finally the example adds a copy of the + John Doe record to the <code>person</code> element sequence.</p> + + <p>Note that in this case using references for the <code>ps</code>, + <code>john</code>, and <code>jane</code> variables is no longer + a performance improvement but a requirement for the application + to function correctly. If we hadn't used references, all our changes + would have been made on copies without affecting the object model.</p> + + <p>If we run the above application on our sample <code>people.xml</code>, + the output looks as follows:</p> + + <pre class="xml"> +<?xml version="1.0"?> +<people xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="people.xsd"> + + <person id="1"> + <first-name>John</first-name> + <middle-name>Mary</middle-name> + <last-name>Doe</last-name> + <gender>male</gender> + <age>33</age> + </person> + + <person id="2"> + <first-name>Jane</first-name> + <last-name>Doe</last-name> + <gender>female</gender> + <age>29</age> + </person> + + <person id="1"> + <first-name>John</first-name> + <middle-name>Mary</middle-name> + <last-name>Doe</last-name> + <gender>male</gender> + <age>33</age> + </person> + +</people> + </pre> + + + <h2><a name="4.4">4.4 Creating the Object Model from Scratch</a></h2> + + <p>In this section we will learn how to create a new object model + for our person records vocabulary. The following application + recreates the content of the original <code>people.xml</code> + file:</p> + + <pre class="c++"> +#include <iostream> +#include "people.hxx" + +using namespace std; + +int +main () +{ + people_t ppl; + people_t::person_sequence& ps (ppl.person ()); + + // Add the John Doe record. + // + ps.push_back ( + person_t ("John", // first-name + "Doe", // last-name + gender_t::male, // gender + 32, // age + 1)); + + // Add the Jane Doe record. + // + ps.push_back ( + person_t ("Jane", // first-name + "Doe", // last-name + gender_t::female, // gender + 28, // age + 2)); // id + + // Add middle name to the Jane Doe record. + // + person_t& jane (ps.back ()); + jane.middle_name ("Mary"); + + // Serialize the object model to XML. + // + xml_schema::namespace_infomap map; + map[""].name = ""; + map[""].schema = "people.xsd"; + + people (cout, ppl, map); +} + </pre> + + <p>The only new part in the above application is the calls + to the <code>people_t</code> and <code>person_t</code> + constructors. As a general rule, for each C++ class + XSD generates a constructor with initializers + for each element and attribute belonging to the <em>one</em> + cardinality class. For our vocabulary, the following + constructors are generated:</p> + + <pre class="c++"> +class person_t +{ + person_t (const first_name_type&, + const last_name_type&, + const gender_type&, + const age_type&, + const id_type&); +}; + +class people_t +{ + people_t (); +}; + </pre> + + <p>Note also that we set the <code>middle-name</code> element + on the Jane Doe record by obtaining a reference to that record + in the object model and setting the <code>middle-name</code> + value on it. This is a general rule that should be followed + in order to obtain the best performance: if possible, + direct modifications to the object model should be preferred + to modifications on temporaries with subsequent copying. The + following code fragment shows a semantically equivalent but + slightly slower version:</p> + + <pre class="c++"> +// Add the Jane Doe record. +// +person_t jane ("Jane", // first-name + "Doe", // last-name + gender_t::female, // gender + 28, // age + 2); // id + +jane.middle_name ("Mary"); + +ps.push_back (jane); + </pre> + + <p>We can also go one step further to reduce copying and improve + the performance of our application by using the non-copying + <code>push_back()</code> function which assumes ownership + of the passed objects:</p> + + <pre class="c++"> +// Add the Jane Doe record. C++11 version +// +unique_ptr<person_t> jane_p ( + new person_t ("Jane", // first-name + "Doe", // last-name + gender_t::female, // gender + 28, // age + 2)); // id +ps.push_back (std::move (jane_p)); // assumes ownership + +// Add the John Doe record. C++98 version. +// +auto_ptr<person_t> john_p ( + new person_t ("John", // first-name + "Doe", // last-name + gender_t::male, // gender + 32, // age + 1)); +ps.push_back (john_p); // assumes ownership + </pre> + + <p>For more information on the non-copying modifier functions refer to + <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/#2.8">Section + 2.8, "Mapping for Local Elements and Attributes"</a> in the C++/Tree Mapping + User Manual. The above application produces the following output:</p> + + <pre class="xml"> +<?xml version="1.0" ?> +<people xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="people.xsd"> + + <person id="1"> + <first-name>John</first-name> + <last-name>Doe</last-name> + <gender>male</gender> + <age>32</age> + </person> + + <person id="2"> + <first-name>Jane</first-name> + <middle-name>Mary</middle-name> + <last-name>Doe</last-name> + <gender>female</gender> + <age>28</age> + </person> + +</people> + </pre> + + <h2><a name="4.5">4.5 Mapping for the Built-in XML Schema Types</a></h2> + + <p>Our person record vocabulary uses several built-in XML Schema + types: <code>string</code>, <code>short</code>, and + <code>unsignedInt</code>. Until now we haven't talked about + the mapping of built-in XML Schema types to C++ types and how + to work with them. This section provides an overview + of the built-in types. For more detailed information refer + to <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/#2.5">Section + 2.5, "Mapping for Built-in Data Types"</a> in the C++/Tree Mapping + User Manual.</p> + + <p>In XML Schema, built-in types are defined in the XML Schema namespace. + By default, the C++/Tree mapping maps this namespace to C++ + namespace <code>xml_schema</code> (this mapping can be altered + with the <code>--namespace-map</code> option). The following table + summarizes the mapping of XML Schema built-in types to C++ types:</p> + + <!-- border="1" is necessary for html2ps --> + <table id="builtin" border="1"> + <tr> + <th>XML Schema type</th> + <th>Alias in the <code>xml_schema</code> namespace</th> + <th>C++ type</th> + </tr> + + <tr> + <th colspan="3">fixed-length integral types</th> + </tr> + <!-- 8-bit --> + <tr> + <td><code>byte</code></td> + <td><code>byte</code></td> + <td><code>signed char</code></td> + </tr> + <tr> + <td><code>unsignedByte</code></td> + <td><code>unsigned_byte</code></td> + <td><code>unsigned char</code></td> + </tr> + + <!-- 16-bit --> + <tr> + <td><code>short</code></td> + <td><code>short_</code></td> + <td><code>short</code></td> + </tr> + <tr> + <td><code>unsignedShort</code></td> + <td><code>unsigned_short</code></td> + <td><code>unsigned short</code></td> + </tr> + + <!-- 32-bit --> + <tr> + <td><code>int</code></td> + <td><code>int_</code></td> + <td><code>int</code></td> + </tr> + <tr> + <td><code>unsignedInt</code></td> + <td><code>unsigned_int</code></td> + <td><code>unsigned int</code></td> + </tr> + + <!-- 64-bit --> + <tr> + <td><code>long</code></td> + <td><code>long_</code></td> + <td><code>long long</code></td> + </tr> + <tr> + <td><code>unsignedLong</code></td> + <td><code>unsigned_long</code></td> + <td><code>unsigned long long</code></td> + </tr> + + <tr> + <th colspan="3">arbitrary-length integral types</th> + </tr> + <tr> + <td><code>integer</code></td> + <td><code>integer</code></td> + <td><code>long long</code></td> + </tr> + <tr> + <td><code>nonPositiveInteger</code></td> + <td><code>non_positive_integer</code></td> + <td><code>long long</code></td> + </tr> + <tr> + <td><code>nonNegativeInteger</code></td> + <td><code>non_negative_integer</code></td> + <td><code>unsigned long long</code></td> + </tr> + <tr> + <td><code>positiveInteger</code></td> + <td><code>positive_integer</code></td> + <td><code>unsigned long long</code></td> + </tr> + <tr> + <td><code>negativeInteger</code></td> + <td><code>negative_integer</code></td> + <td><code>long long</code></td> + </tr> + + <tr> + <th colspan="3">boolean types</th> + </tr> + <tr> + <td><code>boolean</code></td> + <td><code>boolean</code></td> + <td><code>bool</code></td> + </tr> + + <tr> + <th colspan="3">fixed-precision floating-point types</th> + </tr> + <tr> + <td><code>float</code></td> + <td><code>float_</code></td> + <td><code>float</code></td> + </tr> + <tr> + <td><code>double</code></td> + <td><code>double_</code></td> + <td><code>double</code></td> + </tr> + + <tr> + <th colspan="3">arbitrary-precision floating-point types</th> + </tr> + <tr> + <td><code>decimal</code></td> + <td><code>decimal</code></td> + <td><code>double</code></td> + </tr> + + <tr> + <th colspan="3">string types</th> + </tr> + <tr> + <td><code>string</code></td> + <td><code>string</code></td> + <td>type derived from <code>std::basic_string</code></td> + </tr> + <tr> + <td><code>normalizedString</code></td> + <td><code>normalized_string</code></td> + <td>type derived from <code>string</code></td> + </tr> + <tr> + <td><code>token</code></td> + <td><code>token</code></td> + <td>type derived from <code>normalized_string</code></td> + </tr> + <tr> + <td><code>Name</code></td> + <td><code>name</code></td> + <td>type derived from <code>token</code></td> + </tr> + <tr> + <td><code>NMTOKEN</code></td> + <td><code>nmtoken</code></td> + <td>type derived from <code>token</code></td> + </tr> + <tr> + <td><code>NMTOKENS</code></td> + <td><code>nmtokens</code></td> + <td>type derived from <code>sequence<nmtoken></code></td> + </tr> + <tr> + <td><code>NCName</code></td> + <td><code>ncname</code></td> + <td>type derived from <code>name</code></td> + </tr> + <tr> + <td><code>language</code></td> + <td><code>language</code></td> + <td>type derived from <code>token</code></td> + </tr> + + <tr> + <th colspan="3">qualified name</th> + </tr> + <tr> + <td><code>QName</code></td> + <td><code>qname</code></td> + <td><code>xml_schema::qname</code></td> + </tr> + + <tr> + <th colspan="3">ID/IDREF types</th> + </tr> + <tr> + <td><code>ID</code></td> + <td><code>id</code></td> + <td>type derived from <code>ncname</code></td> + </tr> + <tr> + <td><code>IDREF</code></td> + <td><code>idref</code></td> + <td>type derived from <code>ncname</code></td> + </tr> + <tr> + <td><code>IDREFS</code></td> + <td><code>idrefs</code></td> + <td>type derived from <code>sequence<idref></code></td> + </tr> + + <tr> + <th colspan="3">URI types</th> + </tr> + <tr> + <td><code>anyURI</code></td> + <td><code>uri</code></td> + <td>type derived from <code>std::basic_string</code></td> + </tr> + + <tr> + <th colspan="3">binary types</th> + </tr> + <tr> + <td><code>base64Binary</code></td> + <td><code>base64_binary</code></td> + <td><code>xml_schema::base64_binary</code></td> + </tr> + <tr> + <td><code>hexBinary</code></td> + <td><code>hex_binary</code></td> + <td><code>xml_schema::hex_binary</code></td> + </tr> + + <tr> + <th colspan="3">date/time types</th> + </tr> + <tr> + <td><code>date</code></td> + <td><code>date</code></td> + <td><code>xml_schema::date</code></td> + </tr> + <tr> + <td><code>dateTime</code></td> + <td><code>date_time</code></td> + <td><code>xml_schema::date_time</code></td> + </tr> + <tr> + <td><code>duration</code></td> + <td><code>duration</code></td> + <td><code>xml_schema::duration</code></td> + </tr> + <tr> + <td><code>gDay</code></td> + <td><code>gday</code></td> + <td><code>xml_schema::gday</code></td> + </tr> + <tr> + <td><code>gMonth</code></td> + <td><code>gmonth</code></td> + <td><code>xml_schema::gmonth</code></td> + </tr> + <tr> + <td><code>gMonthDay</code></td> + <td><code>gmonth_day</code></td> + <td><code>xml_schema::gmonth_day</code></td> + </tr> + <tr> + <td><code>gYear</code></td> + <td><code>gyear</code></td> + <td><code>xml_schema::gyear</code></td> + </tr> + <tr> + <td><code>gYearMonth</code></td> + <td><code>gyear_month</code></td> + <td><code>xml_schema::gyear_month</code></td> + </tr> + <tr> + <td><code>time</code></td> + <td><code>time</code></td> + <td><code>xml_schema::time</code></td> + </tr> + + <tr> + <th colspan="3">entity types</th> + </tr> + <tr> + <td><code>ENTITY</code></td> + <td><code>entity</code></td> + <td>type derived from <code>name</code></td> + </tr> + <tr> + <td><code>ENTITIES</code></td> + <td><code>entities</code></td> + <td>type derived from <code>sequence<entity></code></td> + </tr> + </table> + + <p>As you can see from the table above a number of built-in + XML Schema types are mapped to fundamental C++ types such + as <code>int</code> or <code>bool</code>. All string-based + XML Schema types are mapped to C++ types that are derived + from either <code>std::string</code> or + <code>std::wstring</code>, depending on the character + type selected. For access and modification purposes these + types can be treated as <code>std::string</code>. A number + of built-in types, such as <code>qname</code>, the binary + types, and the date/time types do not have suitable + fundamental or standard C++ types to map to. As a result, + these types are implemented from scratch in the XSD runtime. + For more information on their interfaces refer to + <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/#2.5">Section + 2.5, "Mapping for Built-in Data Types"</a> in the C++/Tree Mapping + User Manual.</p> + + + <!-- Chapater 5 --> + + + <h1><a name="5">5 Parsing</a></h1> + + <p>We have already seen how to parse XML to an object model in this guide + before. In this chapter we will discuss the parsing topic in more + detail.</p> + + <p>By default, the C++/Tree mapping provides a total of 14 overloaded + parsing functions. They differ in the input methods used to + read XML as well as the error reporting mechanisms. It is also possible + to generate types for root elements instead of parsing and serialization + functions. This may be useful if your XML vocabulary has multiple + root elements. For more information on element types refer to + <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/#2.9">Section + 2.9, "Mapping for Global Elements"</a> in the C++/Tree Mapping User + Manual.</p> + + + <p>In this section we will discuss the most commonly used versions of + the parsing functions. For a comprehensive description of parsing + refer to <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/#3">Chapter + 3, "Parsing"</a> in the C++/Tree Mapping User Manual. For the <code>people</code> + global element from our person record vocabulary, we will concentrate + on the following three parsing functions:</p> + + <pre class="c++"> +std::[unique|auto]_ptr<people_t> +people (const std::string& uri, + xml_schema::flags f = 0, + const xml_schema::properties& p = xml_schema::properties ()); + +std::[unique|auto]_ptr<people_t> +people (std::istream& is, + xml_schema::flags f = 0, + const xml_schema::properties& p = xml_schema::properties ()); + +std::[unique|auto]_ptr<people_t> +people (std::istream& is, + const std::string& resource_id, + xml_schema::flags f = 0, + const xml_schema::properties& p = ::xml_schema::properties ()); + </pre> + + <p>The first function parses a local file or a URI. We have already + used this parsing function in the previous chapters. The second + and third functions read XML from a standard input stream. The + last function also requires a resource id. This id is used to + identify the XML document being parser in diagnostics messages + as well as to resolve relative paths to other documents (for example, + schemas) that might be referenced from the XML document.</p> + + <p>The last two arguments to all three parsing functions are parsing + flags and properties. The flags argument provides a number of ways + to fine-tune the parsing process. The properties argument allows + to pass additional information to the parsing functions. We will + use these two arguments in <a href="#5.1">Section 5.1, "XML Schema + Validation and Searching"</a> below. All three functions return + the object model as either <code>std::unique_ptr</code> (C++11) or + <code>std::auto_ptr</code> (C++98), depending on the C++ standard + selected (<code>--std</code> XSD compiler option). The following + example shows how we can use the above parsing functions:</p> + + <pre class="c++"> +using std::unique_ptr; + +// Parse a local file or URI. +// +unique_ptr<people_t> p1 (people ("people.xml")); +unique_ptr<people_t> p2 (people ("http://example.com/people.xml")); + +// Parse a local file via ifstream. +// +std::ifstream ifs ("people.xml"); +unique_ptr<people_t> p3 (people (ifs, "people.xml")); + +// Parse an XML string. +// +std::string str ("..."); // XML in a string. +std::istringstream iss (str); +unique_ptr<people_t> p4 (people (iss)); + </pre> + + + <h2><a name="5.1">5.1 XML Schema Validation and Searching</a></h2> + + <p>The C++/Tree mapping relies on the underlying Xerces-C++ XML + parser for full XML document validation. The XML Schema + validation is enabled by default and can be disabled by + passing the <code>xml_schema::flags::dont_validate</code> + flag to the parsing functions, for example:</p> + + <pre class="c++"> +unique_ptr<people_t> p ( + people ("people.xml", xml_schema::flags::dont_validate)); + </pre> + + <p>Even when XML Schema validation is disabled, the generated + code still performs a number of checks to prevent + construction of an inconsistent object model (for example, an + object model with missing required attributes or elements).</p> + + <p>When XML Schema validation is enabled, the XML parser needs + to locate a schema to validate against. There are several + methods to provide the schema location information to the + parser. The easiest and most commonly used method is to + specify schema locations in the XML document itself + with the <code>schemaLocation</code> or + <code>noNamespaceSchemaLocation</code> attributes, for example:</p> + + <pre class="xml"> +<?xml version="1.0" ?> +<people xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="people.xsd" + xsi:schemaLocation="http://www.w3.org/XML/1998/namespace xml.xsd"> + </pre> + + <p>As you might have noticed, we used this method in all the sample XML + documents presented in this guide up until now. Note that the + schema locations specified with these two attributes are relative + to the document's path unless they are absolute URIs (that is + start with <code>http://</code>, <code>file://</code>, etc.). + In particular, if you specify just file names as your schema + locations, as we did above, then the schemas should reside in + the same directory as the XML document itself.</p> + + <p>Another method of providing the schema location information + is via the <code>xml_schema::properties</code> argument, as + shown in the following example:</p> + + <pre class="c++"> +xml_schema::properties props; +props.no_namespace_schema_location ("people.xsd"); +props.schema_location ("http://www.w3.org/XML/1998/namespace", "xml.xsd"); + +unique_ptr<people_t> p (people ("people.xml", 0, props)); + </pre> + + <p>The schema locations provided with this method overrides + those specified in the XML document. As with the previous + method, the schema locations specified this way are + relative to the document's path unless they are absolute URIs. + In particular, if you want to use local schemas that are + not related to the document being parsed, then you will + need to use the <code>file://</code> URI. The following + example shows how to use schemas that reside in the current + working directory:</p> + + <pre class="c++"> +#include <unistd.h> // getcwd +#include <limits.h> // PATH_MAX + +char cwd[PATH_MAX]; +if (getcwd (cwd, PATH_MAX) == 0) +{ + // Buffer too small? +} + +xml_schema::properties props; + +props.no_namespace_schema_location ( + "file:///" + std::string (cwd) + "/people.xsd"); + +props.schema_location ( + "http://www.w3.org/XML/1998/namespace", + "file:///" + std::string (cwd) + "/xml.xsd"); + +unique_ptr<people_t> p (people ("people.xml", 0, props)); + </pre> + + <p>A third method is the most useful if you are planning to parse + several XML documents of the same vocabulary. In that case + it may be beneficial to pre-parse and cache the schemas in + the XML parser which can then be used to parse all documents + without re-parsing the schemas. For more information on + this method refer to the <code>caching</code> example in the + <code>cxx/tree/</code> directory in the + <a href="https://cppget.org/xsd-examples">xsd-examples</a> package. + It is also possible to convert the schemas into a pre-compiled + binary representation and embed this representation directly into + the application executable. With this approach your application can + perform XML Schema validation without depending on any external + schema files. For more information on how to achieve this refer to + the <code>embedded</code> example in the <code>cxx/tree/</code> + directory in the <a href="https://cppget.org/xsd-examples">xsd-examples</a> + package.</p> + + <p>When the XML parser cannot locate a schema for the + XML document, the validation fails and XML document + elements and attributes for which schema definitions could + not be located are reported in the diagnostics. For + example, if we remove the <code>noNamespaceSchemaLocation</code> + attribute in <code>people.xml</code> from the previous chapter, + then we will get the following diagnostics if we try to parse + this file with validation enabled:</p> + + <pre class="terminal"> +people.xml:2:63 error: no declaration found for element 'people' +people.xml:4:18 error: no declaration found for element 'person' +people.xml:4:18 error: attribute 'id' is not declared for element 'person' +people.xml:5:17 error: no declaration found for element 'first-name' +people.xml:6:18 error: no declaration found for element 'middle-name' +people.xml:7:16 error: no declaration found for element 'last-name' +people.xml:8:13 error: no declaration found for element 'gender' +people.xml:9:10 error: no declaration found for element 'age' + </pre> + + <h2><a name="5.2">5.2 Error Handling</a></h2> + + <p>The parsing functions offer a number of ways to handle error conditions + with the C++ exceptions being the most commonly used mechanism. All + C++/Tree exceptions derive from common base <code>xml_schema::exception</code> + which in turn derives from <code>std::exception</code>. The easiest + way to uniformly handle all possible C++/Tree exceptions and print + detailed information about the error is to catch and print + <code>xml_schema::exception</code>, as shown in the following + example:</p> + + <pre class="c++"> +try +{ + unique_ptr<people_t> p (people ("people.xml")); +} +catch (const xml_schema::exception& e) +{ + cerr << e << endl; +} + </pre> + + <p>Each individual C++/Tree exception also allows you to obtain + error details programmatically. For example, the + <code>xml_schema::parsing</code> exception is thrown when + the XML parsing and validation in the underlying XML parser + fails. It encapsulates various diagnostics information + such as the file name, line and column numbers, as well as the + error or warning message for each entry. For more information + about this and other exceptions that can be thrown during + parsing, refer to + <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/#3.3">Section + 3.3, "Error Handling"</a> in the C++/Tree Mapping + User Manual.</p> + + <p>Note that if you are parsing <code>std::istream</code> on which + exceptions are not enabled, then you will need to check the + stream state after the call to the parsing function in order + to detect any possible stream failures, for example:</p> + + <pre class="c++"> +std::ifstream ifs ("people.xml"); + +if (ifs.fail ()) +{ + cerr << "people.xml: unable to open" << endl; + return 1; +} + +unique_ptr<people_t> p (people (ifs, "people.xml")); + +if (ifs.fail ()) +{ + cerr << "people.xml: read error" << endl; + return 1; +} + </pre> + + <p>The above example can be rewritten to use exceptions as + shown below:</p> + + <pre class="c++"> +try +{ + std::ifstream ifs; + ifs.exceptions (std::ifstream::badbit | std::ifstream::failbit); + ifs.open ("people.xml"); + + unique_ptr<people_t> p (people (ifs, "people.xml")); +} +catch (const std::ifstream::failure&) +{ + cerr << "people.xml: unable to open or read error" << endl; + return 1; +} + </pre> + + + <!-- Chapater 6 --> + + + <h1><a name="6">6 Serialization</a></h1> + + <p>We have already seen how to serialize an object model back to XML + in this guide before. In this chapter we will discuss the + serialization topic in more detail.</p> + + <p>By default, the C++/Tree mapping provides a total of 8 overloaded + serialization functions. They differ in the output methods used to write + XML as well as the error reporting mechanisms. It is also possible to + generate types for root elements instead of parsing and serialization + functions. This may be useful if your XML vocabulary has multiple + root elements. For more information on element types refer to + <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/#2.9">Section + 2.9, "Mapping for Global Elements"</a> in the C++/Tree Mapping User + Manual.</p> + + + <p>In this section we will discuss the most commonly + used version of serialization functions. For a comprehensive description + of serialization refer to + <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/#4">Chapter + 4, "Serialization"</a> in the C++/Tree Mapping User Manual. For the + <code>people</code> global element from our person record vocabulary, + we will concentrate on the following serialization function:</p> + + <pre class="c++"> +void +people (std::ostream& os, + const people_t& x, + const xml_schema::namespace_infomap& map = + xml_schema::namespace_infomap (), + const std::string& encoding = "UTF-8", + xml_schema::flags f = 0); + </pre> + + <p>This function serializes the object model passed as the second + argument to the standard output stream passed as the first + argument. The third argument is a namespace information map + which we will discuss in more detail in the next section. + The fourth argument is a character encoding that the resulting + XML document should be in. Possible valid values for this + argument are "US-ASCII", "ISO8859-1", "UTF-8", "UTF-16BE", + "UTF-16LE", "UCS-4BE", and "UCS-4LE". Finally, the flags + argument allows fine-tuning of the serialization process. + The following example shows how we can use the above serialization + function:</p> + + <pre class="c++"> +people_t& p = ... + +xml_schema::namespace_infomap map; +map[""].schema = "people.xsd"; + +// Serialize to stdout. +// +people (std::cout, p, map); + +// Serialize to a file. +// +std::ofstream ofs ("people.xml"); +people (ofs, p, map); + +// Serialize to a string. +// +std::ostringstream oss; +people (oss, p, map); +std::string xml (oss.str ()); + </pre> + + + <h2><a name="6.1">6.1 Namespace and Schema Information</a></h2> + + <p>While XML serialization can be done just from the object + model alone, it is often desirable to assign meaningful + prefixes to XML namespaces used in the vocabulary as + well as to provide the schema location information. + This is accomplished by passing the namespace information + map to the serialization function. The key in this map is + a namespace prefix that should be assigned to an XML namespace + specified in the <code>name</code> variable of the + map value. You can also assign an optional schema location for + this namespace in the <code>schema</code> variable. Based + on each key-value entry in this map, the serialization + function adds two attributes to the resulting XML document: + the namespace-prefix mapping attribute and schema location + attribute. The empty prefix indicates that the namespace + should be mapped without a prefix. For example, the following + map:</p> + + <pre class="c++"> +xml_schema::namespace_infomap map; + +map[""].name = "http://www.example.com/example"; +map[""].schema = "example.xsd"; + +map["x"].name = "http://www.w3.org/XML/1998/namespace"; +map["x"].schema = "xml.xsd"; + </pre> + + <p>Results in the following XML document:</p> + + <pre class="xml"> +<?xml version="1.0" ?> +<example + xmlns="http://www.example.com/example" + xmlns:x="http://www.w3.org/XML/1998/namespace" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://www.example.com/example example.xsd + http://www.w3.org/XML/1998/namespace xml.xsd"> + </pre> + + <p>The empty namespace indicates that the vocabulary has no target + namespace. For example, the following map results in only the + <code>noNamespaceSchemaLocation</code> attribute being added:</p> + + <pre class="c++"> +xml_schema::namespace_infomap map; + +map[""].name = ""; +map[""].schema = "example.xsd"; + </pre> + + <h2><a name="6.2">6.2 Error Handling</a></h2> + + <p>Similar to the parsing functions, the serialization functions offer a + number of ways to handle error conditions with the C++ exceptions being + the most commonly used mechanisms. As with parsing, the easiest way to + uniformly handle all possible serialization exceptions and print + detailed information about the error is to catch and print + <code>xml_schema::exception</code>:</p> + + <pre class="c++"> +try +{ + people_t& p = ... + + xml_schema::namespace_infomap map; + map[""].schema = "people.xsd"; + + people (std::cout, p, map)); +} +catch (const xml_schema::exception& e) +{ + cerr << e << endl; +} + </pre> + + <p>The most commonly encountered serialization exception is + <code>xml_schema::serialization</code>. It is thrown + when the XML serialization in the underlying XML writer + fails. It encapsulates various diagnostics information + such as the file name, line and column numbers, as well as the + error or warning message for each entry. For more information + about this and other exceptions that can be thrown during + serialization, refer to + <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/#4.4">Section + 4.4, "Error Handling"</a> in the C++/Tree Mapping + User Manual.</p> + + <p>Note that if you are serializing to <code>std::ostream</code> on + which exceptions are not enabled, then you will need to check the + stream state after the call to the serialization function in order + to detect any possible stream failures, for example:</p> + + <pre class="c++"> +std::ofstream ofs ("people.xml"); + +if (ofs.fail ()) +{ + cerr << "people.xml: unable to open" << endl; + return 1; +} + +people (ofs, p, map)); + +if (ofs.fail ()) +{ + cerr << "people.xml: write error" << endl; + return 1; +} + </pre> + + <p>The above example can be rewritten to use exceptions as + shown below:</p> + + <pre class="c++"> +try +{ + std::ofstream ofs; + ofs.exceptions (std::ofstream::badbit | std::ofstream::failbit); + ofs.open ("people.xml"); + + people (ofs, p, map)); +} +catch (const std::ofstream::failure&) +{ + cerr << "people.xml: unable to open or write error" << endl; + return 1; +} + </pre> + + </div> +</div> + +</body> +</html> diff --git a/xsd/doc/cxx/tree/manual/index.xhtml.in b/xsd/doc/cxx/tree/manual/index.xhtml.in new file mode 100644 index 0000000..5274229 --- /dev/null +++ b/xsd/doc/cxx/tree/manual/index.xhtml.in @@ -0,0 +1,6826 @@ +<?xml version="1.0" encoding="iso-8859-1"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"> + +<head> + <title>C++/Tree Mapping User Manual</title> + + <meta name="copyright" content="© @copyright@"/> + <meta name="keywords" content="xsd,xml,schema,c++,mapping,data,binding,tree,serialization,guide,manual,examples"/> + <meta name="description" content="C++/Tree Mapping User Manual"/> + <meta name="revision" content="@doc_version@"/> + + <link rel="stylesheet" type="text/css" href="../../../default.css" /> + +<style type="text/css"> + pre { + padding : 0 0 0 0em; + margin : 0em 0em 0em 0; + + font-size : 102% + } + + body { + min-width: 48em; + } + + h1 { + font-weight: bold; + font-size: 200%; + } + + h2 { + font-weight : bold; + font-size : 150%; + + padding-top : 0.8em; + } + + h3 { + font-size : 130%; + padding-top : 0.8em; + } + + /* Adjust indentation for three levels. */ + #container { + max-width: 48em; + } + + #content { + padding: 0 0.1em 0 4em; + /*background-color: red;*/ + } + + #content h1 { + margin-left: -2.06em; + } + + #content h2 { + margin-left: -1.33em; + } + + /* Title page */ + + #titlepage { + padding: 2em 0 1em 0; + border-bottom: 1px solid black; + } + + #titlepage #title { + font-weight: bold; + font-size: 200%; + text-align: center; + padding: 1em 0 2em 0; + } + + /* Lists */ + ul.list li { + padding-top : 0.3em; + padding-bottom : 0.3em; + } + + + /* Built-in table */ + #builtin { + margin: 2em 0 2em 0; + + border-collapse : collapse; + border : 1px solid; + border-color : #000000; + + font-size : 11px; + line-height : 14px; + } + + #builtin th, #builtin td { + border: 1px solid; + padding : 0.9em 0.9em 0.7em 0.9em; + } + + #builtin th { + background : #cde8f6; + } + + #builtin td { + text-align: left; + } + + + /* default-fixed */ + #default-fixed { + margin: 2em 0 2em 0; + + border-collapse : collapse; + border : 1px solid; + border-color : #000000; + + font-size : 11px; + line-height : 14px; + } + + #default-fixed th, #default-fixed td { + border: 1px solid; + padding : 0.9em 0.9em 0.7em 0.9em; + } + + #default-fixed th { + background : #cde8f6; + } + + #default-fixed td { + text-align: center; + } + + + /* */ + dl dt { + padding : 0.8em 0 0 0; + } + + + /* TOC */ + table.toc { + border-style : none; + border-collapse : separate; + border-spacing : 0; + + margin : 0.2em 0 0.2em 0; + padding : 0 0 0 0; + } + + table.toc tr { + padding : 0 0 0 0; + margin : 0 0 0 0; + } + + table.toc * td, table.toc * th { + border-style : none; + margin : 0 0 0 0; + vertical-align : top; + } + + table.toc * th { + font-weight : normal; + padding : 0em 0.1em 0em 0; + text-align : left; + white-space : nowrap; + } + + table.toc * table.toc th { + padding-left : 1em; + } + + table.toc * td { + padding : 0em 0 0em 0.7em; + text-align : left; + } +</style> + + +</head> + +<body> +<div id="container"> + <div id="content"> + + <div class="noprint"> + + <div id="titlepage"> + <div id="title">C++/Tree Mapping User Manual</div> + + <p>Copyright © @copyright@.</p> + + <p>Permission is granted to copy, distribute and/or modify this + document under the terms of the + <a href="https://www.codesynthesis.com/licenses/fdl-1.2.txt">GNU Free + Documentation License, version 1.2</a>; with no Invariant Sections, + no Front-Cover Texts and no Back-Cover Texts. + </p> + + <p>This document is available in the following formats: + <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/index.xhtml">XHTML</a>, + <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/cxx-tree-manual.pdf">PDF</a>, and + <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/cxx-tree-manual.ps">PostScript</a>.</p> + </div> + + <h1>Table of Contents</h1> + + <table class="toc"> + <tr> + <th></th><td><a href="#0">Preface</a> + <table class="toc"> + <tr><th></th><td><a href="#0.1">About This Document</a></td></tr> + <tr><th></th><td><a href="#0.2">More Information</a></td></tr> + </table> + </td> + </tr> + + <tr> + <th>1</th><td><a href="#1">Introduction</a></td> + </tr> + + <tr> + <th>2</th><td><a href="#2">C++/Tree Mapping</a> + <table class="toc"> + <tr> + <th>2.1</th><td><a href="#2.1">Preliminary Information</a> + <table class="toc"> + <tr><th>2.1.1</th><td><a href="#2.1.1">C++ Standard</a></td></tr> + <tr><th>2.1.2</th><td><a href="#2.1.2">Identifiers</a></td></tr> + <tr><th>2.1.3</th><td><a href="#2.1.3">Character Type and Encoding</a></td></tr> + <tr><th>2.1.4</th><td><a href="#2.1.4">XML Schema Namespace</a></td></tr> + <tr><th>2.1.5</th><td><a href="#2.1.5">Anonymous Types</a></td></tr> + </table> + </td> + </tr> + <tr> + <th>2.2</th><td><a href="#2.2">Error Handling</a> + <table class="toc"> + <tr><th>2.2.1</th><td><a href="#2.2.1"><code>xml_schema::duplicate_id</code></a></td></tr> + </table> + </td> + </tr> + <tr> + <th>2.3</th><td><a href="#2.3">Mapping for <code>import</code> and <code>include</code></a> + <table class="toc"> + <tr><th>2.3.1</th><td><a href="#2.3.1">Import</a></td></tr> + <tr><th>2.3.2</th><td><a href="#2.3.2">Inclusion with Target Namespace</a></td></tr> + <tr><th>2.3.3</th><td><a href="#2.3.3">Inclusion without Target Namespace</a></td></tr> + </table> + </td> + </tr> + <tr> + <th>2.4</th><td><a href="#2.4">Mapping for Namespaces</a></td> + </tr> + <tr> + <th>2.5</th><td><a href="#2.5">Mapping for Built-in Data Types</a> + <table class="toc"> + <tr><th>2.5.1</th><td><a href="#2.5.1">Inheritance from Built-in Data Types</a></td></tr> + <tr><th>2.5.2</th><td><a href="#2.5.2">Mapping for <code>anyType</code></a></td></tr> + <tr><th>2.5.3</th><td><a href="#2.5.3">Mapping for <code>anySimpleType</code></a></td></tr> + <tr><th>2.5.4</th><td><a href="#2.5.4">Mapping for <code>QName</code></a></td></tr> + <tr><th>2.5.5</th><td><a href="#2.5.5">Mapping for <code>IDREF</code></a></td></tr> + <tr><th>2.5.6</th><td><a href="#2.5.6">Mapping for <code>base64Binary</code> and <code>hexBinary</code></a></td></tr> + <tr><th>2.5.7</th><td><a href="#2.5.7">Time Zone Representation</a></td></tr> + <tr><th>2.5.8</th><td><a href="#2.5.8">Mapping for <code>date</code></a></td></tr> + <tr><th>2.5.9</th><td><a href="#2.5.9">Mapping for <code>dateTime</code></a></td></tr> + <tr><th>2.5.10</th><td><a href="#2.5.10">Mapping for <code>duration</code></a></td></tr> + <tr><th>2.5.11</th><td><a href="#2.5.11">Mapping for <code>gDay</code></a></td></tr> + <tr><th>2.5.12</th><td><a href="#2.5.12">Mapping for <code>gMonth</code></a></td></tr> + <tr><th>2.5.13</th><td><a href="#2.5.13">Mapping for <code>gMonthDay</code></a></td></tr> + <tr><th>2.5.14</th><td><a href="#2.5.14">Mapping for <code>gYear</code></a></td></tr> + <tr><th>2.5.15</th><td><a href="#2.5.15">Mapping for <code>gYearMonth</code></a></td></tr> + <tr><th>2.5.16</th><td><a href="#2.5.16">Mapping for <code>time</code></a></td></tr> + </table> + </td> + </tr> + <tr> + <th>2.6</th><td><a href="#2.6">Mapping for Simple Types</a> + <table class="toc"> + <tr><th>2.6.1</th><td><a href="#2.6.1">Mapping for Derivation by Restriction</a></td></tr> + <tr><th>2.6.2</th><td><a href="#2.6.2">Mapping for Enumerations</a></td></tr> + <tr><th>2.6.3</th><td><a href="#2.6.3">Mapping for Derivation by List</a></td></tr> + <tr><th>2.6.4</th><td><a href="#2.6.4">Mapping for Derivation by Union</a></td></tr> + </table> + </td> + </tr> + <tr> + <th>2.7</th><td><a href="#2.7">Mapping for Complex Types</a> + <table class="toc"> + <tr><th>2.7.1</th><td><a href="#2.7.1">Mapping for Derivation by Extension</a></td></tr> + <tr><th>2.7.2</th><td><a href="#2.7.2">Mapping for Derivation by Restriction</a></td></tr> + </table> + </td> + </tr> + <tr> + <th>2.8</th><td><a href="#2.8">Mapping for Local Elements and Attributes</a> + <table class="toc"> + <tr><th>2.8.1</th><td><a href="#2.8.1">Mapping for Members with the One Cardinality Class</a></td></tr> + <tr><th>2.8.2</th><td><a href="#2.8.2">Mapping for Members with the Optional Cardinality Class</a></td></tr> + <tr><th>2.8.3</th><td><a href="#2.8.3">Mapping for Members with the Sequence Cardinality Class</a></td></tr> + <tr><th>2.8.4</th><td><a href="#2.8.4">Element Order</a></td></tr> + </table> + </td> + </tr> + <tr> + <th>2.9</th><td><a href="#2.9">Mapping for Global Elements</a> + <table class="toc"> + <tr><th>2.9.1</th><td><a href="#2.9.1">Element Types</a></td></tr> + <tr><th>2.9.2</th><td><a href="#2.9.2">Element Map</a></td></tr> + </table> + </td> + </tr> + <tr> + <th>2.10</th><td><a href="#2.10">Mapping for Global Attributes</a></td> + </tr> + <tr> + <th>2.11</th><td><a href="#2.11">Mapping for <code>xsi:type</code> and Substitution Groups</a></td> + </tr> + <tr> + <th>2.12</th><td><a href="#2.12">Mapping for <code>any</code> and <code>anyAttribute</code></a> + <table class="toc"> + <tr><th>2.12.1</th><td><a href="#2.12.1">Mapping for <code>any</code> with the One Cardinality Class</a></td></tr> + <tr><th>2.12.2</th><td><a href="#2.12.2">Mapping for <code>any</code> with the Optional Cardinality Class</a></td></tr> + <tr><th>2.12.3</th><td><a href="#2.12.3">Mapping for <code>any</code> with the Sequence Cardinality Class</a></td></tr> + <tr><th>2.12.4</th><td><a href="#2.12.4">Element Wildcard Order</a></td></tr> + <tr><th>2.12.5</th><td><a href="#2.12.5">Mapping for <code>anyAttribute</code></a></td></tr> + </table> + </td> + </tr> + <tr> + <th>2.13</th><td><a href="#2.13">Mapping for Mixed Content Models</a></td> + </tr> + </table> + </td> + </tr> + + <tr> + <th>3</th><td><a href="#3">Parsing</a> + <table class="toc"> + <tr> + <th>3.1</th><td><a href="#3.1">Initializing the Xerces-C++ Runtime</a></td> + </tr> + <tr> + <th>3.2</th><td><a href="#3.2">Flags and Properties</a></td> + </tr> + <tr> + <th>3.3</th><td><a href="#3.3">Error Handling</a> + <table class="toc"> + <tr><th>3.3.1</th><td><a href="#3.3.1"><code>xml_schema::parsing</code></a></td></tr> + <tr><th>3.3.2</th><td><a href="#3.3.2"><code>xml_schema::expected_element</code></a></td></tr> + <tr><th>3.3.3</th><td><a href="#3.3.3"><code>xml_schema::unexpected_element</code></a></td></tr> + <tr><th>3.3.4</th><td><a href="#3.3.4"><code>xml_schema::expected_attribute</code></a></td></tr> + <tr><th>3.3.5</th><td><a href="#3.3.5"><code>xml_schema::unexpected_enumerator</code></a></td></tr> + <tr><th>3.3.6</th><td><a href="#3.3.6"><code>xml_schema::expected_text_content</code></a></td></tr> + <tr><th>3.3.7</th><td><a href="#3.3.7"><code>xml_schema::no_type_info</code></a></td></tr> + <tr><th>3.3.8</th><td><a href="#3.3.8"><code>xml_schema::not_derived</code></a></td></tr> + <tr><th>3.3.9</th><td><a href="#3.3.9"><code>xml_schema::not_prefix_mapping</code></a></td></tr> + </table> + </td> + </tr> + <tr> + <th>3.4</th><td><a href="#3.4">Reading from a Local File or URI</a></td> + </tr> + <tr> + <th>3.5</th><td><a href="#3.5">Reading from <code>std::istream</code></a></td> + </tr> + <tr> + <th>3.6</th><td><a href="#3.6">Reading from <code>xercesc::InputSource</code></a></td> + </tr> + <tr> + <th>3.7</th><td><a href="#3.7">Reading from DOM</a></td> + </tr> + </table> + </td> + </tr> + + <tr> + <th>4</th><td><a href="#4">Serialization</a> + <table class="toc"> + <tr> + <th>4.1</th><td><a href="#4.1">Initializing the Xerces-C++ Runtime</a></td> + </tr> + <tr> + <th>4.2</th><td><a href="#4.2">Namespace Infomap and Character Encoding</a></td> + </tr> + <tr> + <th>4.3</th><td><a href="#4.3">Flags</a></td> + </tr> + <tr> + <th>4.4</th><td><a href="#4.4">Error Handling</a> + <table class="toc"> + <tr><th>4.4.1</th><td><a href="#4.4.1"><code>xml_schema::serialization</code></a></td></tr> + <tr><th>4.4.2</th><td><a href="#4.4.2"><code>xml_schema::unexpected_element</code></a></td></tr> + <tr><th>4.4.3</th><td><a href="#4.4.3"><code>xml_schema::no_type_info</code></a></td></tr> + </table> + </td> + </tr> + <tr> + <th>4.5</th><td><a href="#4.5">Serializing to <code>std::ostream</code></a></td> + </tr> + <tr> + <th>4.6</th><td><a href="#4.6">Serializing to <code>xercesc::XMLFormatTarget</code></a></td> + </tr> + <tr> + <th>4.7</th><td><a href="#4.7">Serializing to DOM</a></td> + </tr> + </table> + </td> + </tr> + + <tr> + <th>5</th><td><a href="#5">Additional Functionality</a> + <table class="toc"> + <tr> + <th>5.1</th><td><a href="#5.1">DOM Association</a></td> + </tr> + <tr> + <th>5.2</th><td><a href="#5.2">Binary Serialization</a></td> + </tr> + </table> + </td> + </tr> + + <tr> + <th></th><td><a href="#A">Appendix A — Default and Fixed Values</a></td> + </tr> + + </table> + </div> + + <h1><a name="0">Preface</a></h1> + + <h2><a name="0.1">About This Document</a></h2> + + <p>This document describes the mapping of W3C XML Schema + to the C++ programming language as implemented by + <a href="https://www.codesynthesis.com/products/xsd">CodeSynthesis + XSD</a> - an XML Schema to C++ data binding compiler. The mapping + represents information stored in XML instance documents as a + statically-typed, tree-like in-memory data structure and is + called C++/Tree. + </p> + + <p>Revision @doc_version@<br/> + This revision of the manual describes the C++/Tree + mapping as implemented by CodeSynthesis XSD version @doc_version@. + </p> + + <p>This document is available in the following formats: + <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/index.xhtml">XHTML</a>, + <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/cxx-tree-manual.pdf">PDF</a>, and + <a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/cxx-tree-manual.ps">PostScript</a>.</p> + + <h2><a name="0.2">More Information</a></h2> + + <p>Beyond this manual, you may also find the following sources of + information useful:</p> + + <ul class="list"> + <li><a href="https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/guide/">C++/Tree + Mapping Getting Started Guide</a></li> + + <li><a href="http://wiki.codesynthesis.com/Tree/Customization_guide">C++/Tree + Mapping Customization Guide</a></li> + + <li><a href="http://wiki.codesynthesis.com/Tree/FAQ">C++/Tree + Mapping Frequently Asked Questions (FAQ)</a></li> + + <li><a href="https://www.codesynthesis.com/projects/xsd/documentation/xsd.xhtml">XSD + Compiler Command Line Manual</a></li> + + <li>The <code>cxx/tree/</code> directory in the + <a href="https://cppget.org/xsd-examples">xsd-examples</a> package + contains a collection of examples and a README file with an overview + of each example.</li> + + <li>The <code>README</code> file in the + <a href="https://cppget.org/xsd-examples">xsd-examples</a> package + explains how to build the examples.</li> + + <li>The <a href="https://www.codesynthesis.com/mailman/listinfo/xsd-users">xsd-users</a> + mailing list is a place to ask questions. Furthermore the + <a href="https://www.codesynthesis.com/pipermail/xsd-users/">archives</a> + may already have answers to some of your questions.</li> + </ul> + + + <h1><a name="1">1 Introduction</a></h1> + + <p>C++/Tree is a W3C XML Schema to C++ mapping that represents the + data stored in XML as a statically-typed, vocabulary-specific + object model. Based on a formal description of an XML vocabulary + (schema), the C++/Tree mapping produces a tree-like data structure + suitable for in-memory processing as well as XML parsing and + serialization code.</p> + + <p>A typical application that processes XML documents usually + performs the following three steps: it first reads (parses) an XML + instance document to an object model, it then performs + some useful computations on that model which may involve + modification of the model, and finally it may write (serialize) + the modified object model back to XML. + </p> + + <p>The C++/Tree mapping consists of C++ types that represent the + given vocabulary (<a href="#2">Chapter 2, "C++/Tree Mapping"</a>), + a set of parsing functions that convert XML documents to + a tree-like in-memory data structure (<a href="#3">Chapter 3, + "Parsing"</a>), and a set of serialization functions that convert + the object model back to XML (<a href="#4">Chapter 4, + "Serialization"</a>). Furthermore, the mapping provides a number + of additional features, such as DOM association and binary + serialization, that can be useful in some applications + (<a href="#5">Chapter 5, "Additional Functionality"</a>). + </p> + + + <!-- Chapter 2 --> + + + <h1><a name="2">2 C++/Tree Mapping</a></h1> + + <h2><a name="2.1">2.1 Preliminary Information</a></h2> + + <h3><a name="2.1.1">2.1.1 C++ Standard</a></h3> + + <p>The C++/Tree mapping provides support for ISO/IEC C++ 2011 (C++11) + and ISO/IEC C++ 1998/2003 (C++98). To select the C++ standard for the + generated code we use the <code>--std</code> XSD compiler command + line option. While the majority of the examples in this guide use + C++11, the document explains the C++11/98 usage difference and so + they can easily be converted to C++98.</p> + + <h3><a name="2.1.2">2.1.2 Identifiers</a></h3> + + <p>XML Schema names may happen to be reserved C++ keywords or contain + characters that are illegal in C++ identifiers. To avoid C++ compilation + problems, such names are changed (escaped) when mapped to C++. If an + XML Schema name is a C++ keyword, the "_" suffix is added to it. All + character of an XML Schema name that are not allowed in C++ identifiers + are replaced with "_". + </p> + + <p>For example, XML Schema name <code>try</code> will be mapped to + C++ identifier <code>try_</code>. Similarly, XML Schema name + <code>strange.na-me</code> will be mapped to C++ identifier + <code>strange_na_me</code>. + </p> + + <p>Furthermore, conflicts between type names and function names in the + same scope are resolved using name escaping. Such conflicts include + both a global element (which is mapped to a set of parsing and/or + serialization functions or element types, see <a href="#2.9">Section + 2.9, "Mapping for Global Elements"</a>) and a global type sharing the + same name as well as a local element or attribute inside a type having + the same name as the type itself.</p> + + <p>For example, if we had a global type <code>catalog</code> + and a global element with the same name then the type would be + mapped to a C++ class with name <code>catalog</code> while the + parsing functions corresponding to the global element would have + their names escaped as <code>catalog_</code>. + </p> + + <p>By default the mapping uses the so-called K&R (Kernighan and + Ritchie) identifier naming convention which is also used throughout + this manual. In this convention both type and function names are in + lower case and words are separated by underscores. If your application + code or schemas use a different notation, you may want to change the + naming convention used by the mapping for consistency. + The compiler supports a set of widely-used naming conventions + that you can select with the <code>--type-naming</code> and + <code>--function-naming</code> options. You can also further + refine one of the predefined conventions or create a completely + custom naming scheme by using the <code>--*-regex</code> options. + For more detailed information on these options refer to the NAMING + CONVENTION section in the <a href="https://www.codesynthesis.com/projects/xsd/documentation/xsd.xhtml">XSD + Compiler Command Line Manual</a>.</p> + + <h3><a name="2.1.3">2.1.3 Character Type and Encoding</a></h3> + + <p>The code that implements the mapping, depending on the + <code>--char-type</code> option, is generated using either + <code>char</code> or <code>wchar_t</code> as the character + type. In this document code samples use symbol <code>C</code> + to refer to the character type you have selected when translating + your schemas, for example <code>std::basic_string<C></code>. + </p> + + <p>Another aspect of the mapping that depends on the character type + is character encoding. For the <code>char</code> character type + the default encoding is UTF-8. Other supported encodings are + ISO-8859-1, Xerces-C++ Local Code Page (LPC), as well as + custom encodings and can be selected with the + <code>--char-encoding</code> command line option.</p> + + <p>For the <code>wchar_t</code> character type the encoding is + automatically selected between UTF-16 and UTF-32/UCS-4 depending + on the size of the <code>wchar_t</code> type. On some platforms + (for example, Windows with Visual C++ and AIX with IBM XL C++) + <code>wchar_t</code> is 2 bytes long. For these platforms the + encoding is UTF-16. On other platforms <code>wchar_t</code> is 4 bytes + long and UTF-32/UCS-4 is used.</p> + + <h3><a name="2.1.4">2.1.4 XML Schema Namespace</a></h3> + + <p>The mapping relies on some predefined types, classes, and functions + that are logically defined in the XML Schema namespace reserved for + the XML Schema language (<code>http://www.w3.org/2001/XMLSchema</code>). + By default, this namespace is mapped to C++ namespace + <code>xml_schema</code>. It is automatically accessible + from a C++ compilation unit that includes a header file generated + from an XML Schema definition. + </p> + + <p>Note that, if desired, the default mapping of this namespace can be + changed as described in <a href="#2.4">Section 2.4, "Mapping for + Namespaces"</a>. + </p> + + + <h3><a name="2.1.5">2.1.5 Anonymous Types</a></h3> + + <p>For the purpose of code generation, anonymous types defined in + XML Schema are automatically assigned names that are derived + from enclosing attributes and elements. Otherwise, such types + follows standard mapping rules for simple and complex type + definitions (see <a href="#2.6">Section 2.6, "Mapping for Simple Types"</a> + and <a href="#2.7">Section 2.7, "Mapping for Complex Types"</a>). + For example, in the following schema fragment: + </p> + + <pre class="xml"> +<element name="object"> + <complexType> + ... + </complexType> +</element> + </pre> + + <p>The anonymous type defined inside element <code>object</code> will + be given name <code>object</code>. The compiler has a number of + options that control the process of anonymous type naming. For more + information refer to the <a href="https://www.codesynthesis.com/projects/xsd/documentation/xsd.xhtml">XSD + Compiler Command Line Manual</a>.</p> + + + <h2><a name="2.2">2.2 Error Handling</a></h2> + + <p>The mapping uses the C++ exception handling mechanism as a primary way + of reporting error conditions. All exceptions that are specified in + this mapping derive from <code>xml_schema::exception</code> which + itself is derived from <code>std::exception</code>: + </p> + + <pre class="c++"> +struct exception: virtual std::exception +{ + friend + std::basic_ostream<C>& + operator<< (std::basic_ostream<C>& os, const exception& e) + { + e.print (os); + return os; + } + +protected: + virtual void + print (std::basic_ostream<C>&) const = 0; +}; + </pre> + + <p>The exception hierarchy supports "virtual" <code>operator<<</code> + which allows you to obtain diagnostics corresponding to the thrown + exception using the base exception interface. For example:</p> + + <pre class="c++"> +try +{ + ... +} +catch (const xml_schema::exception& e) +{ + cerr << e << endl; +} + </pre> + + <p>The following sub-sections describe exceptions thrown by the + types that constitute the object model. + <a href="#3.3">Section 3.3, "Error Handling"</a> of + <a href="#3">Chapter 3, "Parsing"</a> describes exceptions + and error handling mechanisms specific to the parsing functions. + <a href="#4.4">Section 4.4, "Error Handling"</a> of + <a href="#4">Chapter 4, "Serialization"</a> describes exceptions + and error handling mechanisms specific to the serialization functions. + </p> + + + <h3><a name="2.2.1">2.2.1 <code>xml_schema::duplicate_id</code></a></h3> + + <pre class="c++"> +struct duplicate_id: virtual exception +{ + duplicate_id (const std::basic_string<C>& id); + + const std::basic_string<C>& + id () const; + + virtual const char* + what () const throw (); +}; + </pre> + + <p>The <code>xml_schema::duplicate_id</code> is thrown when + a conflicting instance of <code>xml_schema::id</code> (see + <a href="#2.5">Section 2.5, "Mapping for Built-in Data Types"</a>) + is added to a tree. The offending ID value can be obtained using + the <code>id</code> function. + </p> + + <h2><a name="2.3">2.3 Mapping for <code>import</code> and <code>include</code></a></h2> + + <h3><a name="2.3.1">2.3.1 Import</a></h3> + + <p>The XML Schema <code>import</code> element is mapped to the C++ + Preprocessor <code>#include</code> directive. The value of + the <code>schemaLocation</code> attribute is used to derive + the name of the header file that appears in the <code>#include</code> + directive. For instance: + </p> + + <pre class="xml"> +<import namespace="https://www.codesynthesis.com/test" + schemaLocation="test.xsd"/> + </pre> + + <p>is mapped to:</p> + + <pre class="c++"> +#include "test.hxx" + </pre> + + <p>Note that you will need to compile imported schemas separately + in order to produce corresponding header files.</p> + + <h3><a name="2.3.2">2.3.2 Inclusion with Target Namespace</a></h3> + + <p>The XML Schema <code>include</code> element which refers to a schema + with a target namespace or appears in a schema without a target namespace + follows the same mapping rules as the <code>import</code> element, + see <a href="#2.3.1">Section 2.3.1, "Import"</a>. + </p> + + <h3><a name="2.3.3">2.3.3 Inclusion without Target Namespace</a></h3> + + <p>For the XML Schema <code>include</code> element which refers to a schema + without a target namespace and appears in a schema with a target + namespace (such inclusion sometimes called "chameleon inclusion"), + declarations and definitions from the included schema are generated + in-line in the namespace of the including schema as if they were + declared and defined there verbatim. For example, consider the + following two schemas: + </p> + + <pre class="xml"> +<-- common.xsd --> +<schema> + <complexType name="type"> + ... + </complexType> +</schema> + +<-- test.xsd --> +<schema targetNamespace="https://www.codesynthesis.com/test"> + <include schemaLocation="common.xsd"/> +</schema> + </pre> + + <p>The fragment of interest from the generated header file for + <code>text.xsd</code> would look like this:</p> + + <pre class="c++"> +// test.hxx +namespace test +{ + class type + { + ... + }; +} + </pre> + + <h2><a name="2.4">2.4 Mapping for Namespaces</a></h2> + + <p>An XML Schema namespace is mapped to one or more nested C++ + namespaces. XML Schema namespaces are identified by URIs. + By default, a namespace URI is mapped to a sequence of + C++ namespace names by removing the protocol and host parts + and splitting the rest into a sequence of names with '<code>/</code>' + as the name separator. For instance: + </p> + + <pre class="xml"> +<schema targetNamespace="https://www.codesynthesis.com/system/test"> + ... +</schema> + </pre> + + <p>is mapped to:</p> + + <pre class="c++"> +namespace system +{ + namespace test + { + ... + } +} + </pre> + + <p>The default mapping of namespace URIs to C++ namespace names can be + altered using the <code>--namespace-map</code> and + <code>--namespace-regex</code> options. See the + <a href="https://www.codesynthesis.com/projects/xsd/documentation/xsd.xhtml">XSD + Compiler Command Line Manual</a> for more information. + </p> + + <h2><a name="2.5">2.5 Mapping for Built-in Data Types</a></h2> + + <p>The mapping of XML Schema built-in data types to C++ types is + summarized in the table below.</p> + + <!-- border="1" is necessary for html2ps --> + <table id="builtin" border="1"> + <tr> + <th>XML Schema type</th> + <th>Alias in the <code>xml_schema</code> namespace</th> + <th>C++ type</th> + </tr> + + <tr> + <th colspan="3">anyType and anySimpleType types</th> + </tr> + <tr> + <td><code>anyType</code></td> + <td><code>type</code></td> + <td><a href="#2.5.2">Section 2.5.2, "Mapping for <code>anyType</code>"</a></td> + </tr> + <tr> + <td><code>anySimpleType</code></td> + <td><code>simple_type</code></td> + <td><a href="#2.5.3">Section 2.5.3, "Mapping for <code>anySimpleType</code>"</a></td> + </tr> + + <tr> + <th colspan="3">fixed-length integral types</th> + </tr> + <!-- 8-bit --> + <tr> + <td><code>byte</code></td> + <td><code>byte</code></td> + <td><code>signed char</code></td> + </tr> + <tr> + <td><code>unsignedByte</code></td> + <td><code>unsigned_byte</code></td> + <td><code>unsigned char</code></td> + </tr> + + <!-- 16-bit --> + <tr> + <td><code>short</code></td> + <td><code>short_</code></td> + <td><code>short</code></td> + </tr> + <tr> + <td><code>unsignedShort</code></td> + <td><code>unsigned_short</code></td> + <td><code>unsigned short</code></td> + </tr> + + <!-- 32-bit --> + <tr> + <td><code>int</code></td> + <td><code>int_</code></td> + <td><code>int</code></td> + </tr> + <tr> + <td><code>unsignedInt</code></td> + <td><code>unsigned_int</code></td> + <td><code>unsigned int</code></td> + </tr> + + <!-- 64-bit --> + <tr> + <td><code>long</code></td> + <td><code>long_</code></td> + <td><code>long long</code></td> + </tr> + <tr> + <td><code>unsignedLong</code></td> + <td><code>unsigned_long</code></td> + <td><code>unsigned long long</code></td> + </tr> + + <tr> + <th colspan="3">arbitrary-length integral types</th> + </tr> + <tr> + <td><code>integer</code></td> + <td><code>integer</code></td> + <td><code>long long</code></td> + </tr> + <tr> + <td><code>nonPositiveInteger</code></td> + <td><code>non_positive_integer</code></td> + <td><code>long long</code></td> + </tr> + <tr> + <td><code>nonNegativeInteger</code></td> + <td><code>non_negative_integer</code></td> + <td><code>unsigned long long</code></td> + </tr> + <tr> + <td><code>positiveInteger</code></td> + <td><code>positive_integer</code></td> + <td><code>unsigned long long</code></td> + </tr> + <tr> + <td><code>negativeInteger</code></td> + <td><code>negative_integer</code></td> + <td><code>long long</code></td> + </tr> + + <tr> + <th colspan="3">boolean types</th> + </tr> + <tr> + <td><code>boolean</code></td> + <td><code>boolean</code></td> + <td><code>bool</code></td> + </tr> + + <tr> + <th colspan="3">fixed-precision floating-point types</th> + </tr> + <tr> + <td><code>float</code></td> + <td><code>float_</code></td> + <td><code>float</code></td> + </tr> + <tr> + <td><code>double</code></td> + <td><code>double_</code></td> + <td><code>double</code></td> + </tr> + + <tr> + <th colspan="3">arbitrary-precision floating-point types</th> + </tr> + <tr> + <td><code>decimal</code></td> + <td><code>decimal</code></td> + <td><code>double</code></td> + </tr> + + <tr> + <th colspan="3">string types</th> + </tr> + <tr> + <td><code>string</code></td> + <td><code>string</code></td> + <td>type derived from <code>std::basic_string</code></td> + </tr> + <tr> + <td><code>normalizedString</code></td> + <td><code>normalized_string</code></td> + <td>type derived from <code>string</code></td> + </tr> + <tr> + <td><code>token</code></td> + <td><code>token</code></td> + <td>type derived from <code>normalized_string</code></td> + </tr> + <tr> + <td><code>Name</code></td> + <td><code>name</code></td> + <td>type derived from <code>token</code></td> + </tr> + <tr> + <td><code>NMTOKEN</code></td> + <td><code>nmtoken</code></td> + <td>type derived from <code>token</code></td> + </tr> + <tr> + <td><code>NMTOKENS</code></td> + <td><code>nmtokens</code></td> + <td>type derived from <code>sequence<nmtoken></code></td> + </tr> + <tr> + <td><code>NCName</code></td> + <td><code>ncname</code></td> + <td>type derived from <code>name</code></td> + </tr> + <tr> + <td><code>language</code></td> + <td><code>language</code></td> + <td>type derived from <code>token</code></td> + </tr> + + <tr> + <th colspan="3">qualified name</th> + </tr> + <tr> + <td><code>QName</code></td> + <td><code>qname</code></td> + <td><a href="#2.5.4">Section 2.5.4, "Mapping for <code>QName</code>"</a></td> + </tr> + + <tr> + <th colspan="3">ID/IDREF types</th> + </tr> + <tr> + <td><code>ID</code></td> + <td><code>id</code></td> + <td>type derived from <code>ncname</code></td> + </tr> + <tr> + <td><code>IDREF</code></td> + <td><code>idref</code></td> + <td><a href="#2.5.5">Section 2.5.5, "Mapping for <code>IDREF</code>"</a></td> + </tr> + <tr> + <td><code>IDREFS</code></td> + <td><code>idrefs</code></td> + <td>type derived from <code>sequence<idref></code></td> + </tr> + + <tr> + <th colspan="3">URI types</th> + </tr> + <tr> + <td><code>anyURI</code></td> + <td><code>uri</code></td> + <td>type derived from <code>std::basic_string</code></td> + </tr> + + <tr> + <th colspan="3">binary types</th> + </tr> + <tr> + <td><code>base64Binary</code></td> + <td><code>base64_binary</code></td> + <td rowspan="2"><a href="#2.5.6">Section 2.5.6, "Mapping for + <code>base64Binary</code> and <code>hexBinary</code>"</a></td> + </tr> + <tr> + <td><code>hexBinary</code></td> + <td><code>hex_binary</code></td> + </tr> + + <tr> + <th colspan="3">date/time types</th> + </tr> + <tr> + <td><code>date</code></td> + <td><code>date</code></td> + <td><a href="#2.5.8">Section 2.5.8, "Mapping for + <code>date</code>"</a></td> + </tr> + <tr> + <td><code>dateTime</code></td> + <td><code>date_time</code></td> + <td><a href="#2.5.9">Section 2.5.9, "Mapping for + <code>dateTime</code>"</a></td> + </tr> + <tr> + <td><code>duration</code></td> + <td><code>duration</code></td> + <td><a href="#2.5.10">Section 2.5.10, "Mapping for + <code>duration</code>"</a></td> + </tr> + <tr> + <td><code>gDay</code></td> + <td><code>gday</code></td> + <td><a href="#2.5.11">Section 2.5.11, "Mapping for + <code>gDay</code>"</a></td> + </tr> + <tr> + <td><code>gMonth</code></td> + <td><code>gmonth</code></td> + <td><a href="#2.5.12">Section 2.5.12, "Mapping for + <code>gMonth</code>"</a></td> + </tr> + <tr> + <td><code>gMonthDay</code></td> + <td><code>gmonth_day</code></td> + <td><a href="#2.5.13">Section 2.5.13, "Mapping for + <code>gMonthDay</code>"</a></td> + </tr> + <tr> + <td><code>gYear</code></td> + <td><code>gyear</code></td> + <td><a href="#2.5.14">Section 2.5.14, "Mapping for + <code>gYear</code>"</a></td> + </tr> + <tr> + <td><code>gYearMonth</code></td> + <td><code>gyear_month</code></td> + <td><a href="#2.5.15">Section 2.5.15, "Mapping for + <code>gYearMonth</code>"</a></td> + </tr> + <tr> + <td><code>time</code></td> + <td><code>time</code></td> + <td><a href="#2.5.16">Section 2.5.16, "Mapping for + <code>time</code>"</a></td> + </tr> + + <tr> + <th colspan="3">entity types</th> + </tr> + <tr> + <td><code>ENTITY</code></td> + <td><code>entity</code></td> + <td>type derived from <code>name</code></td> + </tr> + <tr> + <td><code>ENTITIES</code></td> + <td><code>entities</code></td> + <td>type derived from <code>sequence<entity></code></td> + </tr> + </table> + + <p>All XML Schema built-in types are mapped to C++ classes that are + derived from the <code>xml_schema::simple_type</code> class except + where the mapping is to a fundamental C++ type.</p> + + <p>The <code>sequence</code> class template is defined in an + implementation-specific namespace. It conforms to the + sequence interface as defined by the ISO/ANSI Standard for + C++ (ISO/IEC 14882:1998, Section 23.1.1, "Sequences"). + Practically, this means that you can treat such a sequence + as if it was <code>std::vector</code>. One notable extension + to the standard interface that is available only for + sequences of non-fundamental C++ types is the addition of + the overloaded <code>push_back</code> and <code>insert</code> + member functions which instead of the constant reference + to the element type accept automatic pointer (<code>std::unique_ptr</code> + or <code>std::auto_ptr</code>, depending on the C++ standard + selected) to the element type. These functions assume ownership + of the pointed to object and reset the passed automatic pointer. + </p> + + <h3><a name="2.5.1">2.5.1 Inheritance from Built-in Data Types</a></h3> + + <p>In cases where the mapping calls for an inheritance from a built-in + type which is mapped to a fundamental C++ type, a proxy type is + used instead of the fundamental C++ type (C++ does not allow + inheritance from fundamental types). For instance:</p> + + <pre class="xml"> +<simpleType name="my_int"> + <restriction base="int"/> +</simpleType> + </pre> + + <p>is mapped to:</p> + + <pre class="c++"> +class my_int: public fundamental_base<int> +{ + ... +}; + </pre> + + <p>The <code>fundamental_base</code> class template provides a close + emulation (though not exact) of a fundamental C++ type. + It is defined in an implementation-specific namespace and has the + following interface:</p> + + <pre class="c++"> +template <typename X> +class fundamental_base: public simple_type +{ +public: + fundamental_base (); + fundamental_base (X) + fundamental_base (const fundamental_base&) + +public: + fundamental_base& + operator= (const X&); + +public: + operator const X & () const; + operator X& (); + + template <typename Y> + operator Y () const; + + template <typename Y> + operator Y (); +}; + </pre> + + <h3><a name="2.5.2">2.5.2 Mapping for <code>anyType</code></a></h3> + + <p>The XML Schema <code>anyType</code> built-in data type is mapped to the + <code>xml_schema::type</code> C++ class:</p> + + <pre class="c++"> +class type +{ +public: + virtual + ~type (); + + type (); + type (const type&); + + type& + operator= (const type&); + + virtual type* + _clone () const; + + // anyType DOM content. + // +public: + typedef element_optional dom_content_optional; + + const dom_content_optional& + dom_content () const; + + dom_content_optional& + dom_content (); + + void + dom_content (const xercesc::DOMElement&); + + void + dom_content (xercesc::DOMElement*); + + void + dom_content (const dom_content_optional&); + + const xercesc::DOMDocument& + dom_content_document () const; + + xercesc::DOMDocument& + dom_content_document (); + + bool + null_content () const; + + // DOM association. + // +public: + const xercesc::DOMNode* + _node () const; + + xercesc::DOMNode* + _node (); +}; + </pre> + + <p>When <code>xml_schema::type</code> is used to create an instance + (as opposed to being a base of a derived type), it represents + the XML Schema <code>anyType</code> type. <code>anyType</code> + allows any attributes and any content in any order. In the + C++/Tree mapping this content can be represented as a DOM + fragment, similar to XML Schema wildcards (<a href="#2.12">Section + 2.12, "Mapping for <code>any</code> and + <code>anyAttribute</code>"</a>).</p> + + <p>To enable automatic extraction of <code>anyType</code> content + during parsing, the <code>--generate-any-type</code> option must be + specified. Because the DOM API is used to access such content, the + Xerces-C++ runtime should be initialized by the application prior to + parsing and should remain initialized for the lifetime of objects + with the DOM content. For more information on the Xerces-C++ runtime + initialization see <a href="#3.1">Section 3.1, "Initializing the + Xerces-C++ Runtime"</a>.</p> + + <p>The DOM content is stored as the optional DOM element container + and the DOM content accessors and modifiers presented above are + identical to those generated for an optional element wildcard. + Refer to <a href="#2.12.2">Section 2.12.2, "Mapping for <code>any</code> + with the Optional Cardinality Class"</a> for details on their + semantics.</p> + + <p>The <code>dom_content_document()</code> function returns the + DOM document used to store the raw XML content corresponding + to the <code>anyType</code> instance. It is equivalent to the + <code>dom_document()</code> function generated for types + with wildcards.</p> + + <p>The <code>null_content()</code> accessor is an optimization function + that allows us to check for the lack of content without actually + creating its empty representation, that is, empty DOM document for + <code>anyType</code> or empty string for <code>anySimpleType</code> + (see the following section for details on <code>anySimpleType</code>).</p> + + <p>For more information on DOM association refer to + <a href="#5.1">Section 5.1, "DOM Association"</a>.</p> + + <h3><a name="2.5.3">2.5.3 Mapping for <code>anySimpleType</code></a></h3> + + <p>The XML Schema <code>anySimpleType</code> built-in data type is mapped + to the <code>xml_schema::simple_type</code> C++ class:</p> + + <pre class="c++"> +class simple_type: public type +{ +public: + simple_type (); + simple_type (const C*); + simple_type (const std::basic_string<C>&); + + simple_type (const simple_type&); + + simple_type& + operator= (const simple_type&); + + virtual simple_type* + _clone () const; + + // anySimpleType text content. + // +public: + const std::basic_string<C>& + text_content () const; + + std::basic_string<C>& + text_content (); + + void + text_content (const std::basic_string<C>&); +}; + </pre> + + <p>When <code>xml_schema::simple_type</code> is used to create an instance + (as opposed to being a base of a derived type), it represents + the XML Schema <code>anySimpleType</code> type. <code>anySimpleType</code> + allows any simple content. In the C++/Tree mapping this content can + be represented as a string and accessed or modified with the + <code>text_content()</code> functions shown above.</p> + + <h3><a name="2.5.4">2.5.4 Mapping for <code>QName</code></a></h3> + + <p>The XML Schema <code>QName</code> built-in data type is mapped to the + <code>xml_schema::qname</code> C++ class:</p> + + <pre class="c++"> +class qname: public simple_type +{ +public: + qname (const ncname&); + qname (const uri&, const ncname&); + qname (const qname&); + +public: + qname& + operator= (const qname&); + +public: + virtual qname* + _clone () const; + +public: + bool + qualified () const; + + const uri& + namespace_ () const; + + const ncname& + name () const; +}; + </pre> + + <p>The <code>qualified</code> accessor function can be used to determine + if the name is qualified.</p> + + <h3><a name="2.5.5">2.5.5 Mapping for <code>IDREF</code></a></h3> + + <p>The XML Schema <code>IDREF</code> built-in data type is mapped to the + <code>xml_schema::idref</code> C++ class. This class implements the + smart pointer C++ idiom:</p> + + <pre class="c++"> +class idref: public ncname +{ +public: + idref (const C* s); + idref (const C* s, std::size_t n); + idref (std::size_t n, C c); + idref (const std::basic_string<C>&); + idref (const std::basic_string<C>&, + std::size_t pos, + std::size_t n = npos); + +public: + idref (const idref&); + +public: + virtual idref* + _clone () const; + +public: + idref& + operator= (C c); + + idref& + operator= (const C* s); + + idref& + operator= (const std::basic_string<C>&) + + idref& + operator= (const idref&); + +public: + const type* + operator-> () const; + + type* + operator-> (); + + const type& + operator* () const; + + type& + operator* (); + + const type* + get () const; + + type* + get (); + + // Conversion to bool. + // +public: + typedef void (idref::*bool_convertible)(); + operator bool_convertible () const; +}; + </pre> + + <p>The object, <code>idref</code> instance refers to, is the immediate + container of the matching <code>id</code> instance. For example, + with the following instance document and schema: + </p> + + + <pre class="xml"> +<!-- test.xml --> +<root> + <object id="obj-1" text="hello"/> + <reference>obj-1</reference> +</root> + +<!-- test.xsd --> +<schema> + <complexType name="object_type"> + <attribute name="id" type="ID"/> + <attribute name="text" type="string"/> + </complexType> + + <complexType name="root_type"> + <sequence> + <element name="object" type="object_type"/> + <element name="reference" type="IDREF"/> + </sequence> + </complexType> + + <element name="root" type="root_type"/> +</schema> + </pre> + + <p>The <code>ref</code> instance in the code below will refer to + an object of type <code>object_type</code>:</p> + + <pre class="c++"> +root_type& root = ...; +xml_schema::idref& ref (root.reference ()); +object_type& obj (dynamic_cast<object_type&> (*ref)); +cout << obj.text () << endl; + </pre> + + <p>The smart pointer interface of the <code>idref</code> class always + returns a pointer or reference to <code>xml_schema::type</code>. + This means that you will need to manually cast such pointer or + reference to its real (dynamic) type before you can use it (unless + all you need is the base interface provided by + <code>xml_schema::type</code>). As a special extension to the XML + Schema language, the mapping supports static typing of <code>idref</code> + references by employing the <code>refType</code> extension attribute. + The following example illustrates this mechanism: + </p> + + <pre class="xml"> +<!-- test.xsd --> +<schema + xmlns:xse="https://www.codesynthesis.com/xmlns/xml-schema-extension"> + + ... + + <element name="reference" type="IDREF" xse:refType="object_type"/> + + ... + +</schema> + </pre> + + <p>With this modification we do not need to do manual casting anymore: + </p> + + <pre class="c++"> +root_type& root = ...; +root_type::reference_type& ref (root.reference ()); +object_type& obj (*ref); +cout << ref->text () << endl; + </pre> + + + <h3><a name="2.5.6">2.5.6 Mapping for <code>base64Binary</code> and + <code>hexBinary</code></a></h3> + + <p>The XML Schema <code>base64Binary</code> and <code>hexBinary</code> + built-in data types are mapped to the + <code>xml_schema::base64_binary</code> and + <code>xml_schema::hex_binary</code> C++ classes, respectively. The + <code>base64_binary</code> and <code>hex_binary</code> classes + support a simple buffer abstraction by inheriting from the + <code>xml_schema::buffer</code> class: + </p> + + <pre class="c++"> +class bounds: public virtual exception +{ +public: + virtual const char* + what () const throw (); +}; + +class buffer +{ +public: + typedef std::size_t size_t; + +public: + buffer (size_t size = 0); + buffer (size_t size, size_t capacity); + buffer (const void* data, size_t size); + buffer (const void* data, size_t size, size_t capacity); + buffer (void* data, + size_t size, + size_t capacity, + bool assume_ownership); + +public: + buffer (const buffer&); + + buffer& + operator= (const buffer&); + + void + swap (buffer&); + +public: + size_t + capacity () const; + + bool + capacity (size_t); + +public: + size_t + size () const; + + bool + size (size_t); + +public: + const char* + data () const; + + char* + data (); + + const char* + begin () const; + + char* + begin (); + + const char* + end () const; + + char* + end (); +}; + </pre> + + <p>The last overloaded constructor reuses an existing data buffer instead + of making a copy. If the <code>assume_ownership</code> argument is + <code>true</code>, the instance assumes ownership of the + memory block pointed to by the <code>data</code> argument and will + eventually release it by calling <code>operator delete</code>. The + <code>capacity</code> and <code>size</code> modifier functions return + <code>true</code> if the underlying buffer has moved. + </p> + + <p>The <code>bounds</code> exception is thrown if the constructor + arguments violate the <code>(size <= capacity)</code> + constraint.</p> + + <p>The <code>base64_binary</code> and <code>hex_binary</code> classes + support the <code>buffer</code> interface and perform automatic + decoding/encoding from/to the Base64 and Hex formats, respectively: + </p> + + <pre class="c++"> +class base64_binary: public simple_type, public buffer +{ +public: + base64_binary (size_t size = 0); + base64_binary (size_t size, size_t capacity); + base64_binary (const void* data, size_t size); + base64_binary (const void* data, size_t size, size_t capacity); + base64_binary (void* data, + size_t size, + size_t capacity, + bool assume_ownership); + +public: + base64_binary (const base64_binary&); + + base64_binary& + operator= (const base64_binary&); + + virtual base64_binary* + _clone () const; + +public: + std::basic_string<C> + encode () const; +}; + </pre> + + <pre class="c++"> +class hex_binary: public simple_type, public buffer +{ +public: + hex_binary (size_t size = 0); + hex_binary (size_t size, size_t capacity); + hex_binary (const void* data, size_t size); + hex_binary (const void* data, size_t size, size_t capacity); + hex_binary (void* data, + size_t size, + size_t capacity, + bool assume_ownership); + +public: + hex_binary (const hex_binary&); + + hex_binary& + operator= (const hex_binary&); + + virtual hex_binary* + _clone () const; + +public: + std::basic_string<C> + encode () const; +}; + </pre> + + + <h2><a name="2.5.7">2.5.7 Time Zone Representation</a></h2> + + <p>The <code>date</code>, <code>dateTime</code>, <code>gDay</code>, + <code>gMonth</code>, <code>gMonthDay</code>, <code>gYear</code>, + <code>gYearMonth</code>, and <code>time</code> XML Schema built-in + types all include an optional time zone component. The following + <code>xml_schema::time_zone</code> base class is used to represent + this information:</p> + + <pre class="c++"> +class time_zone +{ +public: + time_zone (); + time_zone (short hours, short minutes); + + bool + zone_present () const; + + void + zone_reset (); + + short + zone_hours () const; + + void + zone_hours (short); + + short + zone_minutes () const; + + void + zone_minutes (short); +}; + +bool +operator== (const time_zone&, const time_zone&); + +bool +operator!= (const time_zone&, const time_zone&); + </pre> + + <p>The <code>zone_present()</code> accessor function returns <code>true</code> + if the time zone is specified. The <code>zone_reset()</code> modifier + function resets the time zone object to the <em>not specified</em> + state. If the time zone offset is negative then both hours and + minutes components are represented as negative integers.</p> + + + <h2><a name="2.5.8">2.5.8 Mapping for <code>date</code></a></h2> + + <p>The XML Schema <code>date</code> built-in data type is mapped to the + <code>xml_schema::date</code> C++ class which represents a year, a day, + and a month with an optional time zone. Its interface is presented + below. For more information on the base <code>xml_schema::time_zone</code> + class refer to <a href="#2.5.7">Section 2.5.7, "Time Zone + Representation"</a>.</p> + + <pre class="c++"> +class date: public simple_type, public time_zone +{ +public: + date (int year, unsigned short month, unsigned short day); + date (int year, unsigned short month, unsigned short day, + short zone_hours, short zone_minutes); + +public: + date (const date&); + + date& + operator= (const date&); + + virtual date* + _clone () const; + +public: + int + year () const; + + void + year (int); + + unsigned short + month () const; + + void + month (unsigned short); + + unsigned short + day () const; + + void + day (unsigned short); +}; + +bool +operator== (const date&, const date&); + +bool +operator!= (const date&, const date&); + </pre> + + <h2><a name="2.5.9">2.5.9 Mapping for <code>dateTime</code></a></h2> + + <p>The XML Schema <code>dateTime</code> built-in data type is mapped to the + <code>xml_schema::date_time</code> C++ class which represents a year, a month, + a day, hours, minutes, and seconds with an optional time zone. Its interface + is presented below. For more information on the base + <code>xml_schema::time_zone</code> class refer to <a href="#2.5.7">Section + 2.5.7, "Time Zone Representation"</a>.</p> + + <pre class="c++"> +class date_time: public simple_type, public time_zone +{ +public: + date_time (int year, unsigned short month, unsigned short day, + unsigned short hours, unsigned short minutes, + double seconds); + + date_time (int year, unsigned short month, unsigned short day, + unsigned short hours, unsigned short minutes, + double seconds, short zone_hours, short zone_minutes); +public: + date_time (const date_time&); + + date_time& + operator= (const date_time&); + + virtual date_time* + _clone () const; + +public: + int + year () const; + + void + year (int); + + unsigned short + month () const; + + void + month (unsigned short); + + unsigned short + day () const; + + void + day (unsigned short); + + unsigned short + hours () const; + + void + hours (unsigned short); + + unsigned short + minutes () const; + + void + minutes (unsigned short); + + double + seconds () const; + + void + seconds (double); +}; + +bool +operator== (const date_time&, const date_time&); + +bool +operator!= (const date_time&, const date_time&); + </pre> + + + <h2><a name="2.5.10">2.5.10 Mapping for <code>duration</code></a></h2> + + <p>The XML Schema <code>duration</code> built-in data type is mapped to the + <code>xml_schema::duration</code> C++ class which represents a potentially + negative duration in the form of years, months, days, hours, minutes, + and seconds. Its interface is presented below.</p> + + <pre class="c++"> +class duration: public simple_type +{ +public: + duration (bool negative, + unsigned int years, unsigned int months, unsigned int days, + unsigned int hours, unsigned int minutes, double seconds); +public: + duration (const duration&); + + duration& + operator= (const duration&); + + virtual duration* + _clone () const; + +public: + bool + negative () const; + + void + negative (bool); + + unsigned int + years () const; + + void + years (unsigned int); + + unsigned int + months () const; + + void + months (unsigned int); + + unsigned int + days () const; + + void + days (unsigned int); + + unsigned int + hours () const; + + void + hours (unsigned int); + + unsigned int + minutes () const; + + void + minutes (unsigned int); + + double + seconds () const; + + void + seconds (double); +}; + +bool +operator== (const duration&, const duration&); + +bool +operator!= (const duration&, const duration&); + </pre> + + + <h2><a name="2.5.11">2.5.11 Mapping for <code>gDay</code></a></h2> + + <p>The XML Schema <code>gDay</code> built-in data type is mapped to the + <code>xml_schema::gday</code> C++ class which represents a day of the + month with an optional time zone. Its interface is presented below. + For more information on the base <code>xml_schema::time_zone</code> + class refer to <a href="#2.5.7">Section 2.5.7, "Time Zone + Representation"</a>.</p> + + <pre class="c++"> +class gday: public simple_type, public time_zone +{ +public: + explicit + gday (unsigned short day); + gday (unsigned short day, short zone_hours, short zone_minutes); + +public: + gday (const gday&); + + gday& + operator= (const gday&); + + virtual gday* + _clone () const; + +public: + unsigned short + day () const; + + void + day (unsigned short); +}; + +bool +operator== (const gday&, const gday&); + +bool +operator!= (const gday&, const gday&); + </pre> + + + <h2><a name="2.5.12">2.5.12 Mapping for <code>gMonth</code></a></h2> + + <p>The XML Schema <code>gMonth</code> built-in data type is mapped to the + <code>xml_schema::gmonth</code> C++ class which represents a month of the + year with an optional time zone. Its interface is presented below. + For more information on the base <code>xml_schema::time_zone</code> + class refer to <a href="#2.5.7">Section 2.5.7, "Time Zone + Representation"</a>.</p> + + <pre class="c++"> +class gmonth: public simple_type, public time_zone +{ +public: + explicit + gmonth (unsigned short month); + gmonth (unsigned short month, + short zone_hours, short zone_minutes); + +public: + gmonth (const gmonth&); + + gmonth& + operator= (const gmonth&); + + virtual gmonth* + _clone () const; + +public: + unsigned short + month () const; + + void + month (unsigned short); +}; + +bool +operator== (const gmonth&, const gmonth&); + +bool +operator!= (const gmonth&, const gmonth&); + </pre> + + + <h2><a name="2.5.13">2.5.13 Mapping for <code>gMonthDay</code></a></h2> + + <p>The XML Schema <code>gMonthDay</code> built-in data type is mapped to the + <code>xml_schema::gmonth_day</code> C++ class which represents a day and + a month of the year with an optional time zone. Its interface is presented + below. For more information on the base <code>xml_schema::time_zone</code> + class refer to <a href="#2.5.7">Section 2.5.7, "Time Zone + Representation"</a>.</p> + + <pre class="c++"> +class gmonth_day: public simple_type, public time_zone +{ +public: + gmonth_day (unsigned short month, unsigned short day); + gmonth_day (unsigned short month, unsigned short day, + short zone_hours, short zone_minutes); + +public: + gmonth_day (const gmonth_day&); + + gmonth_day& + operator= (const gmonth_day&); + + virtual gmonth_day* + _clone () const; + +public: + unsigned short + month () const; + + void + month (unsigned short); + + unsigned short + day () const; + + void + day (unsigned short); +}; + +bool +operator== (const gmonth_day&, const gmonth_day&); + +bool +operator!= (const gmonth_day&, const gmonth_day&); + </pre> + + + <h2><a name="2.5.14">2.5.14 Mapping for <code>gYear</code></a></h2> + + <p>The XML Schema <code>gYear</code> built-in data type is mapped to the + <code>xml_schema::gyear</code> C++ class which represents a year with + an optional time zone. Its interface is presented below. For more + information on the base <code>xml_schema::time_zone</code> class refer + to <a href="#2.5.7">Section 2.5.7, "Time Zone Representation"</a>.</p> + + <pre class="c++"> +class gyear: public simple_type, public time_zone +{ +public: + explicit + gyear (int year); + gyear (int year, short zone_hours, short zone_minutes); + +public: + gyear (const gyear&); + + gyear& + operator= (const gyear&); + + virtual gyear* + _clone () const; + +public: + int + year () const; + + void + year (int); +}; + +bool +operator== (const gyear&, const gyear&); + +bool +operator!= (const gyear&, const gyear&); + </pre> + + + <h2><a name="2.5.15">2.5.15 Mapping for <code>gYearMonth</code></a></h2> + + <p>The XML Schema <code>gYearMonth</code> built-in data type is mapped to + the <code>xml_schema::gyear_month</code> C++ class which represents + a year and a month with an optional time zone. Its interface is presented + below. For more information on the base <code>xml_schema::time_zone</code> + class refer to <a href="#2.5.7">Section 2.5.7, "Time Zone + Representation"</a>.</p> + + <pre class="c++"> +class gyear_month: public simple_type, public time_zone +{ +public: + gyear_month (int year, unsigned short month); + gyear_month (int year, unsigned short month, + short zone_hours, short zone_minutes); +public: + gyear_month (const gyear_month&); + + gyear_month& + operator= (const gyear_month&); + + virtual gyear_month* + _clone () const; + +public: + int + year () const; + + void + year (int); + + unsigned short + month () const; + + void + month (unsigned short); +}; + +bool +operator== (const gyear_month&, const gyear_month&); + +bool +operator!= (const gyear_month&, const gyear_month&); + </pre> + + + <h2><a name="2.5.16">2.5.16 Mapping for <code>time</code></a></h2> + + <p>The XML Schema <code>time</code> built-in data type is mapped to + the <code>xml_schema::time</code> C++ class which represents hours, + minutes, and seconds with an optional time zone. Its interface is + presented below. For more information on the base + <code>xml_schema::time_zone</code> class refer to + <a href="#2.5.7">Section 2.5.7, "Time Zone Representation"</a>.</p> + + <pre class="c++"> +class time: public simple_type, public time_zone +{ +public: + time (unsigned short hours, unsigned short minutes, double seconds); + time (unsigned short hours, unsigned short minutes, double seconds, + short zone_hours, short zone_minutes); + +public: + time (const time&); + + time& + operator= (const time&); + + virtual time* + _clone () const; + +public: + unsigned short + hours () const; + + void + hours (unsigned short); + + unsigned short + minutes () const; + + void + minutes (unsigned short); + + double + seconds () const; + + void + seconds (double); +}; + +bool +operator== (const time&, const time&); + +bool +operator!= (const time&, const time&); + </pre> + + + <!-- Mapping for Simple Types --> + + <h2><a name="2.6">2.6 Mapping for Simple Types</a></h2> + + <p>An XML Schema simple type is mapped to a C++ class with the same + name as the simple type. The class defines a public copy constructor, + a public copy assignment operator, and a public virtual + <code>_clone</code> function. The <code>_clone</code> function is + declared <code>const</code>, does not take any arguments, and returns + a pointer to a complete copy of the instance allocated in the free + store. The <code>_clone</code> function shall be used to make copies + when static type and dynamic type of the instance may differ (see + <a href="#2.11">Section 2.11, "Mapping for <code>xsi:type</code> + and Substitution Groups"</a>). For instance:</p> + + <pre class="xml"> +<simpleType name="object"> + ... +</simpleType> + </pre> + + <p>is mapped to:</p> + + <pre class="c++"> +class object: ... +{ +public: + object (const object&); + +public: + object& + operator= (const object&); + +public: + virtual object* + _clone () const; + + ... + +}; + </pre> + + <p>The base class specification and the rest of the class definition + depend on the type of derivation used to define the simple type. </p> + + + <h3><a name="2.6.1">2.6.1 Mapping for Derivation by Restriction</a></h3> + + <p>XML Schema derivation by restriction is mapped to C++ public + inheritance. The base type of the restriction becomes the base + type for the resulting C++ class. In addition to the members described + in <a href="#2.6">Section 2.6, "Mapping for Simple Types"</a>, the + resulting C++ class defines a public constructor with the base type + as its single argument. For instance:</p> + + <pre class="xml"> +<simpleType name="object"> + <restriction base="base"> + ... + </restriction> +</simpleType> + </pre> + + <p>is mapped to:</p> + + <pre class="c++"> +class object: public base +{ +public: + object (const base&); + object (const object&); + +public: + object& + operator= (const object&); + +public: + virtual object* + _clone () const; +}; + </pre> + + + <h3><a name="2.6.2">2.6.2 Mapping for Enumerations</a></h3> + +<p>XML Schema restriction by enumeration is mapped to a C++ class + with semantics similar to C++ <code>enum</code>. Each XML Schema + enumeration element is mapped to a C++ enumerator with the + name derived from the <code>value</code> attribute and defined + in the class scope. In addition to the members + described in <a href="#2.6">Section 2.6, "Mapping for Simple Types"</a>, + the resulting C++ class defines a public constructor that can be called + with one of the enumerators as its single argument, a public constructor + that can be called with enumeration's base value as its single + argument, a public assignment operator that can be used to assign the + value of one of the enumerators, and a public implicit conversion + operator to the underlying C++ enum type.</p> + +<p>Furthermore, for string-based enumeration types, the resulting C++ + class defines a public constructor with a single argument of type + <code>const C*</code> and a public constructor with a single + argument of type <code>const std::basic_string<C>&</code>. + For instance:</p> + + <pre class="xml"> +<simpleType name="color"> + <restriction base="string"> + <enumeration value="red"/> + <enumeration value="green"/> + <enumeration value="blue"/> + </restriction> +</simpleType> + </pre> + + <p>is mapped to:</p> + + <pre class="c++"> +class color: public xml_schema::string +{ +public: + enum value + { + red, + green, + blue + }; + +public: + color (value); + color (const C*); + color (const std::basic_string<C>&); + color (const xml_schema::string&); + color (const color&); + +public: + color& + operator= (value); + + color& + operator= (const color&); + +public: + virtual color* + _clone () const; + +public: + operator value () const; +}; + </pre> + + <h3><a name="2.6.3">2.6.3 Mapping for Derivation by List</a></h3> + + <p>XML Schema derivation by list is mapped to C++ public + inheritance from <code>xml_schema::simple_type</code> + (<a href="#2.5.3">Section 2.5.3, "Mapping for + <code>anySimpleType</code>"</a>) and a suitable sequence type. + The list item type becomes the element type of the sequence. + In addition to the members described in <a href="#2.6">Section 2.6, + "Mapping for Simple Types"</a>, the resulting C++ class defines + a public default constructor, a public constructor + with the first argument of type <code>size_type</code> and + the second argument of list item type that creates + a list object with the specified number of copies of the specified + element value, and a public constructor with the two arguments + of an input iterator type that creates a list object from an + iterator range. For instance: + </p> + + <pre class="xml"> +<simpleType name="int_list"> + <list itemType="int"/> +</simpleType> + </pre> + + <p>is mapped to:</p> + + <pre class="c++"> +class int_list: public simple_type, + public sequence<int> +{ +public: + int_list (); + int_list (size_type n, int x); + + template <typename I> + int_list (const I& begin, const I& end); + int_list (const int_list&); + +public: + int_list& + operator= (const int_list&); + +public: + virtual int_list* + _clone () const; +}; + </pre> + + <p>The <code>sequence</code> class template is defined in an + implementation-specific namespace. It conforms to the + sequence interface as defined by the ISO/ANSI Standard for + C++ (ISO/IEC 14882:1998, Section 23.1.1, "Sequences"). + Practically, this means that you can treat such a sequence + as if it was <code>std::vector</code>. One notable extension + to the standard interface that is available only for + sequences of non-fundamental C++ types is the addition of + the overloaded <code>push_back</code> and <code>insert</code> + member functions which instead of the constant reference + to the element type accept automatic pointer (<code>std::unique_ptr</code> + or <code>std::auto_ptr</code>, depending on the C++ standard + selected) to the element type. These functions assume ownership + of the pointed to object and reset the passed automatic pointer. + </p> + + <h3><a name="2.6.4">2.6.4 Mapping for Derivation by Union</a></h3> + + <p>XML Schema derivation by union is mapped to C++ public + inheritance from <code>xml_schema::simple_type</code> + (<a href="#2.5.3">Section 2.5.3, "Mapping for + <code>anySimpleType</code>"</a>) and <code>std::basic_string<C></code>. + In addition to the members described in <a href="#2.6">Section 2.6, + "Mapping for Simple Types"</a>, the resulting C++ class defines a + public constructor with a single argument of type <code>const C*</code> + and a public constructor with a single argument of type + <code>const std::basic_string<C>&</code>. For instance: + </p> + + <pre class="xml"> +<simpleType name="int_string_union"> + <xsd:union memberTypes="xsd:int xsd:string"/> +</simpleType> + </pre> + + <p>is mapped to:</p> + + <pre class="c++"> +class int_string_union: public simple_type, + public std::basic_string<C> +{ +public: + int_string_union (const C*); + int_string_union (const std::basic_string<C>&); + int_string_union (const int_string_union&); + +public: + int_string_union& + operator= (const int_string_union&); + +public: + virtual int_string_union* + _clone () const; +}; + </pre> + + <h2><a name="2.7">2.7 Mapping for Complex Types</a></h2> + + <p>An XML Schema complex type is mapped to a C++ class with the same + name as the complex type. The class defines a public copy constructor, + a public copy assignment operator, and a public virtual + <code>_clone</code> function. The <code>_clone</code> function is + declared <code>const</code>, does not take any arguments, and returns + a pointer to a complete copy of the instance allocated in the free + store. The <code>_clone</code> function shall be used to make copies + when static type and dynamic type of the instance may differ (see + <a href="#2.11">Section 2.11, "Mapping for <code>xsi:type</code> + and Substitution Groups"</a>).</p> + + <p>Additionally, the resulting C++ class + defines two public constructors that take an initializer for each + member of the complex type and all its base types that belongs to + the One cardinality class (see <a href="#2.8">Section 2.8, "Mapping + for Local Elements and Attributes"</a>). In the first constructor, + the arguments are passed as constant references and the newly created + instance is initialized with copies of the passed objects. In the + second constructor, arguments that are complex types (that is, + they themselves contain elements or attributes) are passed as + either <code>std::unique_ptr</code> (C++11) or <code>std::auto_ptr</code> + (C++98), depending on the C++ standard selected. In this case the newly + created instance is directly initialized with and assumes ownership + of the pointed to objects and the <code>std::[unique|auto]_ptr</code> + arguments are reset to <code>0</code>. For instance:</p> + + <pre class="xml"> +<complexType name="complex"> + <sequence> + <element name="a" type="int"/> + <element name="b" type="string"/> + </sequence> +</complexType> + +<complexType name="object"> + <sequence> + <element name="s-one" type="boolean"/> + <element name="c-one" type="complex"/> + <element name="optional" type="int" minOccurs="0"/> + <element name="sequence" type="string" maxOccurs="unbounded"/> + </sequence> +</complexType> + </pre> + + <p>is mapped to:</p> + + <pre class="c++"> +class complex: public xml_schema::type +{ +public: + object (const int& a, const xml_schema::string& b); + object (const complex&); + +public: + object& + operator= (const complex&); + +public: + virtual complex* + _clone () const; + + ... + +}; + +class object: public xml_schema::type +{ +public: + object (const bool& s_one, const complex& c_one); + object (const bool& s_one, std::[unique|auto]_ptr<complex> c_one); + object (const object&); + +public: + object& + operator= (const object&); + +public: + virtual object* + _clone () const; + + ... + +}; + </pre> + + <p>Notice that the generated <code>complex</code> class does not + have the second (<code>std::[unique|auto]_ptr</code>) version of the + constructor since all its required members are of simple types.</p> + + <p>If an XML Schema complex type has an ultimate base which is an XML + Schema simple type then the resulting C++ class also defines a public + constructor that takes an initializer for the base type as well as + for each member of the complex type and all its base types that + belongs to the One cardinality class. For instance:</p> + + <pre class="xml"> +<complexType name="object"> + <simpleContent> + <extension base="date"> + <attribute name="lang" type="language" use="required"/> + </extension> + </simpleContent> +</complexType> + </pre> + + <p>is mapped to:</p> + + <pre class="c++"> +class object: public xml_schema::string +{ +public: + object (const xml_schema::language& lang); + + object (const xml_schema::date& base, + const xml_schema::language& lang); + + ... + +}; + </pre> + + <p>Furthermore, for string-based XML Schema complex types, the resulting C++ + class also defines two public constructors with the first arguments + of type <code>const C*</code> and <code>std::basic_string<C>&</code>, + respectively, followed by arguments for each member of the complex + type and all its base types that belongs to the One cardinality + class. For enumeration-based complex types the resulting C++ + class also defines a public constructor with the first arguments + of the underlying enum type followed by arguments for each member + of the complex type and all its base types that belongs to the One + cardinality class. For instance:</p> + + <pre class="xml"> +<simpleType name="color"> + <restriction base="string"> + <enumeration value="red"/> + <enumeration value="green"/> + <enumeration value="blue"/> + </restriction> +</simpleType> + +<complexType name="object"> + <simpleContent> + <extension base="color"> + <attribute name="lang" type="language" use="required"/> + </extension> + </simpleContent> +</complexType> + </pre> + + <p>is mapped to:</p> + + <pre class="c++"> +class color: public xml_schema::string +{ +public: + enum value + { + red, + green, + blue + }; + +public: + color (value); + color (const C*); + color (const std::basic_string<C>&); + + ... + +}; + +class object: color +{ +public: + object (const color& base, + const xml_schema::language& lang); + + object (const color::value& base, + const xml_schema::language& lang); + + object (const C* base, + const xml_schema::language& lang); + + object (const std::basic_string<C>& base, + const xml_schema::language& lang); + + ... + +}; + </pre> + + <p>Additional constructors can be requested with the + <code>--generate-default-ctor</code> and + <code>--generate-from-base-ctor</code> options. See the + <a href="https://www.codesynthesis.com/projects/xsd/documentation/xsd.xhtml">XSD + Compiler Command Line Manual</a> for details.</p> + + <p>If an XML Schema complex type is not explicitly derived from any type, + the resulting C++ class is derived from <code>xml_schema::type</code>. + In cases where an XML Schema complex type is defined using derivation + by extension or restriction, the resulting C++ base class specification + depends on the type of derivation and is described in the subsequent + sections. + </p> + + <p>The mapping for elements and attributes that are defined in a complex + type is described in <a href="#2.8">Section 2.8, "Mapping for Local + Elements and Attributes"</a>. + </p> + + <h3><a name="2.7.1">2.7.1 Mapping for Derivation by Extension</a></h3> + + <p>XML Schema derivation by extension is mapped to C++ public + inheritance. The base type of the extension becomes the base + type for the resulting C++ class. + </p> + + <h3><a name="2.7.2">2.7.2 Mapping for Derivation by Restriction</a></h3> + + <p>XML Schema derivation by restriction is mapped to C++ public + inheritance. The base type of the restriction becomes the base + type for the resulting C++ class. XML Schema elements and + attributes defined within restriction do not result in any + definitions in the resulting C++ class. Instead, corresponding + (unrestricted) definitions are inherited from the base class. + In the future versions of this mapping, such elements and + attributes may result in redefinitions of accessors and + modifiers to reflect their restricted semantics. + </p> + + <!-- 2.8 Mapping for Local Elements and Attributes --> + + <h2><a name="2.8">2.8 Mapping for Local Elements and Attributes</a></h2> + + <p>XML Schema element and attribute definitions are called local + if they appear within a complex type definition, an element group + definition, or an attribute group definitions. + </p> + + <p>Local XML Schema element and attribute definitions have the same + C++ mapping. Therefore, in this section, local elements and + attributes are collectively called members. + </p> + + <p>While there are many different member cardinality combinations + (determined by the <code>use</code> attribute for attributes and + the <code>minOccurs</code> and <code>maxOccurs</code> attributes + for elements), the mapping divides all possible cardinality + combinations into three cardinality classes: + </p> + + <dl> + <dt><i>one</i></dt> + <dd>attributes: <code>use == "required"</code></dd> + <dd>attributes: <code>use == "optional"</code> and has default or fixed value</dd> + <dd>elements: <code>minOccurs == "1"</code> and <code>maxOccurs == "1"</code></dd> + + <dt><i>optional</i></dt> + <dd>attributes: <code>use == "optional"</code> and doesn't have default or fixed value</dd> + <dd>elements: <code>minOccurs == "0"</code> and <code>maxOccurs == "1"</code></dd> + + <dt><i>sequence</i></dt> + <dd>elements: <code>maxOccurs > "1"</code></dd> + </dl> + + <p>An optional attribute with a default or fixed value acquires this value + if the attribute hasn't been specified in an instance document (see + <a href="#A">Appendix A, "Default and Fixed Values"</a>). This + mapping places such optional attributes to the One cardinality + class.</p> + + <p>A member is mapped to a set of public type definitions + (<code>typedef</code>s) and a set of public accessor and modifier + functions. Type definitions have names derived from the member's + name. The accessor and modifier functions have the same name as the + member. For example: + </p> + + <pre class="xml"> +<complexType name="object"> + <sequence> + <element name="member" type="string"/> + </sequence> +</complexType> + </pre> + + <p>is mapped to:</p> + + <pre class="c++"> +class object: public xml_schema::type +{ +public: + typedef xml_schema::string member_type; + + const member_type& + member () const; + + ... + +}; + </pre> + + <p>In addition, if a member has a default or fixed value, a static + accessor function is generated that returns this value. For + example:</p> + +<pre class="xml"> +<complexType name="object"> + <attribute name="data" type="string" default="test"/> +</complexType> + </pre> + + <p>is mapped to:</p> + + <pre class="c++"> +class object: public xml_schema::type +{ +public: + typedef xml_schema::string data_type; + + const data_type& + data () const; + + static const data_type& + data_default_value (); + + ... + +}; + </pre> + + <p>Names and semantics of type definitions for the member as well + as signatures of the accessor and modifier functions depend on + the member's cardinality class and are described in the following + sub-sections. + </p> + + + <h3><a name="2.8.1">2.8.1 Mapping for Members with the One Cardinality Class</a></h3> + + <p>For the One cardinality class, the type definitions consist of + an alias for the member's type with the name created by appending + the <code>_type</code> suffix to the member's name. + </p> + + <p>The accessor functions come in constant and non-constant versions. + The constant accessor function returns a constant reference to the + member and can be used for read-only access. The non-constant + version returns an unrestricted reference to the member and can + be used for read-write access. + </p> + + <p>The first modifier function expects an argument of type reference to + constant of the member's type. It makes a deep copy of its argument. + Except for member's types that are mapped to fundamental C++ types, + the second modifier function is provided that expects an argument + of type automatic pointer (<code>std::unique_ptr</code> or + <code>std::auto_ptr</code>, depending on the C++ standard selected) + to the member's type. It assumes ownership of the pointed to object + and resets the passed automatic pointer. For instance:</p> + + <pre class="xml"> +<complexType name="object"> + <sequence> + <element name="member" type="string"/> + </sequence> +</complexType> + </pre> + + <p>is mapped to:</p> + + <pre class="c++"> +class object: public xml_schema::type +{ +public: + // Type definitions. + // + typedef xml_schema::string member_type; + + // Accessors. + // + const member_type& + member () const; + + member_type& + member (); + + // Modifiers. + // + void + member (const member_type&); + + void + member (std::[unique|auto]_ptr<member_type>); + ... + +}; + </pre> + + <p>In addition, if requested by specifying the <code>--generate-detach</code> + option and only for members of non-fundamental C++ types, the mapping + provides a detach function that returns an automatic pointer to the + member's type, for example:</p> + + <pre class="c++"> +class object: public xml_schema::type +{ +public: + ... + + std::[unique|auto]_ptr<member_type> + detach_member (); + ... + +}; + </pre> + + <p>This function detaches the value from the tree leaving the member + value uninitialized. Accessing such an uninitialized value prior to + re-initializing it results in undefined behavior.</p> + + <p>The following code shows how one could use this mapping:</p> + + <pre class="c++"> +void +f (object& o) +{ + using xml_schema::string; + + string s (o.member ()); // get + object::member_type& sr (o.member ()); // get + + o.member ("hello"); // set, deep copy + o.member () = "hello"; // set, deep copy + + // C++11 version. + // + std::unique_ptr<string> p (new string ("hello")); + o.member (std::move (p)); // set, assumes ownership + p = o.detach_member (); // detach, member is uninitialized + o.member (std::move (p)); // re-attach + + // C++98 version. + // + std::auto_ptr<string> p (new string ("hello")); + o.member (p); // set, assumes ownership + p = o.detach_member (); // detach, member is uninitialized + o.member (p); // re-attach +} + </pre> + + +<h3><a name="2.8.2">2.8.2 Mapping for Members with the Optional Cardinality Class</a></h3> + + <p>For the Optional cardinality class, the type definitions consist of + an alias for the member's type with the name created by appending + the <code>_type</code> suffix to the member's name and an alias for + the container type with the name created by appending the + <code>_optional</code> suffix to the member's name. + </p> + + <p>Unlike accessor functions for the One cardinality class, accessor + functions for the Optional cardinality class return references to + corresponding containers rather than directly to members. The + accessor functions come in constant and non-constant versions. + The constant accessor function returns a constant reference to + the container and can be used for read-only access. The non-constant + version returns an unrestricted reference to the container + and can be used for read-write access. + </p> + + <p>The modifier functions are overloaded for the member's + type and the container type. The first modifier function + expects an argument of type reference to constant of the + member's type. It makes a deep copy of its argument. + Except for member's types that are mapped to fundamental C++ types, + the second modifier function is provided that expects an argument + of type automatic pointer (<code>std::unique_ptr</code> or + <code>std::auto_ptr</code>, depending on the C++ standard selected) + to the member's type. It assumes ownership of the pointed to object + and resets the passed automatic pointer. The last modifier function + expects an argument of type reference to constant of the container + type. It makes a deep copy of its argument. For instance: + </p> + + <pre class="xml"> +<complexType name="object"> + <sequence> + <element name="member" type="string" minOccurs="0"/> + </sequence> +</complexType> + </pre> + + <p>is mapped to:</p> + + <pre class="c++"> +class object: public xml_schema::type +{ +public: + // Type definitions. + // + typedef xml_schema::string member_type; + typedef optional<member_type> member_optional; + + // Accessors. + // + const member_optional& + member () const; + + member_optional& + member (); + + // Modifiers. + // + void + member (const member_type&); + + void + member (std::[unique|auto]_ptr<member_type>); + + void + member (const member_optional&); + + ... + +}; + </pre> + + + <p>The <code>optional</code> class template is defined in an + implementation-specific namespace and has the following + interface. The <code>[unique|auto]_ptr</code>-based constructor + and modifier function are only available if the template + argument is not a fundamental C++ type. + </p> + + <pre class="c++"> +template <typename X> +class optional +{ +public: + optional (); + + // Makes a deep copy. + // + explicit + optional (const X&); + + // Assumes ownership. + // + explicit + optional (std::[unique|auto]_ptr<X>); + + optional (const optional&); + +public: + optional& + operator= (const X&); + + optional& + operator= (const optional&); + + // Pointer-like interface. + // +public: + const X* + operator-> () const; + + X* + operator-> (); + + const X& + operator* () const; + + X& + operator* (); + + typedef void (optional::*bool_convertible) (); + operator bool_convertible () const; + + // Get/set interface. + // +public: + bool + present () const; + + const X& + get () const; + + X& + get (); + + // Makes a deep copy. + // + void + set (const X&); + + // Assumes ownership. + // + void + set (std::[unique|auto]_ptr<X>); + + // Detach and return the contained value. + // + std::[unique|auto]_ptr<X> + detach (); + + void + reset (); +}; + +template <typename X> +bool +operator== (const optional<X>&, const optional<X>&); + +template <typename X> +bool +operator!= (const optional<X>&, const optional<X>&); + +template <typename X> +bool +operator< (const optional<X>&, const optional<X>&); + +template <typename X> +bool +operator> (const optional<X>&, const optional<X>&); + +template <typename X> +bool +operator<= (const optional<X>&, const optional<X>&); + +template <typename X> +bool +operator>= (const optional<X>&, const optional<X>&); + </pre> + + + <p>The following code shows how one could use this mapping:</p> + + <pre class="c++"> +void +f (object& o) +{ + using xml_schema::string; + + if (o.member ().present ()) // test + { + string& s (o.member ().get ()); // get + o.member ("hello"); // set, deep copy + o.member ().set ("hello"); // set, deep copy + o.member ().reset (); // reset + } + + // Same as above but using pointer notation: + // + if (o.member ()) // test + { + string& s (*o.member ()); // get + o.member ("hello"); // set, deep copy + *o.member () = "hello"; // set, deep copy + o.member ().reset (); // reset + } + + // C++11 version. + // + std::unique_ptr<string> p (new string ("hello")); + o.member (std::move (p)); // set, assumes ownership + + p.reset (new string ("hello")); + o.member ().set (std::move (p)); // set, assumes ownership + + p = o.member ().detach (); // detach, member is reset + o.member ().set (std::move (p)); // re-attach + + // C++98 version. + // + std::auto_ptr<string> p (new string ("hello")); + o.member (p); // set, assumes ownership + + p = new string ("hello"); + o.member ().set (p); // set, assumes ownership + + p = o.member ().detach (); // detach, member is reset + o.member ().set (p); // re-attach +} + </pre> + + + <h3><a name="2.8.3">2.8.3 Mapping for Members with the Sequence Cardinality Class</a></h3> + + <p>For the Sequence cardinality class, the type definitions consist of an + alias for the member's type with the name created by appending + the <code>_type</code> suffix to the member's name, an alias of + the container type with the name created by appending the + <code>_sequence</code> suffix to the member's name, an alias of + the iterator type with the name created by appending the + <code>_iterator</code> suffix to the member's name, and an alias + of the constant iterator type with the name created by appending the + <code>_const_iterator</code> suffix to the member's name. + </p> + + <p>The accessor functions come in constant and non-constant versions. + The constant accessor function returns a constant reference to the + container and can be used for read-only access. The non-constant + version returns an unrestricted reference to the container and can + be used for read-write access. + </p> + + <p>The modifier function expects an argument of type reference to + constant of the container type. The modifier function + makes a deep copy of its argument. For instance: + </p> + + + <pre class="xml"> +<complexType name="object"> + <sequence> + <element name="member" type="string" minOccurs="unbounded"/> + </sequence> +</complexType> + </pre> + + <p>is mapped to:</p> + + <pre class="c++"> +class object: public xml_schema::type +{ +public: + // Type definitions. + // + typedef xml_schema::string member_type; + typedef sequence<member_type> member_sequence; + typedef member_sequence::iterator member_iterator; + typedef member_sequence::const_iterator member_const_iterator; + + // Accessors. + // + const member_sequence& + member () const; + + member_sequence& + member (); + + // Modifier. + // + void + member (const member_sequence&); + + ... + +}; + </pre> + + <p>The <code>sequence</code> class template is defined in an + implementation-specific namespace. It conforms to the + sequence interface as defined by the ISO/ANSI Standard for + C++ (ISO/IEC 14882:1998, Section 23.1.1, "Sequences"). + Practically, this means that you can treat such a sequence + as if it was <code>std::vector</code>. Two notable extensions + to the standard interface that are available only for + sequences of non-fundamental C++ types are the addition of + the overloaded <code>push_back</code> and <code>insert</code> + as well as the <code>detach_back</code> and <code>detach</code> + member functions. The additional <code>push_back</code> and + <code>insert</code> functions accept an automatic pointer + (<code>std::unique_ptr</code> or <code>std::auto_ptr</code>, + depending on the C++ standard selected) to the + element type instead of the constant reference. They assume + ownership of the pointed to object and reset the passed + automatic pointer. The <code>detach_back</code> and + <code>detach</code> functions detach the element + value from the sequence container and, by default, remove + the element from the sequence. These additional functions + have the following signatures:</p> + + <pre class="c++"> +template <typename X> +class sequence +{ +public: + ... + + void + push_back (std::[unique|auto]_ptr<X>) + + iterator + insert (iterator position, std::[unique|auto]_ptr<X>) + + std::[unique|auto]_ptr<X> + detach_back (bool pop = true); + + iterator + detach (iterator position, + std::[unique|auto]_ptr<X>& result, + bool erase = true) + + ... +} + </pre> + + <p>The following code shows how one could use this mapping:</p> + + <pre class="c++"> +void +f (object& o) +{ + using xml_schema::string; + + object::member_sequence& s (o.member ()); + + // Iteration. + // + for (object::member_iterator i (s.begin ()); i != s.end (); ++i) + { + string& value (*i); + } + + // Modification. + // + s.push_back ("hello"); // deep copy + + // C++11 version. + // + std::unique_ptr<string> p (new string ("hello")); + s.push_back (std::move (p)); // assumes ownership + p = s.detach_back (); // detach and pop + s.push_back (std::move (p)); // re-append + + // C++98 version. + // + std::auto_ptr<string> p (new string ("hello")); + s.push_back (p); // assumes ownership + p = s.detach_back (); // detach and pop + s.push_back (p); // re-append + + // Setting a new container. + // + object::member_sequence n; + n.push_back ("one"); + n.push_back ("two"); + o.member (n); // deep copy +} + </pre> + + <h3><a name="2.8.4">2.8.4 Element Order</a></h3> + + <p>C++/Tree is a "flattening" mapping in a sense that many levels of + nested compositors (<code>choice</code> and <code>sequence</code>), + all potentially with their own cardinalities, are in the end mapped + to a flat set of elements with one of the three cardinality classes + discussed in the previous sections. While this results in a simple + and easy to use API for most types, in certain cases, the order of + elements in the actual XML documents is not preserved once parsed + into the object model. And sometimes such order has + application-specific significance. As an example, consider a schema + that defines a batch of bank transactions:</p> + + <pre class="xml"> +<complexType name="withdraw"> + <sequence> + <element name="account" type="unsignedInt"/> + <element name="amount" type="unsignedInt"/> + </sequence> +</complexType> + +<complexType name="deposit"> + <sequence> + <element name="account" type="unsignedInt"/> + <element name="amount" type="unsignedInt"/> + </sequence> +</complexType> + +<complexType name="batch"> + <choice minOccurs="0" maxOccurs="unbounded"> + <element name="withdraw" type="withdraw"/> + <element name="deposit" type="deposit"/> + </choice> +</complexType> + </pre> + + <p>The batch can contain any number of transactions in any order + but the order of transactions in each actual batch is significant. + For instance, consider what could happen if we reorder the + transactions and apply all the withdrawals before deposits.</p> + + <p>For the <code>batch</code> schema type defined above the default + C++/Tree mapping will produce a C++ class that contains a pair of + sequence containers, one for each of the two elements. While this + will capture the content (transactions), the order of this content + as it appears in XML will be lost. Also, if we try to serialize the + batch we just loaded back to XML, all the withdrawal transactions + will appear before deposits.</p> + + <p>To overcome this limitation of a flattening mapping, C++/Tree + allows us to mark certain XML Schema types, for which content + order is important, as ordered.</p> + + <p>There are several command line options that control which + schema types are treated as ordered. To make an individual + type ordered, we use the <code>--ordered-type</code> option, + for example:</p> + + <pre class="term"> +--ordered-type batch + </pre> + + <p>To automatically treat all the types that are derived from an ordered + type also ordered, we use the <code>--ordered-type-derived</code> + option. This is primarily useful if you would like to iterate + over the complete hierarchy's content using the content order + sequence (discussed below).</p> + + <p>Ordered types are also useful for handling mixed content. To + automatically mark all the types with mixed content as ordered + we use the <code>--ordered-type-mixed</code> option. For more + information on handling mixed content see <a href="#2.13">Section + 2.13, "Mapping for Mixed Content Models"</a>.</p> + + <p>Finally, we can mark all the types in the schema we are + compiling with the <code>--ordered-type-all</code> option. + You should only resort to this option if all the types in + your schema truly suffer from the loss of content + order since, as we will discuss shortly, ordered types + require extra effort to access and, especially, modify. + See the + <a href="https://www.codesynthesis.com/projects/xsd/documentation/xsd.xhtml">XSD + Compiler Command Line Manual</a> for more information on + these options.</p> + + <p>Once a type is marked ordered, C++/Tree alters its mapping + in several ways. Firstly, for each local element, element + wildcard (<a href="#2.12.4">Section 2.12.4, "Element Wildcard + Order"</a>), and mixed content text (<a href="#2.13">Section + 2.13, "Mapping for Mixed Content Models"</a>) in this type, a + content id constant is generated. Secondly, an addition sequence + is added to the class that captures the content order. Here + is how the mapping of our <code>batch</code> class changes + once we make it ordered:</p> + + <pre class="c++"> +class batch: public xml_schema::type +{ +public: + // withdraw + // + typedef withdraw withdraw_type; + typedef sequence<withdraw_type> withdraw_sequence; + typedef withdraw_sequence::iterator withdraw_iterator; + typedef withdraw_sequence::const_iterator withdraw_const_iterator; + + static const std::size_t withdraw_id = 1; + + const withdraw_sequence& + withdraw () const; + + withdraw_sequence& + withdraw (); + + void + withdraw (const withdraw_sequence&); + + // deposit + // + typedef deposit deposit_type; + typedef sequence<deposit_type> deposit_sequence; + typedef deposit_sequence::iterator deposit_iterator; + typedef deposit_sequence::const_iterator deposit_const_iterator; + + static const std::size_t deposit_id = 2; + + const deposit_sequence& + deposit () const; + + deposit_sequence& + deposit (); + + void + deposit (const deposit_sequence&); + + // content_order + // + typedef xml_schema::content_order content_order_type; + typedef std::vector<content_order_type> content_order_sequence; + typedef content_order_sequence::iterator content_order_iterator; + typedef content_order_sequence::const_iterator content_order_const_iterator; + + const content_order_sequence& + content_order () const; + + content_order_sequence& + content_order (); + + void + content_order (const content_order_sequence&); + + ... +}; + </pre> + + <p>Notice the <code>withdraw_id</code> and <code>deposit_id</code> + content ids as well as the extra <code>content_order</code> + sequence that does not correspond to any element in the + schema definition. The other changes to the mapping for ordered + types has to do with XML parsing and serialization code. During + parsing the content order is captured in the <code>content_order</code> + sequence while during serialization this sequence is used to + determine the order in which content is serialized. The + <code>content_order</code> sequence is also copied during + copy construction and assigned during copy assignment. It is also + taken into account during comparison.</p> + + <p>The entry type of the <code>content_order</code> sequence is the + <code>xml_schema::content_order</code> type that has the following + interface:</p> + + <pre class="c++"> +namespace xml_schema +{ + struct content_order + { + content_order (std::size_t id, std::size_t index = 0); + + std::size_t id; + std::size_t index; + }; + + bool + operator== (const content_order&, const content_order&); + + bool + operator!= (const content_order&, const content_order&); + + bool + operator< (const content_order&, const content_order&); +} + </pre> + + <p>The <code>content_order</code> sequence describes the order of + content (elements, including wildcards, as well as mixed content + text). Each entry in this sequence consists of the content id + (for example, <code>withdraw_id</code> or <code>deposit_id</code> + in our case) as well as, for elements of the sequence cardinality + class, an index into the corresponding sequence container (the + index is unused for the one and optional cardinality classes). + For example, in our case, if the content id is <code>withdraw_id</code>, + then the index will point into the <code>withdraw</code> element + sequence.</p> + + <p>With all this information we can now examine how to iterate over + transaction in the batch in content order:</p> + + <pre class="c++"> +batch& b = ... + +for (batch::content_order_const_iterator i (b.content_order ().begin ()); + i != b.content_order ().end (); + ++i) +{ + switch (i->id) + { + case batch::withdraw_id: + { + const withdraw& t (b.withdraw ()[i->index]); + cerr << t.account () << " withdraw " << t.amount () << endl; + break; + } + case batch::deposit_id: + { + const deposit& t (b.deposit ()[i->index]); + cerr << t.account () << " deposit " << t.amount () << endl; + break; + } + default: + { + assert (false); // Unknown content id. + } + } +} + </pre> + + <p>If we serialized our batch back to XML, we would also see that the + order of transactions in the output is exactly the same as in the + input rather than all the withdrawals first followed by all the + deposits.</p> + + <p>The most complex aspect of working with ordered types is + modifications. Now we not only need to change the content, + but also remember to update the order information corresponding + to this change. As a first example, we add a deposit transaction + to the batch:</p> + + <pre class="c++"> +using xml_schema::content_order; + +batch::deposit_sequence& d (b.deposit ()); +batch::withdraw_sequence& w (b.withdraw ()); +batch::content_order_sequence& co (b.content_order ()); + +d.push_back (deposit (123456789, 100000)); +co.push_back (content_order (batch::deposit_id, d.size () - 1)); + </pre> + + <p>In the above example we first added the content (deposit + transaction) and then updated the content order information + by adding an entry with <code>deposit_id</code> content + id and the index of the just added deposit transaction.</p> + + <p>Removing the last transaction can be easy if we know which + transaction (deposit or withdrawal) is last:</p> + + <pre class="c++"> +d.pop_back (); +co.pop_back (); + </pre> + + <p>If, however, we do not know which transaction is last, then + things get a bit more complicated:</p> + + <pre class="c++"> +switch (co.back ().id) +{ +case batch::withdraw_id: + { + d.pop_back (); + break; + } +case batch::deposit_id: + { + w.pop_back (); + break; + } +} + +co.pop_back (); + </pre> + + <p>The following example shows how to add a transaction at the + beginning of the batch:</p> + + <pre class="c++"> +w.push_back (withdraw (123456789, 100000)); +co.insert (co.begin (), + content_order (batch::withdraw_id, w.size () - 1)); + </pre> + + <p>Note also that when we merely modify the content of one + of the elements in place, we do not need to update its + order since it doesn't change. For example, here is how + we can change the amount in the first withdrawal:</p> + + <pre class="c++"> +w[0].amount (10000); + </pre> + + <p>For the complete working code shown in this section refer to the + <code>order/element</code> example in the + <code>cxx/tree/</code> directory in the + <a href="https://cppget.org/xsd-examples">xsd-examples</a> + package.</p> + + <p>If both the base and derived types are ordered, then the + content order sequence is only added to the base and the content + ids are unique within the whole hierarchy. In this case + the content order sequence for the derived type contains + ordering information for both base and derived content.</p> + + <p>In some applications we may need to perform more complex + content processing. For example, in our case, we may need + to remove all the withdrawal transactions. The default + container, <code>std::vector</code>, is not particularly + suitable for such operations. What may be required by + some applications is a multi-index container that not + only allows us to iterate in content order similar to + <code>std::vector</code> but also search by the content + id as well as the content id and index pair.</p> + + <p>While C++/Tree does not provide this functionality by + default, it allows us to specify a custom container + type for content order with the <code>--order-container</code> + command line option. The only requirement from the + generated code side for such a container is to provide + the <code>vector</code>-like <code>push_back()</code>, + <code>size()</code>, and const iteration interfaces.</p> + + <p>As an example, here is how we can use the Boost Multi-Index + container for content order. First we create the + <code>content-order-container.hxx</code> header with the + following definition:</p> + + <pre class="c++"> +#ifndef CONTENT_ORDER_CONTAINER +#define CONTENT_ORDER_CONTAINER + +#include <cstddef> // std::size_t + +#include <boost/multi_index_container.hpp> +#include <boost/multi_index/member.hpp> +#include <boost/multi_index/identity.hpp> +#include <boost/multi_index/ordered_index.hpp> +#include <boost/multi_index/random_access_index.hpp> + +struct by_id {}; +struct by_id_index {}; + +template <typename T> +using content_order_container = + boost::multi_index::multi_index_container< + T, + boost::multi_index::indexed_by< + boost::multi_index::random_access<>, + boost::multi_index::ordered_unique< + boost::multi_index::tag<by_id_index>, + boost::multi_index::identity<T> + >, + boost::multi_index::ordered_non_unique< + boost::multi_index::tag<by_id>, + boost::multi_index::member<T, std::size_t, &T::id> + > + > + >; + +#endif + </pre> + + <p>Next we add the following two XSD compiler options to include + this header into every generated header file and to use the + custom container type (see the XSD compiler command line manual + for more information on shell quoting for the first option):</p> + + <pre class="term"> +--hxx-prologue '#include "content-order-container.hxx"' +--order-container content_order_container + </pre> + + <p>With these changes we can now use the multi-index functionality, + for example, to search for a specific content id:</p> + + <pre class="c++"> +typedef batch::content_order_sequence::index<by_id>::type id_set; +typedef id_set::iterator id_iterator; + +const id_set& ids (b.content_order ().get<by_id> ()); + +std::pair<id_iterator, id_iterator> r ( + ids.equal_range (std::size_t (batch::deposit_id)); + +for (id_iterator i (r.first); i != r.second; ++i) +{ + const deposit& t (b.deposit ()[i->index]); + cerr << t.account () << " deposit " << t.amount () << endl; +} + </pre> + + <h2><a name="2.9">2.9 Mapping for Global Elements</a></h2> + + <p>An XML Schema element definition is called global if it appears + directly under the <code>schema</code> element. + A global element is a valid root of an instance document. By + default, a global element is mapped to a set of overloaded + parsing and, optionally, serialization functions with the + same name as the element. It is also possible to generate types + for root elements instead of parsing and serialization functions. + This is primarily useful to distinguish object models with the + same root type but with different root elements. See + <a href="#2.9.1">Section 2.9.1, "Element Types"</a> for details. + It is also possible to request the generation of an element map + which allows uniform parsing and serialization of multiple root + elements. See <a href="#2.9.2">Section 2.9.2, "Element Map"</a> + for details. + </p> + + <p>The parsing functions read XML instance documents and return + corresponding object models as an automatic pointer + (<code>std::unique_ptr</code> or <code>std::auto_ptr</code>, + depending on the C++ standard selected). Their signatures + have the following pattern (<code>type</code> denotes + element's type and <code>name</code> denotes element's + name): + </p> + + <pre class="c++"> +std::[unique|auto]_ptr<type> +name (....); + </pre> + + <p>The process of parsing, including the exact signatures of the parsing + functions, is the subject of <a href="#3">Chapter 3, "Parsing"</a>. + </p> + + <p>The serialization functions write object models back to XML instance + documents. Their signatures have the following pattern: + </p> + + <pre class="c++"> +void +name (<stream type>&, const type&, ....); + </pre> + + <p>The process of serialization, including the exact signatures of the + serialization functions, is the subject of <a href="#4">Chapter 4, + "Serialization"</a>. + </p> + + + <h3><a name="2.9.1">2.9.1 Element Types</a></h3> + + <p>The generation of element types is requested with the + <code>--generate-element-type</code> option. With this option + each global element is mapped to a C++ class with the + same name as the element. Such a class is derived from + <code>xml_schema::element_type</code> and contains the same set + of type definitions, constructors, and member function as would a + type containing a single element with the One cardinality class + named <code>"value"</code>. In addition, the element type also + contains a set of member functions for accessing the element + name and namespace as well as its value in a uniform manner. + For example:</p> + + <pre class="xml"> +<complexType name="type"> + <sequence> + ... + </sequence> +</complexType> + +<element name="root" type="type"/> + </pre> + +<p>is mapped to:</p> + + <pre class="c++"> +class type +{ + ... +}; + +class root: public xml_schema::element_type +{ +public: + // Element value. + // + typedef type value_type; + + const value_type& + value () const; + + value_type& + value (); + + void + value (const value_type&); + + void + value (std::[unique|auto]_ptr<value_type>); + + // Constructors. + // + root (const value_type&); + + root (std::[unique|auto]_ptr<value_type>); + + root (const xercesc::DOMElement&, xml_schema::flags = 0); + + root (const root&, xml_schema::flags = 0); + + virtual root* + _clone (xml_schema::flags = 0) const; + + // Element name and namespace. + // + static const std::string& + name (); + + static const std::string& + namespace_ (); + + virtual const std::string& + _name () const; + + virtual const std::string& + _namespace () const; + + // Element value as xml_schema::type. + // + virtual const xml_schema::type* + _value () const; + + virtual xml_schema::type* + _value (); +}; + +void +operator<< (xercesc::DOMElement&, const root&); + </pre> + + <p>The <code>xml_schema::element_type</code> class is a common + base type for all element types and is defined as follows:</p> + + <pre class="c++"> +namespace xml_schema +{ + class element_type + { + public: + virtual + ~element_type (); + + virtual element_type* + _clone (flags f = 0) const = 0; + + virtual const std::basic_string<C>& + _name () const = 0; + + virtual const std::basic_string<C>& + _namespace () const = 0; + + virtual xml_schema::type* + _value () = 0; + + virtual const xml_schema::type* + _value () const = 0; + }; +} + </pre> + + <p>The <code>_value()</code> member function returns a pointer to + the element value or 0 if the element is of a fundamental C++ + type and therefore is not derived from <code>xml_schema::type</code>. + </p> + + <p>Unlike parsing and serialization functions, element types + are only capable of parsing and serializing from/to a + <code>DOMElement</code> object. This means that the application + will need to perform its own XML-to-DOM parsing and DOM-to-XML + serialization. The following section describes a mechanism + provided by the mapping to uniformly parse and serialize + multiple root elements.</p> + + + <h3><a name="2.9.2">2.9.2 Element Map</a></h3> + + <p>When element types are generated for root elements it is also + possible to request the generation of an element map with the + <code>--generate-element-map</code> option. The element map + allows uniform parsing and serialization of multiple root + elements via the common <code>xml_schema::element_type</code> + base type. The <code>xml_schema::element_map</code> class is + defined as follows:</p> + + <pre class="c++"> +namespace xml_schema +{ + class element_map + { + public: + static std::[unique|auto]_ptr<xml_schema::element_type> + parse (const xercesc::DOMElement&, flags = 0); + + static void + serialize (xercesc::DOMElement&, const element_type&); + }; +} + </pre> + + <p>The <code>parse()</code> function creates the corresponding + element type object based on the element name and namespace + and returns it as an automatic pointer (<code>std::unique_ptr</code> + or <code>std::auto_ptr</code>, depending on the C++ standard + selected) to <code>xml_schema::element_type</code>. + The <code>serialize()</code> function serializes the passed element + object to <code>DOMElement</code>. Note that in case of + <code>serialize()</code>, the <code>DOMElement</code> object + should have the correct name and namespace. If no element type is + available for an element, both functions throw the + <code>xml_schema::no_element_info</code> exception:</p> + + <pre class="c++"> +struct no_element_info: virtual exception +{ + no_element_info (const std::basic_string<C>& element_name, + const std::basic_string<C>& element_namespace); + + const std::basic_string<C>& + element_name () const; + + const std::basic_string<C>& + element_namespace () const; + + virtual const char* + what () const throw (); +}; + </pre> + + <p>The application can discover the actual type of the element + object returned by <code>parse()</code> either using + <code>dynamic_cast</code> or by comparing element names and + namespaces. The following code fragments illustrate how the + element map can be used:</p> + + <pre class="c++"> +// Parsing. +// +DOMElement& e = ... // Parse XML to DOM. + +unique_ptr<xml_schema::element_type> r ( + xml_schema::element_map::parse (e)); + +if (root1 r1 = dynamic_cast<root1*> (r.get ())) +{ + ... +} +else if (r->_name == root2::name () && + r->_namespace () == root2::namespace_ ()) +{ + root2& r2 (static_cast<root2&> (*r)); + + ... +} + </pre> + + <pre class="c++"> +// Serialization. +// +xml_schema::element_type& r = ... + +string name (r._name ()); +string ns (r._namespace ()); + +DOMDocument& doc = ... // Create a new DOMDocument with name and ns. +DOMElement& e (*doc->getDocumentElement ()); + +xml_schema::element_map::serialize (e, r); + +// Serialize DOMDocument to XML. + </pre> + + <!-- --> + + <h2><a name="2.10">2.10 Mapping for Global Attributes</a></h2> + + <p>An XML Schema attribute definition is called global if it appears + directly under the <code>schema</code> element. A global + attribute does not have any mapping. + </p> + + <!-- + When it is referenced from + a local attribute definition (using the <code>ref</code> attribute) + it is treated as a local attribute (see Section 2.8, "Mapping for + Local Elements and Attributes"). + --> + + <h2><a name="2.11">2.11 Mapping for <code>xsi:type</code> and Substitution + Groups</a></h2> + + <p>The mapping provides optional support for the XML Schema polymorphism + features (<code>xsi:type</code> and substitution groups) which can + be requested with the <code>--generate-polymorphic</code> option. + When used, the dynamic type of a member may be different from + its static type. Consider the following schema definition and + instance document: + </p> + + <pre class="xml"> +<!-- test.xsd --> +<schema> + <complexType name="base"> + <attribute name="text" type="string"/> + </complexType> + + <complexType name="derived"> + <complexContent> + <extension base="base"> + <attribute name="extra-text" type="string"/> + </extension> + </complexContent> + </complexType> + + <complexType name="root_type"> + <sequence> + <element name="item" type="base" maxOccurs="unbounded"/> + </sequence> + </complexType> + + <element name="root" type="root_type"/> +</schema> + +<!-- test.xml --> +<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <item text="hello"/> + <item text="hello" extra-text="world" xsi:type="derived"/> +</root> + </pre> + + <p>In the resulting object model, the container for + the <code>root::item</code> member will have two elements: + the first element's type will be <code>base</code> while + the second element's (dynamic) type will be + <code>derived</code>. This can be discovered using the + <code>dynamic_cast</code> operator as shown in the following + example: + </p> + + <pre class="c++"> +void +f (root& r) +{ + for (root::item_const_iterator i (r.item ().begin ()); + i != r.item ().end () + ++i) + { + if (derived* d = dynamic_cast<derived*> (&(*i))) + { + // derived + } + else + { + // base + } + } +} + </pre> + + <p>The <code>_clone</code> virtual function should be used instead of + copy constructors to make copies of members that might use + polymorphism: + </p> + + <pre class="c++"> +void +f (root& r) +{ + for (root::item_const_iterator i (r.item ().begin ()); + i != r.item ().end () + ++i) + { + std::unique_ptr<base> c (i->_clone ()); + } +} + </pre> + + <p>The mapping can often automatically determine which types are + polymorphic based on the substitution group declarations. However, + if your XML vocabulary is not using substitution groups or if + substitution groups are defined in a separate schema, then you will + need to use the <code>--polymorphic-type</code> option to specify + which types are polymorphic. When using this option you only need + to specify the root of a polymorphic type hierarchy and the mapping + will assume that all the derived types are also polymorphic. + Also note that you need to specify this option when compiling every + schema file that references the polymorphic type. Consider the following + two schemas as an example:</p> + + <pre class="xml"> +<!-- base.xsd --> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> + + <xs:complexType name="base"> + <xs:sequence> + <xs:element name="b" type="xs:int"/> + </xs:sequence> + </xs:complexType> + + <!-- substitution group root --> + <xs:element name="base" type="base"/> + +</xs:schema> + </pre> + + <pre class="xml"> +<!-- derived.xsd --> +<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> + + <include schemaLocation="base.xsd"/> + + <xs:complexType name="derived"> + <xs:complexContent> + <xs:extension base="base"> + <xs:sequence> + <xs:element name="d" type="xs:string"/> + </xs:sequence> + </xs:extension> + </xs:complexContent> + </xs:complexType> + + <xs:element name="derived" type="derived" substitutionGroup="base"/> + +</xs:schema> + </pre> + + <p>In this example we need to specify "<code>--polymorphic-type base</code>" + when compiling both schemas because the substitution group is declared + in a schema other than the one defining type <code>base</code>.</p> + + <p>You can also indicate that all types should be treated as polymorphic + with the <code>--polymorphic-type-all</code>. However, this may result + in slower generated code with a greater footprint.</p> + + + <!-- Mapping for any and anyAttribute --> + + + <h2><a name="2.12">2.12 Mapping for <code>any</code> and <code>anyAttribute</code></a></h2> + + <p>For the XML Schema <code>any</code> and <code>anyAttribute</code> + wildcards an optional mapping can be requested with the + <code>--generate-wildcard</code> option. The mapping represents + the content matched by wildcards as DOM fragments. Because the + DOM API is used to access such content, the Xerces-C++ runtime + should be initialized by the application prior to parsing and + should remain initialized for the lifetime of objects with + the wildcard content. For more information on the Xerces-C++ + runtime initialization see <a href="#3.1">Section 3.1, + "Initializing the Xerces-C++ Runtime"</a>. + </p> + + <p>The mapping for <code>any</code> is similar to the mapping for + local elements (see <a href="#2.8">Section 2.8, "Mapping for Local + Elements and Attributes"</a>) except that the type used in the + wildcard mapping is <code>xercesc::DOMElement</code>. As with local + elements, the mapping divides all possible cardinality combinations + into three cardinality classes: <i>one</i>, <i>optional</i>, and + <i>sequence</i>. + </p> + + <p>The mapping for <code>anyAttribute</code> represents the attributes + matched by this wildcard as a set of <code>xercesc::DOMAttr</code> + objects with a key being the attribute's name and namespace.</p> + + <p>Similar to local elements and attributes, the <code>any</code> and + <code>anyAttribute</code> wildcards are mapped to a set of public type + definitions (typedefs) and a set of public accessor and modifier + functions. Type definitions have names derived from <code>"any"</code> + for the <code>any</code> wildcard and <code>"any_attribute"</code> + for the <code>anyAttribute</code> wildcard. The accessor and modifier + functions are named <code>"any"</code> for the <code>any</code> wildcard + and <code>"any_attribute"</code> for the <code>anyAttribute</code> + wildcard. Subsequent wildcards in the same type have escaped names + such as <code>"any1"</code> or <code>"any_attribute1"</code>. + </p> + + <p>Because Xerces-C++ DOM nodes always belong to a <code>DOMDocument</code>, + each type with a wildcard has an associated <code>DOMDocument</code> + object. The reference to this object can be obtained using the accessor + function called <code>dom_document</code>. The access to the document + object from the application code may be necessary to create or modify + the wildcard content. For example: + </p> + + <pre class="xml"> +<complexType name="object"> + <sequence> + <any namespace="##other"/> + </sequence> + <anyAttribute namespace="##other"/> +</complexType> + </pre> + + <p>is mapped to:</p> + + <pre class="c++"> +class object: public xml_schema::type +{ +public: + // any + // + const xercesc::DOMElement& + any () const; + + void + any (const xercesc::DOMElement&); + + ... + + // any_attribute + // + typedef attribute_set any_attribute_set; + typedef any_attribute_set::iterator any_attribute_iterator; + typedef any_attribute_set::const_iterator any_attribute_const_iterator; + + const any_attribute_set& + any_attribute () const; + + any_attribute_set& + any_attribute (); + + ... + + // DOMDocument object for wildcard content. + // + const xercesc::DOMDocument& + dom_document () const; + + xercesc::DOMDocument& + dom_document (); + + ... +}; + </pre> + + + <p>Names and semantics of type definitions for the wildcards as well + as signatures of the accessor and modifier functions depend on the + wildcard type as well as the cardinality class for the <code>any</code> + wildcard. They are described in the following sub-sections. + </p> + + + <h3><a name="2.12.1">2.12.1 Mapping for <code>any</code> with the One Cardinality Class</a></h3> + + <p>For <code>any</code> with the One cardinality class, + there are no type definitions. The accessor functions come in + constant and non-constant versions. The constant accessor function + returns a constant reference to <code>xercesc::DOMElement</code> and + can be used for read-only access. The non-constant version returns + an unrestricted reference to <code>xercesc::DOMElement</code> and can + be used for read-write access. + </p> + + <p>The first modifier function expects an argument of type reference + to constant <code>xercesc::DOMElement</code> and makes a deep copy + of its argument. The second modifier function expects an argument of + type pointer to <code>xercesc::DOMElement</code>. This modifier + function assumes ownership of its argument and expects the element + object to be created using the DOM document associated with this + instance. For example: + </p> + + <pre class="xml"> +<complexType name="object"> + <sequence> + <any namespace="##other"/> + </sequence> +</complexType> + </pre> + + <p>is mapped to:</p> + + <pre class="c++"> +class object: public xml_schema::type +{ +public: + // Accessors. + // + const xercesc::DOMElement& + any () const; + + xercesc::DOMElement& + any (); + + // Modifiers. + // + void + any (const xercesc::DOMElement&); + + void + any (xercesc::DOMElement*); + + ... + +}; + </pre> + + + <p>The following code shows how one could use this mapping:</p> + + <pre class="c++"> +void +f (object& o, const xercesc::DOMElement& e) +{ + using namespace xercesc; + + DOMElement& e1 (o.any ()); // get + o.any (e) // set, deep copy + DOMDocument& doc (o.dom_document ()); + o.any (doc.createElement (...)); // set, assumes ownership +} + </pre> + + <h3><a name="2.12.2">2.12.2 Mapping for <code>any</code> with the Optional Cardinality Class</a></h3> + + <p>For <code>any</code> with the Optional cardinality class, the type + definitions consist of an alias for the container type with name + <code>any_optional</code> (or <code>any1_optional</code>, etc., for + subsequent wildcards in the type definition). + </p> + + <p>Unlike accessor functions for the One cardinality class, accessor + functions for the Optional cardinality class return references to + corresponding containers rather than directly to <code>DOMElement</code>. + The accessor functions come in constant and non-constant versions. + The constant accessor function returns a constant reference to + the container and can be used for read-only access. The non-constant + version returns an unrestricted reference to the container + and can be used for read-write access. + </p> + + <p>The modifier functions are overloaded for <code>xercesc::DOMElement</code> + and the container type. The first modifier function expects an argument of + type reference to constant <code>xercesc::DOMElement</code> and + makes a deep copy of its argument. The second modifier function + expects an argument of type pointer to <code>xercesc::DOMElement</code>. + This modifier function assumes ownership of its argument and expects + the element object to be created using the DOM document associated + with this instance. The third modifier function expects an argument + of type reference to constant of the container type and makes a + deep copy of its argument. For instance: + </p> + + <pre class="xml"> +<complexType name="object"> + <sequence> + <any namespace="##other" minOccurs="0"/> + </sequence> +</complexType> + </pre> + + <p>is mapped to:</p> + + <pre class="c++"> +class object: public xml_schema::type +{ +public: + // Type definitions. + // + typedef element_optional any_optional; + + // Accessors. + // + const any_optional& + any () const; + + any_optional& + any (); + + // Modifiers. + // + void + any (const xercesc::DOMElement&); + + void + any (xercesc::DOMElement*); + + void + any (const any_optional&); + + ... + +}; + </pre> + + + <p>The <code>element_optional</code> container is a + specialization of the <code>optional</code> class template described + in <a href="#2.8.2">Section 2.8.2, "Mapping for Members with the Optional + Cardinality Class"</a>. Its interface is presented below: + </p> + + <pre class="c++"> +class element_optional +{ +public: + explicit + element_optional (xercesc::DOMDocument&); + + // Makes a deep copy. + // + element_optional (const xercesc::DOMElement&, xercesc::DOMDocument&); + + // Assumes ownership. + // + element_optional (xercesc::DOMElement*, xercesc::DOMDocument&); + + element_optional (const element_optional&, xercesc::DOMDocument&); + +public: + element_optional& + operator= (const xercesc::DOMElement&); + + element_optional& + operator= (const element_optional&); + + // Pointer-like interface. + // +public: + const xercesc::DOMElement* + operator-> () const; + + xercesc::DOMElement* + operator-> (); + + const xercesc::DOMElement& + operator* () const; + + xercesc::DOMElement& + operator* (); + + typedef void (element_optional::*bool_convertible) (); + operator bool_convertible () const; + + // Get/set interface. + // +public: + bool + present () const; + + const xercesc::DOMElement& + get () const; + + xercesc::DOMElement& + get (); + + // Makes a deep copy. + // + void + set (const xercesc::DOMElement&); + + // Assumes ownership. + // + void + set (xercesc::DOMElement*); + + void + reset (); +}; + +bool +operator== (const element_optional&, const element_optional&); + +bool +operator!= (const element_optional&, const element_optional&); + </pre> + + + <p>The following code shows how one could use this mapping:</p> + + <pre class="c++"> +void +f (object& o, const xercesc::DOMElement& e) +{ + using namespace xercesc; + + DOMDocument& doc (o.dom_document ()); + + if (o.any ().present ()) // test + { + DOMElement& e1 (o.any ().get ()); // get + o.any ().set (e); // set, deep copy + o.any ().set (doc.createElement (...)); // set, assumes ownership + o.any ().reset (); // reset + } + + // Same as above but using pointer notation: + // + if (o.member ()) // test + { + DOMElement& e1 (*o.any ()); // get + o.any (e); // set, deep copy + o.any (doc.createElement (...)); // set, assumes ownership + o.any ().reset (); // reset + } +} + </pre> + + + + <h3><a name="2.12.3">2.12.3 Mapping for <code>any</code> with the Sequence Cardinality Class</a></h3> + + <p>For <code>any</code> with the Sequence cardinality class, the type + definitions consist of an alias of the container type with name + <code>any_sequence</code> (or <code>any1_sequence</code>, etc., for + subsequent wildcards in the type definition), an alias of the iterator + type with name <code>any_iterator</code> (or <code>any1_iterator</code>, + etc., for subsequent wildcards in the type definition), and an alias + of the constant iterator type with name <code>any_const_iterator</code> + (or <code>any1_const_iterator</code>, etc., for subsequent wildcards + in the type definition). + </p> + + <p>The accessor functions come in constant and non-constant versions. + The constant accessor function returns a constant reference to the + container and can be used for read-only access. The non-constant + version returns an unrestricted reference to the container and can + be used for read-write access. + </p> + + <p>The modifier function expects an argument of type reference to + constant of the container type. The modifier function makes + a deep copy of its argument. For instance: + </p> + + + <pre class="xml"> +<complexType name="object"> + <sequence> + <any namespace="##other" minOccurs="unbounded"/> + </sequence> +</complexType> + </pre> + + <p>is mapped to:</p> + + <pre class="c++"> +class object: public xml_schema::type +{ +public: + // Type definitions. + // + typedef element_sequence any_sequence; + typedef any_sequence::iterator any_iterator; + typedef any_sequence::const_iterator any_const_iterator; + + // Accessors. + // + const any_sequence& + any () const; + + any_sequence& + any (); + + // Modifier. + // + void + any (const any_sequence&); + + ... + +}; + </pre> + + <p>The <code>element_sequence</code> container is a + specialization of the <code>sequence</code> class template described + in <a href="#2.8.3">Section 2.8.3, "Mapping for Members with the + Sequence Cardinality Class"</a>. Its interface is similar to + the sequence interface as defined by the ISO/ANSI Standard for + C++ (ISO/IEC 14882:1998, Section 23.1.1, "Sequences") and is + presented below: + </p> + + <pre class="c++"> +class element_sequence +{ +public: + typedef xercesc::DOMElement value_type; + typedef xercesc::DOMElement* pointer; + typedef const xercesc::DOMElement* const_pointer; + typedef xercesc::DOMElement& reference; + typedef const xercesc::DOMElement& const_reference; + + typedef <implementation-defined> iterator; + typedef <implementation-defined> const_iterator; + typedef <implementation-defined> reverse_iterator; + typedef <implementation-defined> const_reverse_iterator; + + typedef <implementation-defined> size_type; + typedef <implementation-defined> difference_type; + typedef <implementation-defined> allocator_type; + +public: + explicit + element_sequence (xercesc::DOMDocument&); + + // DOMElement cannot be default-constructed. + // + // explicit + // element_sequence (size_type n); + + element_sequence (size_type n, + const xercesc::DOMElement&, + xercesc::DOMDocument&); + + template <typename I> + element_sequence (const I& begin, + const I& end, + xercesc::DOMDocument&); + + element_sequence (const element_sequence&, xercesc::DOMDocument&); + + element_sequence& + operator= (const element_sequence&); + +public: + void + assign (size_type n, const xercesc::DOMElement&); + + template <typename I> + void + assign (const I& begin, const I& end); + +public: + // This version of resize can only be used to shrink the + // sequence because DOMElement cannot be default-constructed. + // + void + resize (size_type); + + void + resize (size_type, const xercesc::DOMElement&); + +public: + size_type + size () const; + + size_type + max_size () const; + + size_type + capacity () const; + + bool + empty () const; + + void + reserve (size_type); + + void + clear (); + +public: + const_iterator + begin () const; + + const_iterator + end () const; + + iterator + begin (); + + iterator + end (); + + const_reverse_iterator + rbegin () const; + + const_reverse_iterator + rend () const + + reverse_iterator + rbegin (); + + reverse_iterator + rend (); + +public: + xercesc::DOMElement& + operator[] (size_type); + + const xercesc::DOMElement& + operator[] (size_type) const; + + xercesc::DOMElement& + at (size_type); + + const xercesc::DOMElement& + at (size_type) const; + + xercesc::DOMElement& + front (); + + const xercesc::DOMElement& + front () const; + + xercesc::DOMElement& + back (); + + const xercesc::DOMElement& + back () const; + +public: + // Makes a deep copy. + // + void + push_back (const xercesc::DOMElement&); + + // Assumes ownership. + // + void + push_back (xercesc::DOMElement*); + + void + pop_back (); + + // Makes a deep copy. + // + iterator + insert (iterator position, const xercesc::DOMElement&); + + // Assumes ownership. + // + iterator + insert (iterator position, xercesc::DOMElement*); + + void + insert (iterator position, size_type n, const xercesc::DOMElement&); + + template <typename I> + void + insert (iterator position, const I& begin, const I& end); + + iterator + erase (iterator position); + + iterator + erase (iterator begin, iterator end); + +public: + // Note that the DOMDocument object of the two sequences being + // swapped should be the same. + // + void + swap (sequence& x); +}; + +inline bool +operator== (const element_sequence&, const element_sequence&); + +inline bool +operator!= (const element_sequence&, const element_sequence&); + </pre> + + + <p>The following code shows how one could use this mapping:</p> + + <pre class="c++"> +void +f (object& o, const xercesc::DOMElement& e) +{ + using namespace xercesc; + + object::any_sequence& s (o.any ()); + + // Iteration. + // + for (object::any_iterator i (s.begin ()); i != s.end (); ++i) + { + DOMElement& e (*i); + } + + // Modification. + // + s.push_back (e); // deep copy + DOMDocument& doc (o.dom_document ()); + s.push_back (doc.createElement (...)); // assumes ownership +} + </pre> + + <h3><a name="2.12.4">2.12.4 Element Wildcard Order</a></h3> + + <p>Similar to elements, element wildcards in ordered types + (<a href="#2.8.4">Section 2.8.4, "Element Order"</a>) are assigned + content ids and are included in the content order sequence. + Continuing with the bank transactions example started in Section + 2.8.4, we can extend the batch by allowing custom transactions:</p> + + <pre class="xml"> +<complexType name="batch"> + <choice minOccurs="0" maxOccurs="unbounded"> + <element name="withdraw" type="withdraw"/> + <element name="deposit" type="deposit"/> + <any namespace="##other" processContents="lax"/> + </choice> +</complexType> + </pre> + + <p>This will lead to the following changes in the generated + <code>batch</code> C++ class:</p> + + <pre class="c++"> +class batch: public xml_schema::type +{ +public: + ... + + // any + // + typedef element_sequence any_sequence; + typedef any_sequence::iterator any_iterator; + typedef any_sequence::const_iterator any_const_iterator; + + static const std::size_t any_id = 3UL; + + const any_sequence& + any () const; + + any_sequence& + any (); + + void + any (const any_sequence&); + + ... +}; + </pre> + + <p>With this change we also need to update the iteration code to handle + the new content id:</p> + + <pre class="c++"> +for (batch::content_order_const_iterator i (b.content_order ().begin ()); + i != b.content_order ().end (); + ++i) +{ + switch (i->id) + { + ... + + case batch::any_id: + { + const DOMElement& e (b.any ()[i->index]); + ... + break; + } + + ... + } +} + </pre> + + <p>For the complete working code that shows the use of wildcards in + ordered types refer to the <code>order/element</code> example in + the <code>cxx/tree/</code> directory in the + <a href="https://cppget.org/xsd-examples">xsd-examples</a> + package.</p> + + <h3><a name="2.12.5">2.12.5 Mapping for <code>anyAttribute</code></a></h3> + + <p>For <code>anyAttribute</code> the type definitions consist of an alias + of the container type with name <code>any_attribute_set</code> + (or <code>any1_attribute_set</code>, etc., for subsequent wildcards + in the type definition), an alias of the iterator type with name + <code>any_attribute_iterator</code> (or <code>any1_attribute_iterator</code>, + etc., for subsequent wildcards in the type definition), and an alias + of the constant iterator type with name <code>any_attribute_const_iterator</code> + (or <code>any1_attribute_const_iterator</code>, etc., for subsequent + wildcards in the type definition). + </p> + + <p>The accessor functions come in constant and non-constant versions. + The constant accessor function returns a constant reference to the + container and can be used for read-only access. The non-constant + version returns an unrestricted reference to the container and can + be used for read-write access. + </p> + + <p>The modifier function expects an argument of type reference to + constant of the container type. The modifier function makes + a deep copy of its argument. For instance: + </p> + + + <pre class="xml"> +<complexType name="object"> + <sequence> + ... + </sequence> + <anyAttribute namespace="##other"/> +</complexType> + </pre> + + <p>is mapped to:</p> + + <pre class="c++"> +class object: public xml_schema::type +{ +public: + // Type definitions. + // + typedef attribute_set any_attribute_set; + typedef any_attribute_set::iterator any_attribute_iterator; + typedef any_attribute_set::const_iterator any_attribute_const_iterator; + + // Accessors. + // + const any_attribute_set& + any_attribute () const; + + any_attribute_set& + any_attribute (); + + // Modifier. + // + void + any_attribute (const any_attribute_set&); + + ... + +}; + </pre> + + <p>The <code>attribute_set</code> class is an associative container + similar to the <code>std::set</code> class template as defined by + the ISO/ANSI Standard for C++ (ISO/IEC 14882:1998, Section 23.3.3, + "Class template set") with the key being the attribute's name + and namespace. Unlike <code>std::set</code>, <code>attribute_set</code> + allows searching using names and namespaces instead of + <code>xercesc::DOMAttr</code> objects. It is defined in an + implementation-specific namespace and its interface is presented + below: + </p> + + <pre class="c++"> +class attribute_set +{ +public: + typedef xercesc::DOMAttr key_type; + typedef xercesc::DOMAttr value_type; + typedef xercesc::DOMAttr* pointer; + typedef const xercesc::DOMAttr* const_pointer; + typedef xercesc::DOMAttr& reference; + typedef const xercesc::DOMAttr& const_reference; + + typedef <implementation-defined> iterator; + typedef <implementation-defined> const_iterator; + typedef <implementation-defined> reverse_iterator; + typedef <implementation-defined> const_reverse_iterator; + + typedef <implementation-defined> size_type; + typedef <implementation-defined> difference_type; + typedef <implementation-defined> allocator_type; + +public: + attribute_set (xercesc::DOMDocument&); + + template <typename I> + attribute_set (const I& begin, const I& end, xercesc::DOMDocument&); + + attribute_set (const attribute_set&, xercesc::DOMDocument&); + + attribute_set& + operator= (const attribute_set&); + +public: + const_iterator + begin () const; + + const_iterator + end () const; + + iterator + begin (); + + iterator + end (); + + const_reverse_iterator + rbegin () const; + + const_reverse_iterator + rend () const; + + reverse_iterator + rbegin (); + + reverse_iterator + rend (); + +public: + size_type + size () const; + + size_type + max_size () const; + + bool + empty () const; + + void + clear (); + +public: + // Makes a deep copy. + // + std::pair<iterator, bool> + insert (const xercesc::DOMAttr&); + + // Assumes ownership. + // + std::pair<iterator, bool> + insert (xercesc::DOMAttr*); + + // Makes a deep copy. + // + iterator + insert (iterator position, const xercesc::DOMAttr&); + + // Assumes ownership. + // + iterator + insert (iterator position, xercesc::DOMAttr*); + + template <typename I> + void + insert (const I& begin, const I& end); + +public: + void + erase (iterator position); + + size_type + erase (const std::basic_string<C>& name); + + size_type + erase (const std::basic_string<C>& namespace_, + const std::basic_string<C>& name); + + size_type + erase (const XMLCh* name); + + size_type + erase (const XMLCh* namespace_, const XMLCh* name); + + void + erase (iterator begin, iterator end); + +public: + size_type + count (const std::basic_string<C>& name) const; + + size_type + count (const std::basic_string<C>& namespace_, + const std::basic_string<C>& name) const; + + size_type + count (const XMLCh* name) const; + + size_type + count (const XMLCh* namespace_, const XMLCh* name) const; + + iterator + find (const std::basic_string<C>& name); + + iterator + find (const std::basic_string<C>& namespace_, + const std::basic_string<C>& name); + + iterator + find (const XMLCh* name); + + iterator + find (const XMLCh* namespace_, const XMLCh* name); + + const_iterator + find (const std::basic_string<C>& name) const; + + const_iterator + find (const std::basic_string<C>& namespace_, + const std::basic_string<C>& name) const; + + const_iterator + find (const XMLCh* name) const; + + const_iterator + find (const XMLCh* namespace_, const XMLCh* name) const; + +public: + // Note that the DOMDocument object of the two sets being + // swapped should be the same. + // + void + swap (attribute_set&); +}; + +bool +operator== (const attribute_set&, const attribute_set&); + +bool +operator!= (const attribute_set&, const attribute_set&); + </pre> + + <p>The following code shows how one could use this mapping:</p> + + <pre class="c++"> +void +f (object& o, const xercesc::DOMAttr& a) +{ + using namespace xercesc; + + object::any_attribute_set& s (o.any_attribute ()); + + // Iteration. + // + for (object::any_attribute_iterator i (s.begin ()); i != s.end (); ++i) + { + DOMAttr& a (*i); + } + + // Modification. + // + s.insert (a); // deep copy + DOMDocument& doc (o.dom_document ()); + s.insert (doc.createAttribute (...)); // assumes ownership + + // Searching. + // + object::any_attribute_iterator i (s.find ("name")); + i = s.find ("http://www.w3.org/XML/1998/namespace", "lang"); +} + </pre> + + <!-- Mapping for Mixed Content Models --> + + <h2><a name="2.13">2.13 Mapping for Mixed Content Models</a></h2> + + <p>For XML Schema types with mixed content models C++/Tree provides + mapping support only if the type is marked as ordered + (<a href="#2.8.4">Section 2.8.4, "Element Order"</a>). Use the + <code>--ordered-type-mixed</code> XSD compiler option to + automatically mark all types with mixed content as ordered.</p> + + <p>For an ordered type with mixed content, C++/Tree adds an extra + text content sequence that is used to store the text fragments. + This text content sequence is also assigned the content id and + its entries are included in the content order sequence, just + like elements. As a result, it is possible to capture the order + between elements and text fragments.</p> + + <p>As an example, consider the following schema that describes text + with embedded links:</p> + + <pre class="xml"> +<complexType name="anchor"> + <simpleContent> + <extension base="string"> + <attribute name="href" type="anyURI" use="required"/> + </extension> + </simpleContent> +</complexType> + +<complexType name="text" mixed="true"> + <sequence> + <element name="a" type="anchor" minOccurs="0" maxOccurs="unbounded"/> + </sequence> +</complexType> + </pre> + + <p>The generated <code>text</code> C++ class will provide the following + API (assuming it is marked as ordered):</p> + + <pre class="c++"> +class text: public xml_schema::type +{ +public: + // a + // + typedef anchor a_type; + typedef sequence<a_type> a_sequence; + typedef a_sequence::iterator a_iterator; + typedef a_sequence::const_iterator a_const_iterator; + + static const std::size_t a_id = 1UL; + + const a_sequence& + a () const; + + a_sequence& + a (); + + void + a (const a_sequence&); + + // text_content + // + typedef xml_schema::string text_content_type; + typedef sequence<text_content_type> text_content_sequence; + typedef text_content_sequence::iterator text_content_iterator; + typedef text_content_sequence::const_iterator text_content_const_iterator; + + static const std::size_t text_content_id = 2UL; + + const text_content_sequence& + text_content () const; + + text_content_sequence& + text_content (); + + void + text_content (const text_content_sequence&); + + // content_order + // + typedef xml_schema::content_order content_order_type; + typedef std::vector<content_order_type> content_order_sequence; + typedef content_order_sequence::iterator content_order_iterator; + typedef content_order_sequence::const_iterator content_order_const_iterator; + + const content_order_sequence& + content_order () const; + + content_order_sequence& + content_order (); + + void + content_order (const content_order_sequence&); + + ... +}; + </pre> + + <p>Given this interface we can iterate over both link elements + and text in content order. The following code fragment converts + our format to plain text with references.</p> + + <pre class="c++"> +const text& t = ... + +for (text::content_order_const_iterator i (t.content_order ().begin ()); + i != t.content_order ().end (); + ++i) +{ + switch (i->id) + { + case text::a_id: + { + const anchor& a (t.a ()[i->index]); + cerr << a << "[" << a.href () << "]"; + break; + } + case text::text_content_id: + { + const xml_schema::string& s (t.text_content ()[i->index]); + cerr << s; + break; + } + default: + { + assert (false); // Unknown content id. + } + } +} + </pre> + + <p>For the complete working code that shows the use of mixed content + in ordered types refer to the <code>order/mixed</code> example in + the <code>cxx/tree/</code> directory in the + <a href="https://cppget.org/xsd-examples">xsd-examples</a> + package.</p> + + <!-- Parsing --> + + + <h1><a name="3">3 Parsing</a></h1> + + <p>This chapter covers various aspects of parsing XML instance + documents in order to obtain corresponding tree-like object + model. + </p> + + <p>Each global XML Schema element in the form:</p> + + <pre class="xml"> +<element name="name" type="type"/> + </pre> + + <p>is mapped to 14 overloaded C++ functions in the form:</p> + + <pre class="c++"> +// Read from a URI or a local file. +// + +std::[unique|auto]_ptr<type> +name (const std::basic_string<C>& uri, + xml_schema::flags = 0, + const xml_schema::properties& = xml_schema::properties ()); + +std::[unique|auto]_ptr<type> +name (const std::basic_string<C>& uri, + xml_schema::error_handler&, + xml_schema::flags = 0, + const xml_schema::properties& = xml_schema::properties ()); + +std::[unique|auto]_ptr<type> +name (const std::basic_string<C>& uri, + xercesc::DOMErrorHandler&, + xml_schema::flags = 0, + const xml_schema::properties& = xml_schema::properties ()); + + +// Read from std::istream. +// + +std::[unique|auto]_ptr<type> +name (std::istream&, + xml_schema::flags = 0, + const xml_schema::properties& = xml_schema::properties ()); + +std::[unique|auto]_ptr<type> +name (std::istream&, + xml_schema::error_handler&, + xml_schema::flags = 0, + const xml_schema::properties& = xml_schema::properties ()); + +std::[unique|auto]_ptr<type> +name (std::istream&, + xercesc::DOMErrorHandler&, + xml_schema::flags = 0, + const xml_schema::properties& = xml_schema::properties ()); + + +std::[unique|auto]_ptr<type> +name (std::istream&, + const std::basic_string<C>& id, + xml_schema::flags = 0, + const xml_schema::properties& = xml_schema::properties ()); + +std::[unique|auto]_ptr<type> +name (std::istream&, + const std::basic_string<C>& id, + xml_schema::error_handler&, + xml_schema::flags = 0, + const xml_schema::properties& = xml_schema::properties ()); + +std::[unique|auto]_ptr<type> +name (std::istream&, + const std::basic_string<C>& id, + xercesc::DOMErrorHandler&, + xml_schema::flags = 0, + const xml_schema::properties& = xml_schema::properties ()); + + +// Read from InputSource. +// + +std::[unique|auto]_ptr<type> +name (xercesc::InputSource&, + xml_schema::flags = 0, + const xml_schema::properties& = xml_schema::properties ()); + +std::[unique|auto]_ptr<type> +name (xercesc::InputSource&, + xml_schema::error_handler&, + xml_schema::flags = 0, + const xml_schema::properties& = xml_schema::properties ()); + +std::[unique|auto]_ptr<type> +name (xercesc::InputSource&, + xercesc::DOMErrorHandler&, + xml_schema::flags = 0, + const xml_schema::properties& = xml_schema::properties ()); + + +// Read from DOM. +// + +std::[unique|auto]_ptr<type> +name (const xercesc::DOMDocument&, + xml_schema::flags = 0, + const xml_schema::properties& = xml_schema::properties ()); + +std::[unique|auto]_ptr<type> +name (xml_schema::dom::[unique|auto]_ptr<xercesc::DOMDocument>, + xml_schema::flags = 0, + const xml_schema::properties& = xml_schema::properties ()); + </pre> + + <p>You can choose between reading an XML instance from a local file, + URI, <code>std::istream</code>, <code>xercesc::InputSource</code>, + or a pre-parsed DOM instance in the form of + <code>xercesc::DOMDocument</code>. All the parsing functions + return a dynamically allocated object model as either + <code>std::unique_ptr</code> or <code>std::auto_ptr</code>, + depending on the C++ standard selected. Each of these parsing + functions is discussed in more detail in the following sections. + </p> + + <h2><a name="3.1">3.1 Initializing the Xerces-C++ Runtime</a></h2> + + <p>Some parsing functions expect you to initialize the Xerces-C++ + runtime while others initialize and terminate it as part of their + work. The general rule is as follows: if a function has any arguments + or return a value that is an instance of a Xerces-C++ type, then + this function expects you to initialize the Xerces-C++ runtime. + Otherwise, the function initializes and terminates the runtime for + you. Note that it is legal to have nested calls to the Xerces-C++ + initialize and terminate functions as long as the calls are balanced. + </p> + + <p>You can instruct parsing functions that initialize and terminate + the runtime not to do so by passing the + <code>xml_schema::flags::dont_initialize</code> flag (see + <a href="#3.2">Section 3.2, "Flags and Properties"</a>). + </p> + + + <h2><a name="3.2">3.2 Flags and Properties</a></h2> + + <p>Parsing flags and properties are the last two arguments of every + parsing function. They allow you to fine-tune the process of + instance validation and parsing. Both arguments are optional. + </p> + + + <p>The following flags are recognized by the parsing functions:</p> + + <dl> + <dt><code>xml_schema::flags::keep_dom</code></dt> + <dd>Keep association between DOM nodes and the resulting + object model nodes. For more information about DOM association + refer to <a href="#5.1">Section 5.1, "DOM Association"</a>.</dd> + + <dt><code>xml_schema::flags::own_dom</code></dt> + <dd>Assume ownership of the DOM document passed. This flag only + makes sense together with the <code>keep_dom</code> flag in + the call to the parsing function with the + <code>xml_schema::dom::[unique|auto]_ptr<DOMDocument></code> + argument.</dd> + + <dt><code>xml_schema::flags::dont_validate</code></dt> + <dd>Do not validate instance documents against schemas.</dd> + + <dt><code>xml_schema::flags::dont_initialize</code></dt> + <dd>Do not initialize the Xerces-C++ runtime.</dd> + </dl> + + <p>You can pass several flags by combining them using the bit-wise OR + operator. For example:</p> + + <pre class="c++"> +using xml_schema::flags; + +std::unique_ptr<type> r ( + name ("test.xml", flags::keep_dom | flags::dont_validate)); + </pre> + + <p>By default, validation of instance documents is turned on even + though parsers generated by XSD do not assume instance + documents are valid. They include a number of checks that prevent + construction of inconsistent object models. This, + however, does not mean that an instance document that was + successfully parsed by the XSD-generated parsers is + valid per the corresponding schema. If an instance document is not + "valid enough" for the generated parsers to construct consistent + object model, one of the exceptions defined in + <code>xml_schema</code> namespace is thrown (see + <a href="#3.3">Section 3.3, "Error Handling"</a>). + </p> + + <p>For more information on the Xerces-C++ runtime initialization + refer to <a href="#3.1">Section 3.1, "Initializing the Xerces-C++ + Runtime"</a>. + </p> + + <p>The <code>xml_schema::properties</code> class allows you to + programmatically specify schema locations to be used instead + of those specified with the <code>xsi::schemaLocation</code> + and <code>xsi::noNamespaceSchemaLocation</code> attributes + in instance documents. The interface of the <code>properties</code> + class is presented below: + </p> + + <pre class="c++"> +class properties +{ +public: + void + schema_location (const std::basic_string<C>& namespace_, + const std::basic_string<C>& location); + void + no_namespace_schema_location (const std::basic_string<C>& location); +}; + </pre> + + <p>Note that all locations are relative to an instance document unless + they are URIs. For example, if you want to use a local file as your + schema, then you will need to pass + <code>file:///absolute/path/to/your/schema</code> as the location + argument. + </p> + + <h2><a name="3.3">3.3 Error Handling</a></h2> + + <p>As discussed in <a href="#2.2">Section 2.2, "Error Handling"</a>, + the mapping uses the C++ exception handling mechanism as its primary + way of reporting error conditions. However, to handle recoverable + parsing and validation errors and warnings, a callback interface maybe + preferred by the application.</p> + + <p>To better understand error handling and reporting strategies employed + by the parsing functions, it is useful to know that the + transformation of an XML instance document to a statically-typed + tree happens in two stages. The first stage, performed by Xerces-C++, + consists of parsing an XML document into a DOM instance. For short, + we will call this stage the XML-DOM stage. Validation, if not disabled, + happens during this stage. The second stage, + performed by the generated parsers, consist of parsing the DOM + instance into the statically-typed tree. We will call this stage + the DOM-Tree stage. Additional checks are performed during this + stage in order to prevent construction of inconsistent tree which + could otherwise happen when validation is disabled, for example.</p> + + <p>All parsing functions except the one that operates on a DOM instance + come in overloaded triples. The first function in such a triple + reports error conditions exclusively by throwing exceptions. It + accumulates all the parsing and validation errors of the XML-DOM + stage and throws them in a single instance of the + <code>xml_schema::parsing</code> exception (described below). + The second and the third functions in the triple use callback + interfaces to report parsing and validation errors and warnings. + The two callback interfaces are <code>xml_schema::error_handler</code> + and <code>xercesc::DOMErrorHandler</code>. For more information + on the <code>xercesc::DOMErrorHandler</code> interface refer to + the Xerces-C++ documentation. The <code>xml_schema::error_handler</code> + interface is presented below: + </p> + + <pre class="c++"> +class error_handler +{ +public: + struct severity + { + enum value + { + warning, + error, + fatal + }; + }; + + virtual bool + handle (const std::basic_string<C>& id, + unsigned long line, + unsigned long column, + severity, + const std::basic_string<C>& message) = 0; + + virtual + ~error_handler (); +}; + </pre> + + <p>The <code>id</code> argument of the <code>error_handler::handle</code> + function identifies the resource being parsed (e.g., a file name or + URI). + </p> + + <p>By returning <code>true</code> from the <code>handle</code> function + you instruct the parser to recover and continue parsing. Returning + <code>false</code> results in termination of the parsing process. + An error with the <code>fatal</code> severity level results in + termination of the parsing process no matter what is returned from + the <code>handle</code> function. It is safe to throw an exception + from the <code>handle</code> function. + </p> + + <p>The DOM-Tree stage reports error conditions exclusively by throwing + exceptions. Individual exceptions thrown by the parsing functions + are described in the following sub-sections. + </p> + + + <h3><a name="3.3.1">3.3.1 <code>xml_schema::parsing</code></a></h3> + + <pre class="c++"> +struct severity +{ + enum value + { + warning, + error + }; + + severity (value); + operator value () const; +}; + +struct error +{ + error (severity, + const std::basic_string<C>& id, + unsigned long line, + unsigned long column, + const std::basic_string<C>& message); + + severity + severity () const; + + const std::basic_string<C>& + id () const; + + unsigned long + line () const; + + unsigned long + column () const; + + const std::basic_string<C>& + message () const; +}; + +std::basic_ostream<C>& +operator<< (std::basic_ostream<C>&, const error&); + +struct diagnostics: std::vector<error> +{ +}; + +std::basic_ostream<C>& +operator<< (std::basic_ostream<C>&, const diagnostics&); + +struct parsing: virtual exception +{ + parsing (); + parsing (const diagnostics&); + + const diagnostics& + diagnostics () const; + + virtual const char* + what () const throw (); +}; + </pre> + + <p>The <code>xml_schema::parsing</code> exception is thrown if there + were parsing or validation errors reported during the XML-DOM stage. + If no callback interface was provided to the parsing function, the + exception contains a list of errors and warnings accessible using + the <code>diagnostics</code> function. The usual conditions when + this exception is thrown include malformed XML instances and, if + validation is turned on, invalid instance documents. + </p> + + <h3><a name="3.3.2">3.3.2 <code>xml_schema::expected_element</code></a></h3> + + <pre class="c++"> +struct expected_element: virtual exception +{ + expected_element (const std::basic_string<C>& name, + const std::basic_string<C>& namespace_); + + + const std::basic_string<C>& + name () const; + + const std::basic_string<C>& + namespace_ () const; + + + virtual const char* + what () const throw (); +}; + </pre> + + <p>The <code>xml_schema::expected_element</code> exception is thrown + when an expected element is not encountered by the DOM-Tree stage. + The name and namespace of the expected element can be obtained using + the <code>name</code> and <code>namespace_</code> functions respectively. + </p> + + + <h3><a name="3.3.3">3.3.3 <code>xml_schema::unexpected_element</code></a></h3> + + <pre class="c++"> +struct unexpected_element: virtual exception +{ + unexpected_element (const std::basic_string<C>& encountered_name, + const std::basic_string<C>& encountered_namespace, + const std::basic_string<C>& expected_name, + const std::basic_string<C>& expected_namespace) + + + const std::basic_string<C>& + encountered_name () const; + + const std::basic_string<C>& + encountered_namespace () const; + + + const std::basic_string<C>& + expected_name () const; + + const std::basic_string<C>& + expected_namespace () const; + + + virtual const char* + what () const throw (); +}; + </pre> + + <p>The <code>xml_schema::unexpected_element</code> exception is thrown + when an unexpected element is encountered by the DOM-Tree stage. + The name and namespace of the encountered element can be obtained + using the <code>encountered_name</code> and + <code>encountered_namespace</code> functions respectively. If an + element was expected instead of the encountered one, its name + and namespace can be obtained using the <code>expected_name</code> and + <code>expected_namespace</code> functions respectively. Otherwise + these functions return empty strings. + </p> + + <h3><a name="3.3.4">3.3.4 <code>xml_schema::expected_attribute</code></a></h3> + + <pre class="c++"> +struct expected_attribute: virtual exception +{ + expected_attribute (const std::basic_string<C>& name, + const std::basic_string<C>& namespace_); + + + const std::basic_string<C>& + name () const; + + const std::basic_string<C>& + namespace_ () const; + + + virtual const char* + what () const throw (); +}; + </pre> + + <p>The <code>xml_schema::expected_attribute</code> exception is thrown + when an expected attribute is not encountered by the DOM-Tree stage. + The name and namespace of the expected attribute can be obtained using + the <code>name</code> and <code>namespace_</code> functions respectively. + </p> + + + <h3><a name="3.3.5">3.3.5 <code>xml_schema::unexpected_enumerator</code></a></h3> + + <pre class="c++"> +struct unexpected_enumerator: virtual exception +{ + unexpected_enumerator (const std::basic_string<C>& enumerator); + + const std::basic_string<C>& + enumerator () const; + + virtual const char* + what () const throw (); +}; + </pre> + + <p>The <code>xml_schema::unexpected_enumerator</code> exception is thrown + when an unexpected enumerator is encountered by the DOM-Tree stage. + The enumerator can be obtained using the <code>enumerator</code> + functions. + </p> + + <h3><a name="3.3.6">3.3.6 <code>xml_schema::expected_text_content</code></a></h3> + + <pre class="c++"> +struct expected_text_content: virtual exception +{ + virtual const char* + what () const throw (); +}; + </pre> + + <p>The <code>xml_schema::expected_text_content</code> exception is thrown + when a content other than text is encountered and the text content was + expected by the DOM-Tree stage. + </p> + + <h3><a name="3.3.7">3.3.7 <code>xml_schema::no_type_info</code></a></h3> + + <pre class="c++"> +struct no_type_info: virtual exception +{ + no_type_info (const std::basic_string<C>& type_name, + const std::basic_string<C>& type_namespace); + + const std::basic_string<C>& + type_name () const; + + const std::basic_string<C>& + type_namespace () const; + + virtual const char* + what () const throw (); +}; + </pre> + + <p>The <code>xml_schema::no_type_info</code> exception is thrown + when there is no type information associated with a type specified + by the <code>xsi:type</code> attribute. This exception is thrown + by the DOM-Tree stage. The name and namespace of the type in question + can be obtained using the <code>type_name</code> and + <code>type_namespace</code> functions respectively. Usually, catching + this exception means that you haven't linked the code generated + from the schema defining the type in question with your application + or this schema has been compiled without the + <code>--generate-polymorphic</code> option. + </p> + + + <h3><a name="3.3.8">3.3.8 <code>xml_schema::not_derived</code></a></h3> + + <pre class="c++"> +struct not_derived: virtual exception +{ + not_derived (const std::basic_string<C>& base_type_name, + const std::basic_string<C>& base_type_namespace, + const std::basic_string<C>& derived_type_name, + const std::basic_string<C>& derived_type_namespace); + + const std::basic_string<C>& + base_type_name () const; + + const std::basic_string<C>& + base_type_namespace () const; + + + const std::basic_string<C>& + derived_type_name () const; + + const std::basic_string<C>& + derived_type_namespace () const; + + virtual const char* + what () const throw (); +}; + </pre> + + <p>The <code>xml_schema::not_derived</code> exception is thrown + when a type specified by the <code>xsi:type</code> attribute is + not derived from the expected base type. This exception is thrown + by the DOM-Tree stage. The name and namespace of the expected + base type can be obtained using the <code>base_type_name</code> and + <code>base_type_namespace</code> functions respectively. The name + and namespace of the offending type can be obtained using the + <code>derived_type_name</code> and + <code>derived_type_namespace</code> functions respectively. + </p> + + <h3><a name="3.3.9">3.3.9 <code>xml_schema::no_prefix_mapping</code></a></h3> + + <pre class="c++"> +struct no_prefix_mapping: virtual exception +{ + no_prefix_mapping (const std::basic_string<C>& prefix); + + const std::basic_string<C>& + prefix () const; + + virtual const char* + what () const throw (); +}; + </pre> + + <p>The <code>xml_schema::no_prefix_mapping</code> exception is thrown + during the DOM-Tree stage if a namespace prefix is encountered for + which a prefix-namespace mapping hasn't been provided. The namespace + prefix in question can be obtained using the <code>prefix</code> + function. + </p> + + <h2><a name="3.4">3.4 Reading from a Local File or URI</a></h2> + + <p>Using a local file or URI is the simplest way to parse an XML instance. + For example:</p> + + <pre class="c++"> +using std::unique_ptr; + +unique_ptr<type> r1 (name ("test.xml")); +unique_ptr<type> r2 (name ("https://www.codesynthesis.com/test.xml")); + </pre> + + <p>Or, in the C++98 mode:</p> + + <pre class="c++"> +using std::auto_ptr; + +auto_ptr<type> r1 (name ("test.xml")); +auto_ptr<type> r2 (name ("https://www.codesynthesis.com/test.xml")); + </pre> + + <h2><a name="3.5">3.5 Reading from <code>std::istream</code></a></h2> + + <p>When using an <code>std::istream</code> instance, you may also + pass an optional resource id. This id is used to identify the + resource (for example in error messages) as well as to resolve + relative paths. For instance:</p> + + <pre class="c++"> +using std::unique_ptr; + +{ + std::ifstream ifs ("test.xml"); + unique_ptr<type> r (name (ifs, "test.xml")); +} + +{ + std::string str ("..."); // Some XML fragment. + std::istringstream iss (str); + unique_ptr<type> r (name (iss)); +} + </pre> + + <h2><a name="3.6">3.6 Reading from <code>xercesc::InputSource</code></a></h2> + + <p>Reading from a <code>xercesc::InputSource</code> instance + is similar to the <code>std::istream</code> case except + the resource id is maintained by the <code>InputSource</code> + object. For instance:</p> + + <pre class="c++"> +xercesc::StdInInputSource is; +std::unique_ptr<type> r (name (is)); + </pre> + + <h2><a name="3.7">3.7 Reading from DOM</a></h2> + + <p>Reading from a <code>xercesc::DOMDocument</code> instance allows + you to setup a custom XML-DOM stage. Things like DOM + parser reuse, schema pre-parsing, and schema caching can be achieved + with this approach. For more information on how to obtain DOM + representation from an XML instance refer to the Xerces-C++ + documentation. In addition, the + <a href="http://wiki.codesynthesis.com/Tree/FAQ">C++/Tree Mapping + FAQ</a> shows how to parse an XML instance to a Xerces-C++ + DOM document using the XSD runtime utilities. + </p> + + <p>The last parsing function is useful when you would like to perform + your own XML-to-DOM parsing and associate the resulting DOM document + with the object model nodes. The automatic <code>DOMDocument</code> + pointer is reset and the resulting object model assumes ownership + of the DOM document passed. For example:</p> + + <pre class="c++"> +// C++11 version. +// +xml_schema::dom::unique_ptr<xercesc::DOMDocument> doc = ... + +std::unique_ptr<type> r ( + name (std::move (doc), + xml_schema::flags::keep_dom | xml_schema::flags::own_dom)); + +// At this point doc is reset to 0. + +// C++98 version. +// +xml_schema::dom::auto_ptr<xercesc::DOMDocument> doc = ... + +std::auto_ptr<type> r ( + name (doc, xml_schema::flags::keep_dom | xml_schema::flags::own_dom)); + +// At this point doc is reset to 0. + </pre> + + <h1><a name="4">4 Serialization</a></h1> + + <p>This chapter covers various aspects of serializing a + tree-like object model to DOM or XML. + In this regard, serialization is complimentary to the reverse + process of parsing a DOM or XML instance into an object model + which is discussed in <a href="#3">Chapter 3, + "Parsing"</a>. Note that the generation of the serialization code + is optional and should be explicitly requested with the + <code>--generate-serialization</code> option. See the + <a href="https://www.codesynthesis.com/projects/xsd/documentation/xsd.xhtml">XSD + Compiler Command Line Manual</a> for more information. + </p> + + <p>Each global XML Schema element in the form: + </p> + + + <pre class="xml"> +<xsd:element name="name" type="type"/> + </pre> + + <p>is mapped to 8 overloaded C++ functions in the form:</p> + + <pre class="c++"> +// Serialize to std::ostream. +// +void +name (std::ostream&, + const type&, + const xml_schema::namespace_fomap& = + xml_schema::namespace_infomap (), + const std::basic_string<C>& encoding = "UTF-8", + xml_schema::flags = 0); + +void +name (std::ostream&, + const type&, + xml_schema::error_handler&, + const xml_schema::namespace_infomap& = + xml_schema::namespace_infomap (), + const std::basic_string<C>& encoding = "UTF-8", + xml_schema::flags = 0); + +void +name (std::ostream&, + const type&, + xercesc::DOMErrorHandler&, + const xml_schema::namespace_infomap& = + xml_schema::namespace_infomap (), + const std::basic_string<C>& encoding = "UTF-8", + xml_schema::flags = 0); + + +// Serialize to XMLFormatTarget. +// +void +name (xercesc::XMLFormatTarget&, + const type&, + const xml_schema::namespace_infomap& = + xml_schema::namespace_infomap (), + const std::basic_string<C>& encoding = "UTF-8", + xml_schema::flags = 0); + +void +name (xercesc::XMLFormatTarget&, + const type&, + xml_schema::error_handler&, + const xml_schema::namespace_infomap& = + xml_schema::namespace_infomap (), + const std::basic_string<C>& encoding = "UTF-8", + xml_schema::flags = 0); + +void +name (xercesc::XMLFormatTarget&, + const type&, + xercesc::DOMErrorHandler&, + const xml_schema::namespace_infomap& = + xml_schema::namespace_infomap (), + const std::basic_string<C>& encoding = "UTF-8", + xml_schema::flags = 0); + + +// Serialize to DOM. +// +xml_schema::dom::[unique|auto]_ptr<xercesc::DOMDocument> +name (const type&, + const xml_schema::namespace_infomap& + xml_schema::namespace_infomap (), + xml_schema::flags = 0); + +void +name (xercesc::DOMDocument&, + const type&, + xml_schema::flags = 0); + </pre> + + <p>You can choose between writing XML to <code>std::ostream</code> or + <code>xercesc::XMLFormatTarget</code> and creating a DOM instance + in the form of <code>xercesc::DOMDocument</code>. Serialization + to <code>ostream</code> or <code>XMLFormatTarget</code> requires a + considerably less work while serialization to DOM provides + for greater flexibility. Each of these serialization functions + is discussed in more detail in the following sections. + </p> + + + <h2><a name="4.1">4.1 Initializing the Xerces-C++ Runtime</a></h2> + + <p>Some serialization functions expect you to initialize the Xerces-C++ + runtime while others initialize and terminate it as part of their + work. The general rule is as follows: if a function has any arguments + or return a value that is an instance of a Xerces-C++ type, then + this function expects you to initialize the Xerces-C++ runtime. + Otherwise, the function initializes and terminates the runtime for + you. Note that it is legal to have nested calls to the Xerces-C++ + initialize and terminate functions as long as the calls are balanced. + </p> + + <p>You can instruct serialization functions that initialize and terminate + the runtime not to do so by passing the + <code>xml_schema::flags::dont_initialize</code> flag (see + <a href="#4.3">Section 4.3, "Flags"</a>). + </p> + + <h2><a name="4.2">4.2 Namespace Infomap and Character Encoding</a></h2> + + <p>When a document being serialized uses XML namespaces, custom + prefix-namespace associations can to be established. If custom + prefix-namespace mapping is not provided then generic prefixes + (<code>p1</code>, <code>p2</code>, etc) are automatically assigned + to namespaces as needed. Also, if + you would like the resulting instance document to contain the + <code>schemaLocation</code> or <code>noNamespaceSchemaLocation</code> + attributes, you will need to provide namespace-schema associations. + The <code>xml_schema::namespace_infomap</code> class is used + to capture this information:</p> + + <pre class="c++"> +struct namespace_info +{ + namespace_info (); + namespace_info (const std::basic_string<C>& name, + const std::basic_string<C>& schema); + + std::basic_string<C> name; + std::basic_string<C> schema; +}; + +// Map of namespace prefix to namespace_info. +// +struct namespace_infomap: public std::map<std::basic_string<C>, + namespace_info> +{ +}; + </pre> + + <p>Consider the following associations as an example:</p> + + <pre class="c++"> +xml_schema::namespace_infomap map; + +map["t"].name = "https://www.codesynthesis.com/test"; +map["t"].schema = "test.xsd"; + </pre> + + <p>This map, if passed to one of the serialization functions, + could result in the following XML fragment:</p> + + <pre class="xml"> +<?xml version="1.0" ?> +<t:name xmlns:t="https://www.codesynthesis.com/test" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="https://www.codesynthesis.com/test test.xsd"> + </pre> + + <p>As you can see, the serialization function automatically added namespace + mapping for the <code>xsi</code> prefix. You can change this by + providing your own prefix:</p> + + <pre class="c++"> +xml_schema::namespace_infomap map; + +map["xsn"].name = "http://www.w3.org/2001/XMLSchema-instance"; + +map["t"].name = "https://www.codesynthesis.com/test"; +map["t"].schema = "test.xsd"; + </pre> + + <p>This could result in the following XML fragment:</p> + + <pre class="xml"> +<?xml version="1.0" ?> +<t:name xmlns:t="https://www.codesynthesis.com/test" + xmlns:xsn="http://www.w3.org/2001/XMLSchema-instance" + xsn:schemaLocation="https://www.codesynthesis.com/test test.xsd"> + </pre> + + <p>To specify the location of a schema without a namespace you can use + an empty prefix as in the example below: </p> + + <pre class="c++"> +xml_schema::namespace_infomap map; + +map[""].schema = "test.xsd"; + </pre> + + <p>This would result in the following XML fragment:</p> + + <pre class="xml"> +<?xml version="1.0" ?> +<name xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="test.xsd"> + </pre> + + <p>To make a particular namespace default you can use an empty + prefix, for example:</p> + + <pre class="c++"> +xml_schema::namespace_infomap map; + +map[""].name = "https://www.codesynthesis.com/test"; +map[""].schema = "test.xsd"; + </pre> + + <p>This could result in the following XML fragment:</p> + + <pre class="xml"> +<?xml version="1.0" ?> +<name xmlns="https://www.codesynthesis.com/test" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="https://www.codesynthesis.com/test test.xsd"> + </pre> + + + <p>Another bit of information that you can pass to the serialization + functions is the character encoding method that you would like to use. + Common values for this argument are <code>"US-ASCII"</code>, + <code>"ISO8859-1"</code>, <code>"UTF-8"</code>, + <code>"UTF-16BE"</code>, <code>"UTF-16LE"</code>, + <code>"UCS-4BE"</code>, and <code>"UCS-4LE"</code>. The default + encoding is <code>"UTF-8"</code>. For more information on + encoding methods see the + "<a href="http://en.wikipedia.org/wiki/Character_code">Character + Encoding</a>" article from Wikipedia. + </p> + + <h2><a name="4.3">4.3 Flags</a></h2> + + <p>Serialization flags are the last argument of every serialization + function. They allow you to fine-tune the process of serialization. + The flags argument is optional. + </p> + + + <p>The following flags are recognized by the serialization + functions:</p> + + <dl> + <dt><code>xml_schema::flags::dont_initialize</code></dt> + <dd>Do not initialize the Xerces-C++ runtime.</dd> + + <dt><code>xml_schema::flags::dont_pretty_print</code></dt> + <dd>Do not add extra spaces or new lines that make the resulting XML + slightly bigger but easier to read.</dd> + + <dt><code>xml_schema::flags::no_xml_declaration</code></dt> + <dd>Do not write XML declaration (<?xml ... ?>).</dd> + </dl> + + <p>You can pass several flags by combining them using the bit-wise OR + operator. For example:</p> + + <pre class="c++"> +std::unique_ptr<type> r = ... +std::ofstream ofs ("test.xml"); +xml_schema::namespace_infomap map; +name (ofs, + *r, + map, + "UTF-8", + xml_schema::flags::no_xml_declaration | + xml_schema::flags::dont_pretty_print); + </pre> + + <p>For more information on the Xerces-C++ runtime initialization + refer to <a href="#4.1">Section 4.1, "Initializing the Xerces-C++ + Runtime"</a>. + </p> + + <h2><a name="4.4">4.4 Error Handling</a></h2> + + <p>As with the parsing functions (see <a href="#3.3">Section 3.3, + "Error Handling"</a>), to better understand error handling and + reporting strategies employed by the serialization functions, it + is useful to know that the transformation of a statically-typed + tree to an XML instance document happens in two stages. The first + stage, performed by the generated code, consist of building a DOM + instance from the statically-typed tree . For short, we will call + this stage the Tree-DOM stage. The second stage, performed by + Xerces-C++, consists of serializing the DOM instance into the XML + document. We will call this stage the DOM-XML stage. + </p> + + <p>All serialization functions except the two that serialize into + a DOM instance come in overloaded triples. The first function + in such a triple reports error conditions exclusively by throwing + exceptions. It accumulates all the serialization errors of the + DOM-XML stage and throws them in a single instance of the + <code>xml_schema::serialization</code> exception (described below). + The second and the third functions in the triple use callback + interfaces to report serialization errors and warnings. The two + callback interfaces are <code>xml_schema::error_handler</code> and + <code>xercesc::DOMErrorHandler</code>. The + <code>xml_schema::error_handler</code> interface is described in + <a href="#3.3">Section 3.3, "Error Handling"</a>. For more information + on the <code>xercesc::DOMErrorHandler</code> interface refer to the + Xerces-C++ documentation. + </p> + + <p>The Tree-DOM stage reports error conditions exclusively by throwing + exceptions. Individual exceptions thrown by the serialization functions + are described in the following sub-sections. + </p> + + <h3><a name="4.4.1">4.4.1 <code>xml_schema::serialization</code></a></h3> + + <pre class="c++"> +struct serialization: virtual exception +{ + serialization (); + serialization (const diagnostics&); + + const diagnostics& + diagnostics () const; + + virtual const char* + what () const throw (); +}; + </pre> + + <p>The <code>xml_schema::diagnostics</code> class is described in + <a href="#3.3.1">Section 3.3.1, "<code>xml_schema::parsing</code>"</a>. + The <code>xml_schema::serialization</code> exception is thrown if + there were serialization errors reported during the DOM-XML stage. + If no callback interface was provided to the serialization function, + the exception contains a list of errors and warnings accessible using + the <code>diagnostics</code> function. + </p> + + + <h3><a name="4.4.2">4.4.2 <code>xml_schema::unexpected_element</code></a></h3> + + <p>The <code>xml_schema::unexpected_element</code> exception is + described in <a href="#3.3.3">Section 3.3.3, + "<code>xml_schema::unexpected_element</code>"</a>. It is thrown + by the serialization functions during the Tree-DOM stage if the + root element name of the provided DOM instance does not match with + the name of the element this serialization function is for. + </p> + + <h3><a name="4.4.3">4.4.3 <code>xml_schema::no_type_info</code></a></h3> + + <p>The <code>xml_schema::no_type_info</code> exception is + described in <a href="#3.3.7">Section 3.3.7, + "<code>xml_schema::no_type_info</code>"</a>. It is thrown + by the serialization functions during the Tree-DOM stage when there + is no type information associated with a dynamic type of an + element. Usually, catching this exception means that you haven't + linked the code generated from the schema defining the type in + question with your application or this schema has been compiled + without the <code>--generate-polymorphic</code> option. + </p> + + <h2><a name="4.5">4.5 Serializing to <code>std::ostream</code></a></h2> + + <p>In order to serialize to <code>std::ostream</code> you will need + an object model, an output stream and, optionally, a namespace + infomap. For instance:</p> + + <pre class="c++"> +// Obtain the object model. +// +std::unique_ptr<type> r = ... + +// Prepare namespace mapping and schema location information. +// +xml_schema::namespace_infomap map; + +map["t"].name = "https://www.codesynthesis.com/test"; +map["t"].schema = "test.xsd"; + +// Write it out. +// +name (std::cout, *r, map); + </pre> + + <p>Note that the output stream is treated as a binary stream. This + becomes important when you use a character encoding that is wider + than 8-bit <code>char</code>, for instance UTF-16 or UCS-4. For + example, things will most likely break if you try to serialize + to <code>std::ostringstream</code> with UTF-16 or UCS-4 as an + encoding. This is due to the special value, + <code>'\0'</code>, that will most likely occur as part of such + serialization and it won't have the special meaning assumed by + <code>std::ostringstream</code>. + </p> + + + <h2><a name="4.6">4.6 Serializing to <code>xercesc::XMLFormatTarget</code></a></h2> + + <p>Serializing to an <code>xercesc::XMLFormatTarget</code> instance + is similar the <code>std::ostream</code> case. For instance: + </p> + + <pre class="c++"> +using std::unique_ptr; + +// Obtain the object model. +// +unique_ptr<type> r = ... + +// Prepare namespace mapping and schema location information. +// +xml_schema::namespace_infomap map; + +map["t"].name = "https://www.codesynthesis.com/test"; +map["t"].schema = "test.xsd"; + +using namespace xercesc; + +XMLPlatformUtils::Initialize (); + +{ + // Choose a target. + // + unique_ptr<XMLFormatTarget> ft; + + if (argc != 2) + { + ft = unique_ptr<XMLFormatTarget> (new StdOutFormatTarget ()); + } + else + { + ft = unique_ptr<XMLFormatTarget> ( + new LocalFileFormatTarget (argv[1])); + } + + // Write it out. + // + name (*ft, *r, map); +} + +XMLPlatformUtils::Terminate (); + </pre> + + <p>Note that we had to initialize the Xerces-C++ runtime before we + could call this serialization function.</p> + + <h2><a name="4.7">4.7 Serializing to DOM</a></h2> + + <p>The mapping provides two overloaded functions that implement + serialization to a DOM instance. The first creates a DOM instance + for you and the second serializes to an existing DOM instance. + While serializing to a new DOM instance is similar to serializing + to <code>std::ostream</code> or <code>xercesc::XMLFormatTarget</code>, + serializing to an existing DOM instance requires quite a bit of work + from your side. You will need to set all the custom namespace mapping + attributes as well as the <code>schemaLocation</code> and/or + <code>noNamespaceSchemaLocation</code> attributes. The following + listing should give you an idea about what needs to be done: + </p> + + <pre class="c++"> +// Obtain the object model. +// +std::unique_ptr<type> r = ... + +using namespace xercesc; + +XMLPlatformUtils::Initialize (); + +{ + // Create a DOM instance. Set custom namespace mapping and schema + // location attributes. + // + DOMDocument& doc = ... + + // Serialize to DOM. + // + name (doc, *r); + + // Serialize the DOM document to XML. + // + ... +} + +XMLPlatformUtils::Terminate (); + </pre> + + <p>For more information on how to create and serialize a DOM instance + refer to the Xerces-C++ documentation. In addition, the + <a href="http://wiki.codesynthesis.com/Tree/FAQ">C++/Tree Mapping + FAQ</a> shows how to implement these operations using the XSD + runtime utilities. + </p> + + <h1><a name="5">5 Additional Functionality</a></h1> + + <p>The C++/Tree mapping provides a number of optional features + that can be useful in certain situations. They are described + in the following sections.</p> + + <h2><a name="5.1">5.1 DOM Association</a></h2> + + <p>Normally, after parsing is complete, the DOM document which + was used to extract the data is discarded. However, the parsing + functions can be instructed to preserve the DOM document + and create an association between the DOM nodes and object model + nodes. When there is an association between the DOM and + object model nodes, you can obtain the corresponding DOM element + or attribute node from an object model node as well as perform + the reverse transition: obtain the corresponding object model + from a DOM element or attribute node.</p> + + <p>Maintaining DOM association is normally useful when the application + needs access to XML constructs that are not preserved in the + object model, for example, XML comments. + Another useful aspect of DOM association is the ability of the + application to navigate the document tree using the generic DOM + interface (for example, with the help of an XPath processor) + and then move back to the statically-typed object model. Note + also that while you can change the underlying DOM document, + these changes are not reflected in the object model and will + be ignored during serialization. If you need to not only access + but also modify some aspects of XML that are not preserved in + the object model, then type customization with custom parsing + constructors and serialization operators should be used instead.</p> + + <p>To request DOM association you will need to pass the + <code>xml_schema::flags::keep_dom</code> flag to one of the + parsing functions (see <a href="#3.2">Section 3.2, + "Flags and Properties"</a> for more information). In this case the + DOM document is retained and will be released when the object model + is deleted. Note that since DOM nodes "out-live" the parsing function + call, you need to initialize the Xerces-C++ runtime before calling + one of the parsing functions with the <code>keep_dom</code> flag and + terminate it after the object model is destroyed (see + <a href="#3.1">Section 3.1, "Initializing the Xerces-C++ Runtime"</a>).</p> + + <p>If the <code>keep_dom</code> flag is passed + as the second argument to the copy constructor and the copy + being made is of a complete tree, then the DOM association + is also maintained in the copy by cloning the underlying + DOM document and reestablishing the associations. For example:</p> + + <pre class="c++"> +using namespace xercesc; + +XMLPlatformUtils::Initialize (); + +{ + // Parse XML to object model. + // + std::unique_ptr<type> r (root ( + "root.xml", + xml_schema::flags::keep_dom | + xml_schema::flags::dont_initialize)); + + // Copy without DOM association. + // + type copy1 (*r); + + // Copy with DOM association. + // + type copy2 (*r, xml_schema::flags::keep_dom); +} + +XMLPlatformUtils::Terminate (); + </pre> + + + <p>To obtain the corresponding DOM node from an object model node + you will need to call the <code>_node</code> accessor function + which returns a pointer to <code>DOMNode</code>. You can then query + this DOM node's type and cast it to either <code>DOMAttr*</code> + or <code>DOMElement*</code>. To obtain the corresponding object + model node from a DOM node, the DOM user data API is used. The + <code>xml_schema::dom::tree_node_key</code> variable contains + the key for object model nodes. The following schema and code + fragment show how to navigate from DOM to object model nodes + and in the opposite direction:</p> + + <pre class="xml"> +<complexType name="object"> + <sequence> + <element name="a" type="string"/> + </sequence> +</complexType> + +<element name="root" type="object"/> + </pre> + + <pre class="c++"> +using namespace xercesc; + +XMLPlatformUtils::Initialize (); + +{ + // Parse XML to object model. + // + std::unique_ptr<type> r (root ( + "root.xml", + xml_schema::flags::keep_dom | + xml_schema::flags::dont_initialize)); + + DOMNode* n = r->_node (); + assert (n->getNodeType () == DOMNode::ELEMENT_NODE); + DOMElement* re = static_cast<DOMElement*> (n); + + // Get the 'a' element. Note that it is not necessarily the + // first child node of 'root' since there could be whitespace + // nodes before it. + // + DOMElement* ae; + + for (n = re->getFirstChild (); n != 0; n = n->getNextSibling ()) + { + if (n->getNodeType () == DOMNode::ELEMENT_NODE) + { + ae = static_cast<DOMElement*> (n); + break; + } + } + + // Get from the 'a' DOM element to xml_schema::string object model + // node. + // + xml_schema::type& t ( + *reinterpret_cast<xml_schema::type*> ( + ae->getUserData (xml_schema::dom::tree_node_key))); + + xml_schema::string& a (dynamic_cast<xml_schema::string&> (t)); +} + +XMLPlatformUtils::Terminate (); + </pre> + + <p>The 'mixed' example which can be found in the XSD distribution + shows how to handle the mixed content using DOM association.</p> + + <h2><a name="5.2">5.2 Binary Serialization</a></h2> + + <p>Besides reading from and writing to XML, the C++/Tree mapping + also allows you to save the object model to and load it from a + number of predefined as well as custom data representation + formats. The predefined binary formats are CDR (Common Data + Representation) and XDR (eXternal Data Representation). A + custom format can easily be supported by providing + insertion and extraction operators for basic types.</p> + + <p>Binary serialization saves only the data without any meta + information or markup. As a result, saving to and loading + from a binary representation can be an order of magnitude + faster than parsing and serializing the same data in XML. + Furthermore, the resulting representation is normally several + times smaller than the equivalent XML representation. These + properties make binary serialization ideal for internal data + exchange and storage. A typical application that uses this + facility stores the data and communicates within the + system using a binary format and reads/writes the data + in XML when communicating with the outside world.</p> + + <p>In order to request the generation of insertion operators and + extraction constructors for a specific predefined or custom + data representation stream, you will need to use the + <code>--generate-insertion</code> and <code>--generate-extraction</code> + compiler options. See the + <a href="https://www.codesynthesis.com/projects/xsd/documentation/xsd.xhtml">XSD + Compiler Command Line Manual</a> for more information.</p> + + <p>Once the insertion operators and extraction constructors are + generated, you can use the <code>xml_schema::istream</code> + and <code>xml_schema::ostream</code> wrapper stream templates + to save the object model to and load it from a specific format. + The following code fragment shows how to do this using ACE + (Adaptive Communication Environment) CDR streams as an example:</p> + + <pre class="xml"> +<complexType name="object"> + <sequence> + <element name="a" type="string"/> + <element name="b" type="int"/> + </sequence> +</complexType> + +<element name="root" type="object"/> + </pre> + + <pre class="c++"> +// Parse XML to object model. +// +std::unique_ptr<type> r (root ("root.xml")); + +// Save to a CDR stream. +// +ACE_OutputCDR ace_ocdr; +xml_schema::ostream<ACE_OutputCDR> ocdr (ace_ocdr); + +ocdr << *r; + +// Load from a CDR stream. +// +ACE_InputCDR ace_icdr (buf, size); +xml_schema::istream<ACE_InputCDR> icdr (ace_icdr); + +std::unique_ptr<object> copy (new object (icdr)); + +// Serialize to XML. +// +root (std::cout, *copy); + </pre> + + <p>The XSD distribution contains a number of examples that + show how to save the object model to and load it from + CDR, XDR, and a custom format.</p> + + <!-- Appendix A --> + + + <h1><a name="A">Appendix A — Default and Fixed Values</a></h1> + + <p>The following table summarizes the effect of default and fixed + values (specified with the <code>default</code> and <code>fixed</code> + attributes, respectively) on attribute and element values. The + <code>default</code> and <code>fixed</code> attributes are mutually + exclusive. It is also worthwhile to note that the fixed value semantics + is a superset of the default value semantics. + </p> + + <!-- border="1" is necessary for html2ps --> + <table id="default-fixed" border="1"> + <tr> + <th></th> + <th></th> + <th colspan="2">default</th> + <th colspan="2">fixed</th> + </tr> + + <!-- element --> + + <tr> + <th rowspan="4">element</th> + <th rowspan="2">not present</th> + <th>optional</th> + <th>required</th> + <th>optional</th> + <th>required</th> + </tr> + <tr> + <td>not present</td> + <td>invalid instance</td> + <td>not present</td> + <td>invalid instance</td> + </tr> + + + <tr> + <th>empty</th> + <td colspan="2">default value is used</td> + <td colspan="2">fixed value is used</td> + </tr> + + <tr> + <th>value</th> + <td colspan="2">value is used</td> + <td colspan="2">value is used provided it's the same as fixed</td> + </tr> + + <!-- attribute --> + + <!-- element --> + + <tr> + <th rowspan="4">attribute</th> + <th rowspan="2">not present</th> + <th>optional</th> + <th>required</th> + <th>optional</th> + <th>required</th> + </tr> + <tr> + <td>default value is used</td> + <td>invalid schema</td> + <td>fixed value is used</td> + <td>invalid instance</td> + </tr> + + + <tr> + <th>empty</th> + <td colspan="2">empty value is used</td> + <td colspan="2">empty value is used provided it's the same as fixed</td> + </tr> + + <tr> + <th>value</th> + <td colspan="2">value is used</td> + <td colspan="2">value is used provided it's the same as fixed</td> + </tr> + + </table> + + </div> +</div> + + +</body> +</html> diff --git a/xsd/doc/cxx/tree/manual/manual.html2ps.in b/xsd/doc/cxx/tree/manual/manual.html2ps.in new file mode 100644 index 0000000..5629122 --- /dev/null +++ b/xsd/doc/cxx/tree/manual/manual.html2ps.in @@ -0,0 +1,66 @@ +@@html2ps { + option { + toc: hb; + colour: 1; + hyphenate: 1; + titlepage: 1; + } + + datefmt: "%B %Y"; + + titlepage { + content: " +<div align=center> + <h1><big>C++/Tree Mapping User Manual</big></h1> + <h1> </h1> + <h1> </h1> + <h1> </h1> + <h1> </h1> + <h1> </h1> + <h1> </h1> + <h1> </h1> +</div> + <p>Revision $[revision] $D</p> + <p>Copyright © @copyright@.</p> + + <p>Permission is granted to copy, distribute and/or modify this + document under the terms of the + <a href='https://www.codesynthesis.com/licenses/fdl-1.2.txt'>GNU Free + Documentation License, version 1.2</a>; with no Invariant Sections, + no Front-Cover Texts and no Back-Cover Texts. + </p> + + <p>This document is available in the following formats: + <a href='https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/index.xhtml'>XHTML</a>, + <a href='https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/cxx-tree-manual.pdf'>PDF</a>, and + <a href='https://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/cxx-tree-manual.ps'>PostScript</a>.</p>"; + } + + toc { + indent: 2em; + } + + header { + odd-right: $H; + even-left: $H; + } + + footer { + odd-left: $D; + odd-center: $T, v$[revision]; + odd-right: $N; + + even-left: $N; + even-center: $T, v$[revision]; + even-right: $D; + } +} + +body { + font-size: 12pt; + text-align: justify; +} + +pre { + font-size: 10pt; +} diff --git a/xsd/doc/default.css b/xsd/doc/default.css new file mode 100644 index 0000000..bb3805b --- /dev/null +++ b/xsd/doc/default.css @@ -0,0 +1,319 @@ +html { + margin : 0; + padding : 0; + background : white; +} + +body { + font-family : "Lucida Grande", Verdana, "Bitstream Vera Sans", sans-serif; + font-weight : normal; + font-size : 13px; + line-height : 19px; + + color : black; + + margin : 0 2em 0 2em; + padding : 0; +} + + +body { + min-width: 40em; +} + +#container { + max-width : 46em; + margin : 0 auto; + padding : 0 1em 0 1em; +} + + + +/* + * Footer + * + */ +#footer { + color : #3a84a7; + + padding : 1em 0 0.5em 0; + + font-size : 10px; + line-height : 15px; + + text-align: center; +} + +#footer a:link, #footer a:visited { + + color:#1d6699; + text-decoration: underline; +} + +#footer a { + margin-left: 0.7em; + margin-right: 0.7em; +} + +#footer p { + padding: 0; + margin: 0.3em 0 0 0; +} + +/* Distribution terms. */ +#footer #terms { + text-align: justify; + + font-size : 110%; + font-family : monospace; + + padding : 1em 0 0.5em 0; +} + + +/* + * Content + * + */ + +#content { + padding : 0em 0.1em 0 1.3em; + margin : 1.4em 0 0 0; +} + +#content p, +#content ol, +#content ul, +#content dl { + text-align: justify; +} + +#content h1 { + margin-left: -0.89em; +} + +a:link { + color:#0536d2; +} + + +/* + * Headings + * + */ + +h1, h2, h3, h4, h5, h6 { + font-weight : 500; +} + +h1 { font-size : 155%; } +h2 { font-size : 130%; } +h3 { font-size : 125%; } +h4 { font-size : 110%; } +h5 { font-size : 106%; } +h6 { font-size : 100%; } + +h1 { margin : 1.8em 0 0.8em 0;} +h2 { margin-top : 1.4em;} +h3 { margin-top : 1em;} + +p.indent { + margin-left : 1.5em; +} + + +/* + * Fix for IE 5.5 table font problem + * + */ + +table { + font-size : 13px; +} + + +/* + * table of content + * + */ + +ul.toc li { + padding : .4em 0em 0em 0em; +} + + +/* Toc links don't need to show when they are visited. */ +.toc a:visited { + color:#0536d2; +} + + +/* + * lists + * + */ + + +/* list of links */ +ul.menu { + list-style-type : none; +} + +ul.menu li { + padding-top : 0.3em; + padding-bottom : 0.3em; +} + + + +/* @@ I should probably use child selector here */ +/* list with multiline list-elements */ +ul.multiline li, ol.multiline li, dl.multiline dd { + padding-top : 0.16em; + padding-bottom : 0.16em; + + font-size : 11px; + line-height : 15px; +} + + + +/* C++ code snippet */ +pre.cxx { + margin-top : 0em; + margin-bottom : 2em; + + margin-left : 1em; +} + + + +/* make code snippet */ +pre.make { + margin-top : 0em; + margin-bottom : 2em; + + margin-left : 1em; +} + + + +/* terminal output */ +pre.term { + margin-top : 0em; + margin-bottom : 2em; + + margin-left : 1em; +} + + +/* Images */ +div.center { + text-align: center; +} + +/* Document info. */ +#docinfo { + margin-top: 4em; + border-top: 1px dashed #000000; + font-size: 70%; +} + + +/* Footnote */ + +#footnote { + margin-top : 2.5em; +} + +#footnote hr, hr.footnote { + margin-left: 0; + margin-bottom: 0.6em; + width: 8em; + border-top: 1px solid #000000; + border-right: none; + border-bottom: none; + border-left: none; + +} + +#footnote ol { + margin-left: 0; + padding-left: 1.45em; +} + +#footnote li { + text-align : left; + font-size : 11px; + line-height : 15px; + + padding : .4em 0 .4em 0; +} + + +/* Normal table with borders, etc. */ + +table.std { + margin: 2em 0 2em 0; + + border-collapse : collapse; + border : 1px solid; + border-color : #000000; + + font-size : 11px; + line-height : 14px; +} + +table.std th, table.std td { + border : 1px solid; + padding : 0.6em 0.8em 0.6em 0.8em; +} + +table.std th { + background : #cde8f6; +} + +table.std td { + text-align: left; +} + + +/* + * "item | description" table. + * + */ + +table.description { + border-style : none; + border-collapse : separate; + border-spacing : 0; + + font-size : 13px; + + margin : 0.6em 0 0.6em 0; + padding : 0 0 0 0; +} + +table.description tr { + padding : 0 0 0 0; + margin : 0 0 0 0; +} + +table.description * td, table.description * th { + border-style : none; + margin : 0 0 0 0; + vertical-align : top; +} + +table.description * th { + font-weight : normal; + padding : 0.4em 1em 0.4em 0; + text-align : left; + white-space : nowrap; + background : none; +} + +table.description * td { + padding : 0.4em 0 0.4em 1em; + text-align : justify; +} diff --git a/xsd/doc/pregenerated/xsd.1 b/xsd/doc/pregenerated/xsd.1 new file mode 100644 index 0000000..580ac78 --- /dev/null +++ b/xsd/doc/pregenerated/xsd.1 @@ -0,0 +1,1500 @@ +.\" Process this file with +.\" groff -man -Tascii xsd.1 +.\" +.TH XSD 1 "January 2023" "XSD 4.2.1-a.0" +.SH NAME +xsd \- W3C XML Schema to C++ Compiler +.\" +.\" +.\" +.\"-------------------------------------------------------------------- +.SH SYNOPSIS +.\"-------------------------------------------------------------------- +.B xsd +.I command +.B [ +.I options +.B ] +.I file +.B [ +.I file +.B ...] +.in +.B xsd help +.B [ +.I command +.B ] +.in +.B xsd version +.\" +.\" +.\" +.\"-------------------------------------------------------------------- +.SH DESCRIPTION +.\"-------------------------------------------------------------------- +.B xsd +generates vocabulary-specific, statically-typed C++ mapping from W3C XML +Schema definitions. Particular mapping to produce is selected by a +.IR command . +Each mapping has a number of mapping-specific +.I options +that should appear, if any, after the +.IR command . +Input files should be W3C XML Schema definitions. The exact set of the +generated files depends on the selected mapping and options. +.\" +.\" +.\" +.\"-------------------------------------------------------------------- +.SH COMMANDS +.\"-------------------------------------------------------------------- +.IP \fBcxx-tree\fR +Generate the C++/Tree mapping. For each input file in the form +.B name.xsd +the following C++ files are generated: +.B name.hxx +(header file), +.B name.ixx +(inline file, generated only if the +.B --generate-inline +option is specified), +.B name.cxx +(source file), and +.B name-fwd.hxx +(forward declaration file, generated only if the +.B --generate-forward +option is specified). + +.IP \fBcxx-parser\fR +Generate the C++/Parser mapping. For each input file in the form +.B name.xsd +the following C++ files are generated: +.B name-pskel.hxx +(parser skeleton header file), +.B name-pskel.ixx +(parser skeleton inline file, generated only if the +.B --generate-inline +option is specified), and +.B name-pskel.cxx +(parser skeleton source file). If the +.B --generate-noop-impl +or +.B --generate-print-impl +option is specified, the following additional sample implementation files +are generated: +.B name-pimpl.hxx +(parser implementation header file) and +.B name-pimpl.cxx +(parser implementation source file). If the +.B --generate-test-driver +option is specified, the additional +.B name-driver.cxx +test driver file is generated. + +.IP \fBhelp\fR +Print usage information and exit. Use +.PP +.RS +.RS 3 +.B xsd help +.I command +.RE +.PP +for command-specific help. +.RE +.IP \fBversion\fR +Print version and exit. +.\"-------------------------------------------------------------------- +.SH OPTIONS +.\"-------------------------------------------------------------------- +Command-specific +.IR options , +if any, should appear after the corresponding +.IR command . + +.\" +.\" Common options. +.\" +.SS common options +. +.IP "\fB--std\fR \fIversion\fR" +Specify the C++ standard that the generated code should conform to\. Valid +values are \fBc++98\fR, \fBc++11\fR (default), \fBc++14\fR, \fBc++17\fR, +\fBc++20\fR, and \fBc++23\fR\. + +The C++ standard affects various aspects of the generated code that are +discussed in more detail in various mapping-specific documentation\. Overall, +when C++11 is selected, the generated code relies on the move semantics and +uses \fBstd::unique_ptr\fR instead of deprecated \fBstd::auto_ptr\fR\. +Currently, there is no difference between the C++11 and the later standards +modes\. + +When the C++11 mode is selected, you normally don't need to perform any extra +steps other than enable C++11 in your C++ compiler, if required\. The XSD +compiler will automatically add the necessary macro defines to the generated +header files that will switch the header-only XSD runtime library +(\fBlibxsd\fR) to the C++11 mode\. However, if you include any of the XSD +runtime headers directly in your application (normally you just include the +generated headers), then you will need to define the \fBXSD_CXX11\fR macro for +your entire project\. +.IP "\fB--char-type\fR \fItype\fR" +Generate code using the provided character \fItype\fR instead of the default +\fBchar\fR\. Valid values are \fBchar\fR and \fBwchar_t\fR\. +.IP "\fB--char-encoding\fR \fIenc\fR" +Specify the character encoding that should be used in the generated code\. +Valid values for the \fBchar\fR character type are \fButf8\fR (default), +\fBiso8859-1\fR, \fBlcp\fR (Xerces-C++ local code page), and \fBcustom\fR\. If +you pass \fBcustom\fR as the value then you will need to include the +transcoder implementation header for your encoding at the beginning of the +generated header files (see the \fB--hxx-prologue\fR option)\. + +For the \fBwchar_t\fR character type the only valid value is \fBauto\fR and +the encoding is automatically selected between UTF-16 and UTF-32/UCS-4, +depending on the \fBwchar_t\fR type size\. +.IP "\fB--output-dir\fR \fIdir\fR" +Write generated files to \fIdir\fR instead of the current directory\. +.IP "\fB--generate-inline\fR" +Generate simple functions inline\. This option triggers creation of the inline +file\. +.IP "\fB--generate-xml-schema\fR" +Generate a C++ header file as if the schema being compiled defines the XML +Schema namespace\. For the C++/Tree mapping, the resulting file will contain +definitions for all XML Schema built-in types\. For the C++/Parser mapping, +the resulting file will contain definitions for all the parser skeletons and +implementations corresponding to the XML Schema built-in types\. + +The schema file provided to the compiler need not exist and is only used to +derive the name of the resulting header file\. Use the +\fB--extern-xml-schema\fR option to include this file in the generated files +for other schemas\. +.IP "\fB--extern-xml-schema\fR \fIfile\fR" +Include a header file derived from \fIfile\fR instead of generating the XML +Schema namespace mapping inline\. The provided file need not exist and is only +used to derive the name of the included header file\. Use the +\fB--generate-xml-schema\fR option to generate this header file\. +.IP "\fB--namespace-map\fR \fIxns\fR=\fIcns\fR" +Map XML Schema namespace \fIxns\fR to C++ namespace \fIcns\fR\. Repeat this +option to specify mapping for more than one XML Schema namespace\. For +example, the following option: + +\fB--namespace-map http://example\.com/foo/bar=foo::bar\fR + +Will map the \fBhttp://example\.com/foo/bar\fR XML Schema namespace to the +\fBfoo::bar\fR C++ namespace\. +.IP "\fB--namespace-regex\fR \fIregex\fR" +Add \fIregex\fR to the list of regular expressions used to translate XML +Schema namespace names to C++ namespace names\. \fIregex\fR is a Perl-like +regular expression in the form +\fB/\fR\fIpattern\fR\fB/\fR\fIreplacement\fR\fB/\fR\fR\. Any character can be +used as a delimiter instead of '\fB/\fR'\. Escaping of the delimiter character +in \fIpattern\fR or \fIreplacement\fR is not supported\. + +All the regular expressions are pushed into a stack with the last specified +expression considered first\. The first match that succeeds is used\. Regular +expressions are applied to a string in the form + +\fIfilename\fR \fInamespace\fR\fR + +For example, if you have file \fBhello\.xsd\fR with namespace +\fBhttp://example\.com/hello\fR and you run \fBxsd\fR on this file, then the +string in question will be: + +\fBhello\.xsd\. http://example\.com/hello\fR + +For the built-in XML Schema namespace the string is: + +\fBXMLSchema\.xsd http://www\.w3\.org/2001/XMLSchema\fR + +The following three steps are performed for each regular expression until the +match is found: + +1\. The expression is applied and if the result is empty the next expression +is considered\. + +2\. All '\fB/\fR' are replaced with '\fB::\fR'\. + +3\. The result is verified to be a valid C++ scope name (e\.g\., +\fBfoo::bar\fR)\. If this test succeeds, the result is used as a C++ namespace +name\. + +As an example, the following expression maps XML Schema namespaces in the +form \fBhttp://example\.com/foo/bar\fR to C++ namespaces in the form +\fBfoo::bar\fR: + +\fB%\.* http://example\.com/(\.+)%$1%\fR + +See also the REGEX AND SHELL QUOTING section below\. +.IP "\fB--namespace-regex-trace\fR" +Trace the process of applying regular expressions specified with the +\fB--namespace-regex\fR option\. Use this option to find out why your regular +expressions don't do what you expected them to do\. +.IP "\fB--reserved-name\fR \fIn\fR[=\fIr\fR]" +Add name \fIn\fR to the list of names that should not be used as identifiers\. +The name can optionally be followed by \fB=\fR and the replacement name +\fIr\fR that should be used instead\. All the C++ keywords are already in this +list\. +.IP "\fB--include-with-brackets\fR" +Use angle brackets (<>) instead of quotes ("") in generated \fB#include\fR +directives\. +.IP "\fB--include-prefix\fR \fIprefix\fR" +Add \fIprefix\fR to generated \fB#include\fR directive paths\. + +For example, if you had the following import element in your schema + +\fB<import namespace="\.\.\." schemaLocation="base\.xsd"/>\fR + +and compiled this fragment with \fB--include-prefix schemas/\fR, then the +include directive in the generated code would be: + +\fB#include "schemas/base\.hxx"\fR +.IP "\fB--include-regex\fR \fIregex\fR" +Add \fIregex\fR to the list of regular expressions used to transform +\fB#include\fR directive paths\. \fIregex\fR is a Perl-like regular expression +in the form \fB/\fR\fIpattern\fR\fB/\fR\fIreplacement\fR\fB/\fR\fR\. Any +character can be used as a delimiter instead of '\fB/\fR'\. Escaping of the +delimiter character in \fIpattern\fR or \fIreplacement\fR is not supported\. + +All the regular expressions are pushed into a stack with the last specified +expression considered first\. The first match that succeeds is used\. + +As an example, the following expression transforms paths in the form +\fBschemas/foo/bar\fR to paths in the form \fBgenerated/foo/bar\fR: + +\fB%schemas/(\.+)%generated/$1%\fR + +See also the REGEX AND SHELL QUOTING section below\. +.IP "\fB--include-regex-trace\fR" +Trace the process of applying regular expressions specified with the +\fB--include-regex\fR option\. Use this option to find out why your regular +expressions don't do what you expected them to do\. +.IP "\fB--guard-prefix\fR \fIprefix\fR" +Add \fIprefix\fR to generated header inclusion guards\. The prefix is +transformed to upper case and characters that are illegal in a preprocessor +macro name are replaced with underscores\. If this option is not specified +then the directory part of the input schema file is used as a prefix\. +.IP "\fB--hxx-suffix\fR \fIsuffix\fR" +Use the provided \fIsuffix\fR instead of the default \fB\.hxx\fR to construct +the name of the header file\. Note that this suffix is also used to construct +names of header files corresponding to included/imported schemas\. +.IP "\fB--ixx-suffix\fR \fIsuffix\fR" +Use the provided \fIsuffix\fR instead of the default \fB\.ixx\fR to construct +the name of the inline file\. +.IP "\fB--cxx-suffix\fR \fIsuffix\fR" +Use the provided \fIsuffix\fR instead of the default \fB\.cxx\fR to construct +the name of the source file\. +.IP "\fB--fwd-suffix\fR \fIsuffix\fR" +Use the provided \fIsuffix\fR instead of the default \fB-fwd\.hxx\fR to +construct the name of the forward declaration file\. +.IP "\fB--hxx-regex\fR \fIregex\fR" +Use the provided expression to construct the name of the header file\. +\fIregex\fR is a Perl-like regular expression in the form +\fB/\fR\fIpattern\fR\fB/\fR\fIreplacement\fR\fB/\fR\fR\. Note that this +expression is also used to construct names of header files corresponding to +included/imported schemas\. See also the REGEX AND SHELL QUOTING section +below\. +.IP "\fB--ixx-regex\fR \fIregex\fR" +Use the provided expression to construct the name of the inline file\. +\fIregex\fR is a Perl-like regular expression in the form +\fB/\fR\fIpattern\fR\fB/\fR\fIreplacement\fR\fB/\fR\fR\. See also the REGEX +AND SHELL QUOTING section below\. +.IP "\fB--cxx-regex\fR \fIregex\fR" +Use the provided expression to construct the name of the source file\. +\fIregex\fR is a Perl-like regular expression in the form +\fB/\fR\fIpattern\fR\fB/\fR\fIreplacement\fR\fB/\fR\fR\. See also the REGEX +AND SHELL QUOTING section below\. +.IP "\fB--fwd-regex\fR \fIregex\fR" +Use the provided expression to construct the name of the forward declaration +file\. \fIregex\fR is a Perl-like regular expression in the form +\fB/\fR\fIpattern\fR\fB/\fR\fIreplacement\fR\fB/\fR\fR\. See also the REGEX +AND SHELL QUOTING section below\. +.IP "\fB--hxx-prologue\fR \fItext\fR" +Insert \fItext\fR at the beginning of the header file\. +.IP "\fB--ixx-prologue\fR \fItext\fR" +Insert \fItext\fR at the beginning of the inline file\. +.IP "\fB--cxx-prologue\fR \fItext\fR" +Insert \fItext\fR at the beginning of the source file\. +.IP "\fB--fwd-prologue\fR \fItext\fR" +Insert \fItext\fR at the beginning of the forward declaration file\. +.IP "\fB--prologue\fR \fItext\fR" +Insert \fItext\fR at the beginning of each generated file for which there is +no file-specific prologue\. +.IP "\fB--hxx-epilogue\fR \fItext\fR" +Insert \fItext\fR at the end of the header file\. +.IP "\fB--ixx-epilogue\fR \fItext\fR" +Insert \fItext\fR at the end of the inline file\. +.IP "\fB--cxx-epilogue\fR \fItext\fR" +Insert \fItext\fR at the end of the source file\. +.IP "\fB--fwd-epilogue\fR \fItext\fR" +Insert \fItext\fR at the end of the forward declaration file\. +.IP "\fB--epilogue\fR \fItext\fR" +Insert \fItext\fR at the end of each generated file for which there is no +file-specific epilogue\. +.IP "\fB--hxx-prologue-file\fR \fIfile\fR" +Insert the content of the \fIfile\fR at the beginning of the header file\. +.IP "\fB--ixx-prologue-file\fR \fIfile\fR" +Insert the content of the \fIfile\fR at the beginning of the inline file\. +.IP "\fB--cxx-prologue-file\fR \fIfile\fR" +Insert the content of the \fIfile\fR at the beginning of the source file\. +.IP "\fB--fwd-prologue-file\fR \fIfile\fR" +Insert the content of the \fIfile\fR at the beginning of the forward +declaration file\. +.IP "\fB--prologue-file\fR \fIfile\fR" +Insert the content of the \fIfile\fR at the beginning of each generated file +for which there is no file-specific prologue file\. +.IP "\fB--hxx-epilogue-file\fR \fIfile\fR" +Insert the content of the \fIfile\fR at the end of the header file\. +.IP "\fB--ixx-epilogue-file\fR \fIfile\fR" +Insert the content of the \fIfile\fR at the end of the inline file\. +.IP "\fB--cxx-epilogue-file\fR \fIfile\fR" +Insert the content of the \fIfile\fR at the end of the source file\. +.IP "\fB--fwd-epilogue-file\fR \fIfile\fR" +Insert the content of the \fIfile\fR at the end of the forward declaration +file\. +.IP "\fB--epilogue-file\fR \fIfile\fR" +Insert the content of the \fIfile\fR at the end of each generated file for +which there is no file-specific epilogue file\. +.IP "\fB--export-symbol\fR \fIsymbol\fR" +Insert \fIsymbol\fR in places where DLL export/import control statements +(\fB__declspec(dllexport/dllimport)\fR) are necessary\. +.IP "\fB--export-xml-schema\fR" +Export/import types in the XML Schema namespace using the export symbol +provided with the \fB--export-symbol\fR option\. The \fBXSD_NO_EXPORT\fR macro +can be used to omit this code during C++ compilation, which may be useful if +you would like to use the same generated code across multiple platforms\. +.IP "\fB--export-maps\fR" +Export polymorphism support maps from a Win32 DLL into which this generated +code is placed\. This is necessary when your type hierarchy is split across +several DLLs since otherwise each DLL will have its own set of maps\. In this +situation the generated code for the DLL which contains base types and/or +substitution group heads should be compiled with this option and the generated +code for all other DLLs should be compiled with \fB--import-maps\fR\. This +option is only valid together with \fB--generate-polymorphic\fR\. The +\fBXSD_NO_EXPORT\fR macro can be used to omit this code during C++ +compilation, which may be useful if you would like to use the same generated +code across multiple platforms\. +.IP "\fB--import-maps\fR" +Import polymorphism support maps to a Win32 DLL or executable into which this +generated code is linked\. See the \fB--export-maps\fR option documentation +for details\. This options is only valid together with +\fB--generate-polymorphic\fR\. The \fBXSD_NO_EXPORT\fR macro can be used to +omit this code during C++ compilation, which may be useful if you would like +to use the same generated code across multiple platforms\. +.IP "\fB--generate-dep\fR" +Generate \fBmake\fR dependency information\. This option triggers the creation +of the \fB\.d\fR file containing the dependencies of the generated files on +the main schema file as well as all the schema files that it includes/imports, +transitively\. This dependency file is then normally included into the main +\fBmakefile\fR to implement automatic dependency tracking\. See also the +\fB--dep-*\fR options\. + +Note also that automatic dependency generation is not supported in the +file-per-type mode (\fB--file-per-type\fR)\. In this case, all the generated +files are produced with a single compiler invocation and depend on all the +schemas\. As a result, it is easier to establish such a dependency manually, +perhaps with the help of the \fB--file-list*\fR options\. +.IP "\fB--generate-dep-only\fR" +Generate \fBmake\fR dependency information only\. +.IP "\fB--dep-phony\fR" +Generate phony targets for included/imported schema files, causing each to +depend on nothing\. Such dummy rules work around \fBmake\fR errors caused by +the removal of schema files without also updating the dependency file to +match\. +.IP "\fB--dep-target\fR \fItarget\fR" +Change the target of the dependency rule\. By default it contains all the +generated C++ files as well as the dependency file itself, without any +directory prefixes\. If you require multiple targets, then you can specify +them as a single, space-separated argument or you can repeat this option +multiple times\. +.IP "\fB--dep-suffix\fR \fIsuffix\fR" +Use \fIsuffix\fR instead of the default \fB\.d\fR to construct the name of the +dependency file\. See also \fB--dep-file\fR\. +.IP "\fB--dep-file\fR \fIpath\fR" +Use \fIpath\fR as the generated dependency file path instead of deriving it +from the input file name\. Write the dependency information to \fBstdout\fR if +\fIpath\fR is \fB-\fR\. See also \fB--dep-regex\fR\. +.IP "\fB--dep-regex\fR \fIregex\fR" +Use the provided expression to construct the name of the dependency file\. +\fIregex\fR is a Perl-like regular expression in the form +\fB/\fR\fIpattern\fR\fB/\fR\fIreplacement\fR\fB/\fR\fR\. See also the REGEX +AND SHELL QUOTING section below\. +.IP "\fB--disable-warning\fR \fIwarn\fR" +Disable printing warning with id \fIwarn\fR\. If \fBall\fR is specified for +the warning id then all warnings are disabled\. +.IP "\fB--options-file\fR \fIfile\fR" +Read additional options from \fIfile\fR\. Each option should appearing on a +separate line optionally followed by space and an option value\. Empty lines +and lines starting with \fB#\fR are ignored\. Option values can be enclosed in +double (\fB"\fR) or single (\fB'\fR) quotes to preserve leading and trailing +whitespaces as well as to specify empty values\. If the value itself contains +trailing or leading quotes, enclose it with an extra pair of quotes, for +example \fB'"x"'\fR\. Non-leading and non-trailing quotes are interpreted as +being part of the option value\. + +The semantics of providing options in a file is equivalent to providing the +same set of options in the same order on the command line at the point where +the \fB--options-file\fR option is specified except that the shell escaping +and quoting is not required\. You can repeat this option to specify more than +one options file\. +.IP "\fB--show-sloc\fR" +Show the number of generated physical source lines of code (SLOC)\. +.IP "\fB--sloc-limit\fR \fInum\fR" +Check that the number of generated physical source lines of code (SLOC) does +not exceed \fInum\fR\. +.IP "\fB--proprietary-license\fR" +Indicate that the generated code is licensed under a proprietary license +instead of the GPL\. +.IP "\fB--custom-literals\fR \fIfile\fR" +Load custom XML string to C++ literal mappings from \fIfile\fR\. This +mechanism can be useful if you are using a custom character encoding and some +of the strings in your schemas, for example element/attribute names or +enumeration values, contain non-ASCII characters\. In this case you will need +to provide a custom mapping to C++ literals for such strings\. The format of +this file is specified in the \fBcustom-literals\.xsd\fR XML Schema file that +can be found in the documentation directory\. +.IP "\fB--preserve-anonymous\fR" +Preserve anonymous types\. By default anonymous types are automatically named +with names derived from the enclosing elements/attributes\. Because mappings +implemented by this compiler require all types to be named, this option is +only useful if you want to make sure your schemas don't have anonymous types\. +.IP "\fB--show-anonymous\fR" +Show elements and attributes that are of anonymous types\. This option only +makes sense together with the \fB--preserve-anonymous\fR option\. +.IP "\fB--anonymous-regex\fR \fIregex\fR" +Add \fIregex\fR to the list of regular expressions used to derive names for +anonymous types from the enclosing attributes/elements\. \fIregex\fR is a +Perl-like regular expression in the form +\fB/\fR\fIpattern\fR\fB/\fR\fIreplacement\fR\fB/\fR\fR\. Any character can be +used as a delimiter instead of '\fB/\fR'\. Escaping of the delimiter character +in \fIpattern\fR or \fIreplacement\fR is not supported\. + +All the regular expressions are pushed into a stack with the last specified +expression considered first\. The first match that succeeds is used\. Regular +expressions are applied to a string in the form + +\fIfilename\fR \fInamespace\fR \fIxpath\fR\fR + +For instance: + +\fBhello\.xsd http://example\.com/hello element\fR + +\fBhello\.xsd http://example\.com/hello type/element\fR + +As an example, the following expression makes all the derived names start with +capital letters\. This could be useful when your naming convention requires +type names to start with capital letters: + +\fB%\.* \.* (\.+/)*(\.+)%\eu$2%\fR + +See also the REGEX AND SHELL QUOTING section below\. +.IP "\fB--anonymous-regex-trace\fR" +Trace the process of applying regular expressions specified with the +\fB--anonymous-regex\fR option\. Use this option to find out why your regular +expressions don't do what you expected them to do\. +.IP "\fB--location-map\fR \fIol\fR=\fInl\fR" +Map the original schema location \fIol\fR that is specified in the XML Schema +include or import elements to new schema location \fInl\fR\. Repeat this +option to map more than one schema location\. For example, the following +option maps the \fBhttp://example\.com/foo\.xsd\fR URL to the \fBfoo\.xsd\fR +local file\. + +\fB--location-map http://example\.com/foo\.xsd=foo\.xsd\fR +.IP "\fB--location-regex\fR \fIregex\fR" +Add \fIregex\fR to the list of regular expressions used to map schema +locations that are specified in the XML Schema include or import elements\. +\fIregex\fR is a Perl-like regular expression in the form +\fB/\fR\fIpattern\fR\fB/\fR\fIreplacement\fR\fB/\fR\fR\. Any character can be +used as a delimiter instead of '\fB/\fR'\. Escaping of the delimiter character +in \fIpattern\fR or \fIreplacement\fR is not supported\. All the regular +expressions are pushed into a stack with the last specified expression +considered first\. The first match that succeeds is used\. + +For example, the following expression maps URL locations in the form +\fBhttp://example\.com/foo/bar\.xsd\fR to local files in the form +\fBbar\.xsd\fR: + +\fB%http://\.+/(\.+)%$1%\fR + +See also the REGEX AND SHELL QUOTING section below\. +.IP "\fB--location-regex-trace\fR" +Trace the process of applying regular expressions specified with the +\fB--location-regex\fR option\. Use this option to find out why your regular +expressions don't do what you expected them to do\. +.IP "\fB--file-per-type\fR" +Generate a separate set of C++ files for each type defined in XML Schema\. +Note that in this mode you only need to compile the root schema(s) and the +code will be generated for all included and imported schemas\. This +compilation mode is primarily useful when some of your schemas cannot be +compiled separately or have cyclic dependencies which involve type +inheritance\. Other options related to this mode are: \fB--type-file-regex\fR, +\fB--schema-file-regex\fR, \fB--fat-type-file\fR, and \fB--file-list\fR\. +.IP "\fB--type-file-regex\fR \fIregex\fR" +Add \fIregex\fR to the list of regular expressions used to translate type +names to file names when the \fB--file-per-type\fR option is specified\. +\fIregex\fR is a Perl-like regular expression in the form +\fB/\fR\fIpattern\fR\fB/\fR\fIreplacement\fR\fB/\fR\fR\. Any character can be +used as a delimiter instead of '\fB/\fR'\. Escaping of the delimiter character +in \fIpattern\fR or \fIreplacement\fR is not supported\. All the regular +expressions are pushed into a stack with the last specified expression +considered first\. The first match that succeeds is used\. Regular expressions +are applied to a string in the form + +\fInamespace\fR \fItype-name\fR\fR + +For example, the following expression maps type \fBfoo\fR that is defined in +the \fBhttp://example\.com/bar\fR namespace to file name \fBbar-foo\fR: + +\fB%http://example\.com/(\.+) (\.+)%$1-$2%\fR + +See also the REGEX AND SHELL QUOTING section below\. +.IP "\fB--type-file-regex-trace\fR" +Trace the process of applying regular expressions specified with the +\fB--type-file-regex\fR option\. Use this option to find out why your regular +expressions don't do what you expected them to do\. +.IP "\fB--schema-file-regex\fR \fIregex\fR" +Add \fIregex\fR to the list of regular expressions used to translate schema +file names when the \fB--file-per-type\fR option is specified\. \fIregex\fR is +a Perl-like regular expression in the form +\fB/\fR\fIpattern\fR\fB/\fR\fIreplacement\fR\fB/\fR\fR\. Any character can be +used as a delimiter instead of '\fB/\fR'\. Escaping of the delimiter character +in \fIpattern\fR or \fIreplacement\fR is not supported\. All the regular +expressions are pushed into a stack with the last specified expression +considered first\. The first match that succeeds is used\. Regular Expressions +are applied to the absolute filesystem path of a schema file and the result, +including the directory part, if any, is used to derive the \fB#include\fR +directive paths as well as the generated C++ file paths\. This option, along +with \fB--type-file-regex\fR are primarily useful to place the generated files +into subdirectories or to resolve file name conflicts\. + +For example, the following expression maps schema files in the +\fBfoo/1\.0\.0/\fR subdirectory to the files in the \fBfoo/\fR subdirectory\. +As a result, the \fB#include\fR directive paths for such schemas will be in +the \fBfoo/schema\.hxx\fR form and the generated C++ files will be placed into +the \fBfoo/\fR subdirectory: + +\fB%\.*/foo/1\.0\.0/(\.+)%foo/$1%\fR + +See also the REGEX AND SHELL QUOTING section below\. +.IP "\fB--schema-file-regex-trace\fR" +Trace the process of applying regular expressions specified with the +\fB--schema-file-regex\fR option\. Use this option to find out why your +regular expressions don't do what you expected them to do\. +.IP "\fB--fat-type-file\fR" +Generate code corresponding to global elements into type files instead of +schema files when the \fB--type-file-regex\fR option is specified\. This +option is primarily useful when trying to minimize the amount of object code +that is linked to an executable by packaging compiled generated code into a +static (archive) library\. +.IP "\fB--file-list\fR \fIfile\fR" +Write a list of generated C++ files to \fIfile\fR or to \fBstdout\fR if +\fIfile\fR is \fB-\fR\. This option is primarily useful in the file-per-type +compilation mode (\fB--file-per-type\fR) to create a list of generated C++ +files, for example, as a makefile fragment\. +.IP "\fB--file-list-only\fR" +Only write the list of C++ files that would be generated without actually +generating them\. This option only makes sense together with +\fB--file-list\fR\. +.IP "\fB--file-list-prologue\fR \fItext\fR" +Insert \fItext\fR at the beginning of the file list\. As a convenience, all +occurrences of the \fB\en\fR character sequence in \fItext\fR are replaced +with new lines\. This option can, for example, be used to assign the generated +file list to a makefile variable\. +.IP "\fB--file-list-epilogue\fR \fItext\fR" +Insert \fItext\fR at the end of the file list\. As a convenience, all +occurrences of the \fB\en\fR character sequence in \fItext\fR are replaced +with new lines\. +.IP "\fB--file-list-delim\fR \fItext\fR" +Delimit file names written to the file list with \fItext\fR instead of new +lines\. As a convenience, all occurrences of the \fB\en\fR character sequence +in \fItext\fR are replaced with new lines\. +.\" +.\" C++/Tree options. +.\" +.SS cxx-tree command options +.IP "\fB--generate-polymorphic\fR" +Generate polymorphism-aware code\. Specify this option if you use substitution +groups or \fBxsi:type\fR\. Use the \fB--polymorphic-type\fR or +\fB--polymorphic-type-all\fR option to specify which type hierarchies are +polymorphic\. +.IP "\fB--polymorphic-type\fR \fItype\fR" +Indicate that \fItype\fR is a root of a polymorphic type hierarchy\. The +compiler can often automatically determine which types are polymorphic based +on the substitution group declarations\. However, you may need to use this +option if you are not using substitution groups or if substitution groups are +defined in another schema\. You need to specify this option when compiling +every schema file that references \fItype\fR\. The \fItype\fR argument is an +XML Schema type name that can be optionally qualified with a namespace in the +\fInamespace\fR\fB#\fR\fIname\fR\fR form\. +.IP "\fB--polymorphic-type-all\fR" +Indicate that all types should be treated as polymorphic\. +.IP "\fB--polymorphic-plate\fR \fInum\fR" +Specify the polymorphic map plate the generated code should register on\. This +functionality is primarily useful to segregate multiple schemas that define +the same polymorphic types\. +.IP "\fB--ordered-type\fR \fItype\fR" +Indicate that element order in \fItype\fR is significant\. An example would be +a complex type with unbounded choice as a content model where the element +order in XML has application-specific semantics\. For ordered types the +compiler generates a special container data member and a corresponding set of +accessors and modifiers that are used to capture the order of elements and, +for mixed content, of text\. + +The \fItype\fR argument is an XML Schema type name that can be optionally +qualified with a namespace in the \fInamespace\fR\fB#\fR\fIname\fR\fR form\. +Note also that you will need to specify this option when compiling every +schema file that has other ordered types derived from this type\. +.IP "\fB--ordered-type-derived\fR" +Automatically treat types derived from ordered bases as also ordered\. This is +primarily useful if you would like to be able to iterate over the complete +content using the content order container\. +.IP "\fB--ordered-type-mixed\fR" +Automatically treat complex types with mixed content as ordered\. +.IP "\fB--ordered-type-all\fR" +Indicate that element order in all types is significant\. +.IP "\fB--order-container\fR \fItype\fR" +Specify a custom class template that should be used as a container for the +content order in ordered types instead of the default \fBstd::vector\fR\. See +\fB--ordered-type\fR for more information on ordered type\. This option is +primarily useful if you need to perform more complex lookups in the content +order container, for example by element id\. In this case, a container like +Boost multi-index may be more convenient\. Note that if using a custom +container, you will also most likely need to include the relevant headers +using the \fB--hxx-prologue*\fR options\. +.IP "\fB--generate-serialization\fR" +Generate serialization functions\. Serialization functions convert the object +model back to XML\. +.IP "\fB--generate-ostream\fR" +Generate ostream insertion operators (\fBoperator<<\fR) for generated types\. +This allows one to easily print a fragment or the whole object model for +debugging or logging\. +.IP "\fB--generate-doxygen\fR" +Generate documentation comments suitable for extraction by the Doxygen +documentation system\. Documentation from annotations is added to the comments +if present in the schema\. +.IP "\fB--generate-comparison\fR" +Generate comparison operators (\fBoperator==\fR and \fBoperator!=\fR) for +complex types\. Comparison is performed member-wise\. +.IP "\fB--generate-default-ctor\fR" +Generate default constructors even for types that have required members\. +Required members of an instance constructed using such a constructor are not +initialized and accessing them results in undefined behavior\. +.IP "\fB--generate-from-base-ctor\fR" +Generate constructors that expect an instance of a base type followed by all +required members\. +.IP "\fB--suppress-assignment\fR" +Suppress the generation of copy assignment operators for complex types\. If +this option is specified, the copy assignment operators for such types are +declared private and left unimplemented\. +.IP "\fB--generate-detach\fR" +Generate detach functions for required elements and attributes\. Detach +functions for optional and sequence cardinalities are provided by the +respective containers\. These functions, for example, allow you to move +sub-trees in the object model either within the same tree or between different +trees\. +.IP "\fB--generate-wildcard\fR" +Generate accessors and modifiers as well as parsing and serialization code for +XML Schema wildcards (\fBany\fR and \fBanyAttribute\fR)\. XML content matched +by wildcards is presented as DOM fragments\. Note that you need to initialize +the Xerces-C++ runtime if you are using this option\. +.IP "\fB--generate-any-type\fR" +Extract and store content of the XML Schema \fBanyType\fR type as a DOM +fragment\. Note that you need to initialize the Xerces-C++ runtime if you are +using this option\. +.IP "\fB--generate-insertion\fR \fIos\fR" +Generate data representation stream insertion operators for the \fIos\fR +output stream type\. Repeat this option to specify more than one stream type\. +The ACE CDR stream (\fBACE_OutputCDR\fR) and RPC XDR are recognized by the +compiler and the necessary \fB#include\fR directives are automatically +generated\. For custom stream types use the \fB--hxx-prologue*\fR options to +provide the necessary declarations\. +.IP "\fB--generate-extraction\fR \fIis\fR" +Generate data representation stream extraction constructors for the \fIis\fR +input stream type\. Repeat this option to specify more than one stream type\. +The ACE CDR stream (\fBACE_InputCDR\fR) and RPC XDR are recognized by the +compiler and the necessary \fB#include\fR directives are automatically +generated\. For custom stream types use the \fB--hxx-prologue*\fR options to +provide the necessary declarations\. +.IP "\fB--generate-forward\fR" +Generate a separate header file with forward declarations for the types being +generated\. +.IP "\fB--suppress-parsing\fR" +Suppress the generation of the parsing functions and constructors\. Use this +option to reduce the generated code size when parsing from XML is not needed\. +.IP "\fB--generate-element-type\fR" +Generate types instead of parsing and serialization functions for root +elements\. This is primarily useful to distinguish object models with the same +root type but with different root elements\. +.IP "\fB--generate-element-map\fR" +Generate a root element map that allows uniform parsing and serialization of +multiple root elements\. This option is only valid together with +\fB--generate-element-type\fR\. +.IP "\fB--generate-intellisense\fR" +Generate workarounds for IntelliSense bugs in Visual Studio 2005 (8\.0)\. When +this option is used, the resulting code is slightly more verbose\. +IntelliSense in Visual Studio 2008 (9\.0) and later does not require these +workarounds\. Support for IntelliSense in Visual Studio 2003 (7\.1) is +improved with this option but is still incomplete\. +.IP "\fB--omit-default-attributes\fR" +Omit attributes with default and fixed values from serialized XML documents\. +.IP "\fB--type-naming\fR \fIstyle\fR" +Specify the type naming convention that should be used in the generated code\. +Valid styles are \fBknr\fR (default), \fBucc\fR, and \fBjava\fR\. See the +NAMING CONVENTION section below for more information\. +.IP "\fB--function-naming\fR \fIstyle\fR" +Specify the function naming convention that should be used in the generated +code\. Valid styles are \fBknr\fR (default), \fBlcc\fR, \fBucc\fR, and +\fBjava\fR\. See the NAMING CONVENTION section below for more information\. +.IP "\fB--type-regex\fR \fIregex\fR" +Add \fIregex\fR to the list of regular expressions used to translate XML +Schema type names to C++ type names\. See the NAMING CONVENTION section below +for more information\. +.IP "\fB--accessor-regex\fR \fIregex\fR" +Add \fIregex\fR to the list of regular expressions used to translate XML +Schema names of elements/attributes to C++ accessor function names\. See the +NAMING CONVENTION section below for more information\. +.IP "\fB--one-accessor-regex\fR \fIregex\fR" +Add \fIregex\fR to the list of regular expressions used to translate XML +Schema names of elements/attributes with cardinality one to C++ accessor +function names\. See the NAMING CONVENTION section below for more +information\. +.IP "\fB--opt-accessor-regex\fR \fIregex\fR" +Add \fIregex\fR to the list of regular expressions used to translate XML +Schema names of elements/attributes with cardinality optional to C++ accessor +function names\. See the NAMING CONVENTION section below for more +information\. +.IP "\fB--seq-accessor-regex\fR \fIregex\fR" +Add \fIregex\fR to the list of regular expressions used to translate XML +Schema names of elements/attributes with cardinality sequence to C++ accessor +function names\. See the NAMING CONVENTION section below for more +information\. +.IP "\fB--modifier-regex\fR \fIregex\fR" +Add \fIregex\fR to the list of regular expressions used to translate XML +Schema names of elements/attributes to C++ modifier function names\. See the +NAMING CONVENTION section below for more information\. +.IP "\fB--one-modifier-regex\fR \fIregex\fR" +Add \fIregex\fR to the list of regular expressions used to translate XML +Schema names of elements/attributes with cardinality one to C++ modifier +function names\. See the NAMING CONVENTION section below for more +information\. +.IP "\fB--opt-modifier-regex\fR \fIregex\fR" +Add \fIregex\fR to the list of regular expressions used to translate XML +Schema names of elements/attributes with cardinality optional to C++ modifier +function names\. See the NAMING CONVENTION section below for more +information\. +.IP "\fB--seq-modifier-regex\fR \fIregex\fR" +Add \fIregex\fR to the list of regular expressions used to translate XML +Schema names of elements/attributes with cardinality sequence to C++ modifier +function names\. See the NAMING CONVENTION section below for more +information\. +.IP "\fB--parser-regex\fR \fIregex\fR" +Add \fIregex\fR to the list of regular expressions used to translate XML +Schema element names to C++ parsing function names\. See the NAMING CONVENTION +section below for more information\. +.IP "\fB--serializer-regex\fR \fIregex\fR" +Add \fIregex\fR to the list of regular expressions used to translate XML +Schema element names to C++ serialization function names\. See the NAMING +CONVENTION section below for more information\. +.IP "\fB--const-regex\fR \fIregex\fR" +Add \fIregex\fR to the list of regular expressions used to translate XML +Schema-derived names to C++ constant names\. See the NAMING CONVENTION section +below for more information\. +.IP "\fB--enumerator-regex\fR \fIregex\fR" +Add \fIregex\fR to the list of regular expressions used to translate XML +Schema enumeration values to C++ enumerator names\. See the NAMING CONVENTION +section below for more information\. +.IP "\fB--element-type-regex\fR \fIregex\fR" +Add \fIregex\fR to the list of regular expressions used to translate XML +Schema element names to C++ element type names\. See the NAMING CONVENTION +section below for more information\. +.IP "\fB--name-regex-trace\fR" +Trace the process of applying regular expressions specified with the name +transformation options\. Use this option to find out why your regular +expressions don't do what you expected them to do\. +.IP "\fB--root-element-first\fR" +Treat only the first global element as a document root\. By default all global +elements are considered document roots\. +.IP "\fB--root-element-last\fR" +Treat only the last global element as a document root\. By default all global +elements are considered document roots\. +.IP "\fB--root-element-all\fR" +Treat all global elements as document roots\. This is the default behavior\. +By explicitly specifying this option you can suppress the warning that is +issued if more than one global element is defined\. +.IP "\fB--root-element-none\fR" +Do not treat any global elements as document roots\. By default all global +elements are considered document roots\. +.IP "\fB--root-element\fR \fIelement\fR" +Treat only \fIelement\fR as a document root\. Repeat this option to specify +more than one root element\. +.IP "\fB--custom-type\fR \fImap\fR" +Use a custom C++ type instead of the generated class\. The \fImap\fR argument +is in the form \fIname\fR[\fB=\fR\fItype\fR[\fB/\fR\fIbase\fR]]\fR, where +\fIname\fR is a type name as defined in XML Schema and \fItype\fR is a C++ +type name that should be used instead\. If \fItype\fR is not present or empty +then the custom type is assumed to have the same name and be defined in the +same namespace as the generated class would have\. If \fIbase\fR is specified +then the generated class is still generated but with that name\. +.IP "\fB--custom-type-regex\fR \fIregex\fR" +Use custom C++ types instead of the generated classes\. The \fIregex\fR +argument is in the form +\fB/\fR\fIname-pat\fR\fB/\fR[\fItype-sub\fR\fB/\fR[\fIbase-sub\fR\fB/\fR]]\fR, +where \fIname-pat\fR is a regex pattern that will be matched against type +names as defined in XML Schema and \fItype-sub\fR is a C++ type name +substitution that should be used instead\. If \fItype-sub\fR is not present or +its substitution results in an empty string then the custom type is assumed to +have the same name and be defined in the same namespace as the generated class +would have\. If \fIbase-sub\fR is present and its substitution results in a +non-empty string then the generated class is still generated but with the +result of this substitution as its name\. The pattern and substitutions are in +the Perl regular expression format\. See also the REGEX AND SHELL QUOTING +section below\. +.IP "\fB--parts\fR \fInum\fR" +Split generated source code into \fInum\fR parts\. This is useful when +translating large, monolithic schemas and a C++ compiler is not able to +compile the resulting source code at once (usually due to insufficient +memory)\. +.IP "\fB--parts-suffix\fR \fIsuffix\fR" +Use \fIsuffix\fR instead of the default '\fB-\fR' to separate the file name +from the part number\. +\" +\" C++/Parser +\" +.SS cxx-parser command options +.IP "\fB--type-map\fR \fImapfile\fR" +Read XML Schema to C++ type mapping information from \fImapfile\fR\. Repeat +this option to specify several type maps\. Type maps are considered in order +of appearance and the first match is used\. By default all user-defined types +are mapped to \fBvoid\fR\. See the TYPE MAP section below for more +information\. +.IP "\fB--xml-parser\fR \fIparser\fR" +Use \fIparser\fR as the underlying XML parser\. Valid values are \fBxerces\fR +for Xerces-C++ (default) and \fBexpat\fR for Expat\. +.IP "\fB--generate-validation\fR" +Generate validation code\. The validation code ("perfect parser") ensures that +instance documents conform to the schema\. Validation code is generated by +default when the selected underlying XML parser is non-validating +(\fBexpat\fR)\. +.IP "\fB--suppress-validation\fR" +Suppress the generation of validation code\. Validation is suppressed by +default when the selected underlying XML parser is validating (\fBxerces\fR)\. +.IP "\fB--generate-polymorphic\fR" +Generate polymorphism-aware code\. Specify this option if you use substitution +groups or \fBxsi:type\fR\. +.IP "\fB--generate-noop-impl\fR" +Generate a sample parser implementation that does nothing (no operation)\. The +sample implementation can then be filled with the application-specific code\. +For an input file in the form \fBname\.xsd\fR this option triggers the +generation of two additional C++ files in the form: \fBname-pimpl\.hxx\fR +(parser implementation header file) and \fBname-pimpl\.cxx\fR (parser +implementation source file)\. +.IP "\fB--generate-print-impl\fR" +Generate a sample parser implementation that prints the XML data to +STDOUT\fR\. For an input file in the form \fBname\.xsd\fR this option triggers +the generation of two additional C++ files in the form: \fBname-pimpl\.hxx\fR +(parser implementation header file) and \fBname-pimpl\.cxx\fR (parser +implementation source file)\. +.IP "\fB--generate-test-driver\fR" +Generate a test driver for the sample parser implementation\. For an input +file in the form \fBname\.xsd\fR this option triggers the generation of an +additional C++ file in the form \fBname-driver\.cxx\fR\. +.IP "\fB--force-overwrite\fR" +Force overwriting of the existing implementation and test driver files\. Use +this option only if you do not mind loosing the changes you have made in the +sample implementation or test driver files\. +.IP "\fB--root-element-first\fR" +Indicate that the first global element is the document root\. This information +is used to generate the test driver for the sample implementation\. +.IP "\fB--root-element-last\fR" +Indicate that the last global element is the document root\. This information +is used to generate the test driver for the sample implementation\. +.IP "\fB--root-element\fR \fIelement\fR" +Indicate that \fIelement\fR is the document root\. This information is used to +generate the test driver for the sample implementation\. +.IP "\fB--skel-type-suffix\fR \fIsuffix\fR" +Use the provided \fIsuffix\fR instead of the default \fB_pskel\fR to construct +the names of the generated parser skeletons\. +.IP "\fB--skel-file-suffix\fR \fIsuffix\fR" +Use the provided \fIsuffix\fR instead of the default \fB-pskel\fR to construct +the names of the generated parser skeleton files\. +.IP "\fB--impl-type-suffix\fR \fIsuffix\fR" +Use the provided \fIsuffix\fR instead of the default \fB_pimpl\fR to construct +the names of the parser implementations for the built-in XML Schema types as +well as sample parser implementations\. +.IP "\fB--impl-file-suffix\fR \fIsuffix\fR" +Use the provided \fIsuffix\fR instead of the default \fB-pimpl\fR to construct +the names of the generated sample parser implementation files\. +\" +\" NAMING CONVENTION +\" + +.SH NAMING CONVENTION +The compiler can be instructed to use a particular naming convention in +the generated code. A number of widely-used conventions can be selected +using the +.B --type-naming +and +.B --function-naming +options. A custom naming convention can be achieved using the +.BR --type-regex , +.BR --accessor-regex , +.BR --one-accessor-regex , +.BR --opt-accessor-regex , +.BR --seq-accessor-regex , +.BR --modifier-regex , +.BR --one-modifier-regex , +.BR --opt-modifier-regex , +.BR --seq-modifier-regex , +.BR --parser-regex , +.BR --serializer-regex , +.BR --const-regex , +.BR --enumerator-regex , +and +.B --element-type-regex +options. + +The +.B --type-naming +option specifies the convention that should be used for naming C++ types. +Possible values for this option are +.B knr +(default), +.BR ucc , +and +.BR java . +The +.B knr +value (stands for K&R) signifies the standard, lower-case naming convention +with the underscore used as a word delimiter, for example: foo, foo_bar. +The +.B ucc +(stands for upper-camel-case) and +.B java +values a synonyms for the same naming convention where the first letter +of each word in the name is capitalized, for example: Foo, FooBar. + +Similarly, the +.B --function-naming +option specifies the convention that should be used for naming C++ functions. +Possible values for this option are +.B knr +(default), +.BR lcc , +and +.BR java . +The +.B knr +value (stands for K&R) signifies the standard, lower-case naming convention +with the underscore used as a word delimiter, for example: foo(), foo_bar(). +The +.B lcc +value (stands for lower-camel-case) signifies a naming convention where the +first letter of each word except the first is capitalized, for example: foo(), +fooBar(). The +.B ucc +value (stands for upper-camel-case) signifies a naming convention where the +first letter of each word is capitalized, for example: Foo(), FooBar(). The +.B java +naming convention is similar to the lower-camel-case one except that accessor +functions are prefixed with get, modifier functions are prefixed with set, +parsing functions are prefixed with parse, and serialization functions are +prefixed with serialize, for example: getFoo(), setFooBar(), parseRoot(), +serializeRoot(). + +Note that the naming conventions specified with the +.B --type-naming +and +.B --function-naming +options perform only limited transformations on the +names that come from the schema in the form of type, attribute, and element +names. In other words, to get consistent results, your schemas should follow +a similar naming convention as the one you would like to have in the generated +code. Alternatively, you can use the +.B --*-regex +options (discussed below) to perform further transformations on the names +that come from the schema. + +The +.BR --type-regex , +.BR --accessor-regex , +.BR --one-accessor-regex , +.BR --opt-accessor-regex , +.BR --seq-accessor-regex , +.BR --modifier-regex , +.BR --one-modifier-regex , +.BR --opt-modifier-regex , +.BR --seq-modifier-regex , +.BR --parser-regex , +.BR --serializer-regex , +.BR --const-regex , +.BR --enumerator-regex , +and +.B --element-type-regex +options allow you to specify extra regular expressions for each name +category in addition to the predefined set that is added depending on +the +.B --type-naming +and +.B --function-naming +options. Expressions that are provided with the +.B --*-regex +options are evaluated prior to any predefined expressions. This allows +you to selectively override some or all of the predefined transformations. +When debugging your own expressions, it is often useful to see which +expressions match which names. The +.B --name-regex-trace +option allows you to trace the process of applying +regular expressions to names. + +The value for the +.B --*-regex +options should be a perl-like regular expression in the form +.BI / pattern / replacement /\fR. +Any character can be used as a delimiter instead of +.BR / . +Escaping of the delimiter character in +.I pattern +or +.I replacement +is not supported. All the regular expressions for each category are pushed +into a category-specific stack with the last specified expression +considered first. The first match that succeeds is used. For the +.B --one-accessor-regex +(accessors with cardinality one), +.B --opt-accessor-regex +(accessors with cardinality optional), and +.B --seq-accessor-regex +(accessors with cardinality sequence) categories the +.B --accessor-regex +expressions are used as a fallback. For the +.BR --one-modifier-regex , +.BR --opt-modifier-regex , +and +.B --seq-modifier-regex +categories the +.B --modifier-regex +expressions are used as a fallback. For the +.B --element-type-regex +category the +.B --type-regex +expressions are used as a fallback. + +The type name expressions +.RB ( --type-regex ) +are evaluated on the name string that has the following format: + +[\fInamespace \fR]\fIname\fR[\fB,\fIname\fR][\fB,\fIname\fR][\fB,\fIname\fR] + +The element type name expressions +.RB ( --element-type-regex ), +effective only when the +.B --generate-element-type +option is specified, are evaluated on the name string that has the following +format: + +.I namespace name + +In the type name format the +.I namespace +part followed by a space is only present for global type names. For global +types and elements defined in schemas without a target namespace, the +.I namespace +part is empty but the space is still present. In the type name format after +the initial +.I name +component, up to three additional +.I name +components can be present, separated by commas. For example: + +.B http://example.com/hello type + +.B foo + +.B foo,iterator + +.B foo,const,iterator + +The following set of predefined regular expressions is used to transform +type names when the upper-camel-case naming convention is selected: + +.B /(?:[^ ]* )?([^,]+)/\\\\u$1/ + +.B /(?:[^ ]* )?([^,]+),([^,]+)/\\\\u$1\\\\u$2/ + +.B /(?:[^ ]* )?([^,]+),([^,]+),([^,]+)/\\\\u$1\\\\u$2\\\\u$3/ + +.B /(?:[^ ]* )?([^,]+),([^,]+),([^,]+),([^,]+)/\\\\u$1\\\\u$2\\\\u$3\\\\u$4/ + +The accessor and modifier expressions +.RB ( --*accessor-regex +and +.BR --*modifier-regex ) +are evaluated on the name string that has the following format: + +\fIname\fR[\fB,\fIname\fR][\fB,\fIname\fR] + +After the initial +.I name +component, up to two additional +.I name +components can be present, separated by commas. For example: + +.B foo + +.B dom,document + +.B foo,default,value + +The following set of predefined regular expressions is used to transform +accessor names when the +.B java +naming convention is selected: + +.B /([^,]+)/get\\\\u$1/ + +.B /([^,]+),([^,]+)/get\\\\u$1\\\\u$2/ + +.B /([^,]+),([^,]+),([^,]+)/get\\\\u$1\\\\u$2\\\\u$3/ + +For the parser, serializer, and enumerator categories, the corresponding +regular expressions are evaluated on local names of elements and on +enumeration values, respectively. For example, the following predefined +regular expression is used to transform parsing function names when the +.B java +naming convention is selected: + +.B /(.+)/parse\\\\u$1/ + +The const category is used to create C++ constant names for the +element/wildcard/text content ids in ordered types. + +See also the REGEX AND SHELL QUOTING section below. + +\" +\" TYPE MAP +\" +.SH TYPE MAP +Type map files are used in C++/Parser to define a mapping between XML +Schema and C++ types. The compiler uses this information to determine +the return types of +.B post_* +functions in parser skeletons corresponding to XML Schema types +as well as argument types for callbacks corresponding to elements +and attributes of these types. + +The compiler has a set of predefined mapping rules that map built-in +XML Schema types to suitable C++ types (discussed below) and all +other types to +.BR void . +By providing your own type maps you can override these predefined rules. +The format of the type map file is presented below: + +.RS +.B namespace +.I schema-namespace +[ +.I cxx-namespace +] +.br +.B { +.br + ( +.B include +.IB file-name ; +)* +.br + ([ +.B type +] +.I schema-type cxx-ret-type +[ +.I cxx-arg-type +.RB ] ; +)* +.br +.B } +.br +.RE + +Both +.I schema-namespace +and +.I schema-type +are regex patterns while +.IR cxx-namespace , +.IR cxx-ret-type , +and +.I cxx-arg-type +are regex pattern substitutions. All names can be optionally enclosed +in \fR" "\fR, for example, to include white-spaces. + +.I schema-namespace +determines XML Schema namespace. Optional +.I cxx-namespace +is prefixed to every C++ type name in this namespace declaration. +.I cxx-ret-type +is a C++ type name that is used as a return type for the +.B post_* +functions. Optional +.I cxx-arg-type +is an argument type for callback functions corresponding to elements and +attributes of this type. If +.I cxx-arg-type +is not specified, it defaults to +.I cxx-ret-type +if +.I cxx-ret-type +ends with +.B * +or +.B & +(that is, it is a pointer or a reference) and +.B const +\fIcxx-ret-type\fB&\fR otherwise. +.I file-name +is a file name either in the \fR" "\fR or < > format and is added with the +.B #include +directive to the generated code. + +The \fB#\fR character starts a comment that ends with a new line or end of +file. To specify a name that contains \fB#\fR enclose it in \fR" "\fR. For +example: + +.RS +namespace http://www.example.com/xmlns/my my +.br +{ +.br + include "my.hxx"; +.br + + # Pass apples by value. + # + apple apple; +.br + + # Pass oranges as pointers. + # + orange orange_t*; +.br +} +.br +.RE + +In the example above, for the +.B http://www.example.com/xmlns/my#orange +XML Schema type, the +.B my::orange_t* +C++ type will be used as both return and argument types. + +Several namespace declarations can be specified in a single file. +The namespace declaration can also be completely omitted to map +types in a schema without a namespace. For instance: + +.RS +include "my.hxx"; +.br +apple apple; +.br + +namespace http://www.example.com/xmlns/my +.br +{ +.br + orange "const orange_t*"; +.br +} +.br +.RE + +The compiler has a number of predefined mapping rules that can be +presented as the following map files. The string-based XML Schema +built-in types are mapped to either +.B std::string +or +.B std::wstring +depending on the character type selected with the +.B --char-type +option +.RB ( char +by default). The binary XML Schema types are mapped to either +.B std::unique_ptr<xml_schema::buffer> +or +.B std::auto_ptr<xml_schema::buffer> +depending on the C++ standard selected with the +.B --std +option +.RB ( c++11 +by default). + +.RS +namespace http://www.w3.org/2001/XMLSchema +.br +{ +.br + boolean bool bool; +.br + + byte "signed char" "signed char"; +.br + unsignedByte "unsigned char" "unsigned char"; +.br + + short short short; +.br + unsignedShort "unsigned short" "unsigned short"; +.br + + int int int; +.br + unsignedInt "unsigned int" "unsigned int"; +.br + + long "long long" "long long"; +.br + unsignedLong "unsigned long long" "unsigned long long"; +.br + + integer "long long" "long long"; +.br + + negativeInteger "long long" "long long"; +.br + nonPositiveInteger "long long" "long long"; +.br + + positiveInteger "unsigned long long" "unsigned long long"; +.br + nonNegativeInteger "unsigned long long" "unsigned long long"; +.br + + float float float; +.br + double double double; +.br + decimal double double; +.br + + string std::string; +.br + normalizedString std::string; +.br + token std::string; +.br + Name std::string; +.br + NMTOKEN std::string; +.br + NCName std::string; +.br + ID std::string; +.br + IDREF std::string; +.br + language std::string; +.br + anyURI std::string; +.br + + NMTOKENS xml_schema::string_sequence; +.br + IDREFS xml_schema::string_sequence; +.br + + QName xml_schema::qname; +.br + + base64Binary std::[unique|auto]_ptr<xml_schema::buffer> +.br + std::[unique|auto]_ptr<xml_schema::buffer>; +.br + hexBinary std::[unique|auto]_ptr<xml_schema::buffer> +.br + std::[unique|auto]_ptr<xml_schema::buffer>; +.br + + date xml_schema::date; +.br + dateTime xml_schema::date_time; +.br + duration xml_schema::duration; +.br + gDay xml_schema::gday; +.br + gMonth xml_schema::gmonth; +.br + gMonthDay xml_schema::gmonth_day; +.br + gYear xml_schema::gyear; +.br + gYearMonth xml_schema::gyear_month; +.br + time xml_schema::time; +.br +} +.br +.RE + + +The last predefined rule maps anything that wasn't mapped by previous +rules to +.BR void : + +.RS +namespace .* +.br +{ +.br + .* void void; +.br +} +.br +.RE + +When you provide your own type maps with the +.B --type-map +option, they are evaluated first. This allows you to selectively override +predefined rules. + +.\" +.\" REGEX AND SHELL QUOTING +.\" +.SH REGEX AND SHELL QUOTING +When entering a regular expression argument in the shell command line +it is often necessary to use quoting (enclosing the argument in " " +or ' ') in order to prevent the shell from interpreting certain +characters, for example, spaces as argument separators and $ as +variable expansions. + +Unfortunately it is hard to achieve this in a manner that is portable +across POSIX shells, such as those found on GNU/Linux and UNIX, and +Windows shell. For example, if you use " " for quoting you will get +a wrong result with POSIX shells if your expression contains $. The +standard way of dealing with this on POSIX systems is to use ' ' +instead. Unfortunately, Windows shell does not remove ' ' from +arguments when they are passed to applications. As a result you may +have to use ' ' for POSIX and " " for Windows ($ is not treated as +a special character on Windows). + +Alternatively, you can save regular expression options into a file, +one option per line, and use this file with the +.B --options-file +option. With this approach you don't need to worry about shell quoting. + +.\" +.\" DIAGNOSTICS +.\" +.SH DIAGNOSTICS +If the input file is not a valid W3C XML Schema definition, +.B xsd +will issue diagnostic messages to +.B STDERR +and exit with non-zero exit code. +.SH BUGS +Send bug reports to the xsd-users@codesynthesis.com mailing list. +.SH COPYRIGHT +Copyright (c) 2005-2023 Code Synthesis. + +Permission is granted to copy, distribute and/or modify this +document under the terms of the GNU Free Documentation License, +version 1.2; with no Invariant Sections, no Front-Cover Texts and +no Back-Cover Texts. Copy of the license can be obtained from +https://www.codesynthesis.com/licenses/fdl-1.2.txt diff --git a/xsd/doc/pregenerated/xsd.xhtml b/xsd/doc/pregenerated/xsd.xhtml new file mode 100644 index 0000000..2e30ed4 --- /dev/null +++ b/xsd/doc/pregenerated/xsd.xhtml @@ -0,0 +1,1620 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> + <title>XSD 4.2.1-a.0 Compiler Command Line Manual</title> + + <meta charset="UTF-8"/> + <meta name="version" content="4.2.1-a.0"/> + <meta name="copyright" content="© 2005-2023 Code Synthesis"/> + <meta name="keywords" content="xsd,xml,schema,c++,mapping,data,binding,code,generator,manual,man,page"/> + <meta name="description" content="XSD Compiler Command Line Manual"/> + + <link rel="stylesheet" type="text/css" href="default.css" /> + +<style type="text/css"> + + #synopsis { + list-style-type: none; + } + + #synopsis li { + padding-top : 0.0em; + padding-bottom : 0.0em; + } + + #commands dt { + padding-top : 0.4em; + } + + #commands dd { + padding-bottom : 0.4em; + padding-left : 2em; + } + + .options { + margin: 1em 0 1em 0; + } + + .options dt { + margin: 1em 0 0 0; + } + + .options dd { + margin: .1em 0 0 4.5em; + } + +</style> +</head> + +<body> +<div id="container"> + <div id="content"> + + <h1>NAME</h1> + + <p>xsd - W3C XML Schema to C++ Compiler</p> + + <h1>SYNOPSIS</h1> + + <dl id="synopsis"> + <dt><code><b>xsd</b> <i>command</i> [<i>options</i>] <i>file</i> [<i>file</i> ...]</code></dt> + <dt><code><b>xsd help</b> [<i>command</i>]</code></dt> + <dt><code><b>xsd version</b></code></dt> + </dl> + + <h1>DESCRIPTION</h1> + + <p><code><b>xsd</b></code> generates vocabulary-specific, statically-typed + C++ mapping from W3C XML Schema definitions. Particular mapping to + produce is selected by a <code><i>command</i></code>. Each mapping has + a number of mapping-specific <code><i>options</i></code> that should + appear, if any, after the <code><i>command</i></code>. Input files should + be W3C XML Schema definitions. The exact set of the generated files depends + on the selected mapping and options.</p> + + <h1>COMMANDS</h1> + + <dl id="commands"> + <dt><code><b>cxx-tree</b></code></dt> + <dd>Generate the C++/Tree mapping. For each input file in the form + <code><b>name.xsd</b></code> the following C++ files are generated: + <code><b>name.hxx</b></code> (header file), + <code><b>name.ixx</b></code> (inline file, generated only if the + <code><b>--generate-inline</b></code> option is specified), + <code><b>name.cxx</b></code> (source file), and + <code><b>name-fwd.hxx</b></code> (forward declaration file, generated + only if the <code><b>--generate-forward</b></code> option is + specified).</dd> + + <dt><code><b>cxx-parser</b></code></dt> + <dd>Generate the C++/Parser mapping. For each input file in the form + <code><b>name.xsd</b></code> the following C++ files are generated: + <code><b>name-pskel.hxx</b></code> (parser skeleton header file), + <code><b>name-pskel.ixx</b></code> (parser skeleton inline file, + generated only if the <code><b>--generate-inline</b></code> + option is specified), and + <code><b>name-pskel.cxx</b></code> (parser skeleton source file). + If the <code><b>--generate-noop-impl</b></code> or + <code><b>--generate-print-impl</b></code> option is specified, + the following additional sample implementation files are generated: + <code><b>name-pimpl.hxx</b></code> (parser implementation header + file) and + <code><b>name-pimpl.cxx</b></code> (parser implementation source + file). If the <code><b>--generate-test-driver</b></code> option + is specified, the additional <code><b>name-driver.cxx</b></code> + test driver file is generated.</dd> + + <dt><code><b>help</b></code></dt> + <dd>Print usage information and exit. Use + <p><code><b>xsd help</b> <i>command</i></code></p> + for command-specific help. + </dd> + + <dt><code><b>version</b></code></dt> + <dd>Print version and exit.</dd> + </dl> + + <h1>OPTIONS</h1> + + <p>Command-specific <code><i>options</i></code>, if any, should appear + after the corresponding <code><i>command</i></code>.</p> + + <h2>COMMON OPTIONS</h2> + <dl class="options"> + <dt><code><b>--std</b></code> <code><i>version</i></code></dt> + <dd>Specify the C++ standard that the generated code should conform to. + Valid values are <code><b>c++98</b></code>, <code><b>c++11</b></code> + (default), <code><b>c++14</b></code>, <code><b>c++17</b></code>, + <code><b>c++20</b></code>, and <code><b>c++23</b></code>. + + <p>The C++ standard affects various aspects of the generated code that are + discussed in more detail in various mapping-specific documentation. + Overall, when C++11 is selected, the generated code relies on the move + semantics and uses <code><b>std::unique_ptr</b></code> instead of + deprecated <code><b>std::auto_ptr</b></code>. Currently, there is no + difference between the C++11 and the later standards modes.</p> + + <p>When the C++11 mode is selected, you normally don't need to perform any + extra steps other than enable C++11 in your C++ compiler, if required. The + XSD compiler will automatically add the necessary macro defines to the + generated header files that will switch the header-only XSD runtime + library (<code><b>libxsd</b></code>) to the C++11 mode. However, if you + include any of the XSD runtime headers directly in your application + (normally you just include the generated headers), then you will need to + define the <code><b>XSD_CXX11</b></code> macro for your entire + project.</p></dd> + + <dt><code><b>--char-type</b></code> <code><i>type</i></code></dt> + <dd>Generate code using the provided character <code><i>type</i></code> + instead of the default <code><b>char</b></code>. Valid values are + <code><b>char</b></code> and <code><b>wchar_t</b></code>.</dd> + + <dt><code><b>--char-encoding</b></code> <code><i>enc</i></code></dt> + <dd>Specify the character encoding that should be used in the generated + code. Valid values for the <code><b>char</b></code> character type are + <code><b>utf8</b></code> (default), <code><b>iso8859-1</b></code>, + <code><b>lcp</b></code> (Xerces-C++ local code page), and + <code><b>custom</b></code>. If you pass <code><b>custom</b></code> as the + value then you will need to include the transcoder implementation header + for your encoding at the beginning of the generated header files (see the + <code><b>--hxx-prologue</b></code> option). + + <p>For the <code><b>wchar_t</b></code> character type the only valid value + is <code><b>auto</b></code> and the encoding is automatically selected + between UTF-16 and UTF-32/UCS-4, depending on the + <code><b>wchar_t</b></code> type size.</p></dd> + + <dt><code><b>--output-dir</b></code> <code><i>dir</i></code></dt> + <dd>Write generated files to <code><i>dir</i></code> instead of the + current directory.</dd> + + <dt><code><b>--generate-inline</b></code></dt> + <dd>Generate simple functions inline. This option triggers creation of the + inline file.</dd> + + <dt><code><b>--generate-xml-schema</b></code></dt> + <dd>Generate a C++ header file as if the schema being compiled defines the + XML Schema namespace. For the C++/Tree mapping, the resulting file will + contain definitions for all XML Schema built-in types. For the C++/Parser + mapping, the resulting file will contain definitions for all the parser + skeletons and implementations corresponding to the XML Schema built-in + types. + + <p>The schema file provided to the compiler need not exist and is only + used to derive the name of the resulting header file. Use the + <code><b>--extern-xml-schema</b></code> option to include this file in the + generated files for other schemas.</p></dd> + + <dt><code><b>--extern-xml-schema</b></code> <code><i>file</i></code></dt> + <dd>Include a header file derived from <code><i>file</i></code> instead of + generating the XML Schema namespace mapping inline. The provided file need + not exist and is only used to derive the name of the included header file. + Use the <code><b>--generate-xml-schema</b></code> option to generate this + header file.</dd> + + <dt><code><b>--namespace-map</b></code> <code><i>xns</i></code>=<code><i>cns</i></code></dt> + <dd>Map XML Schema namespace <code><i>xns</i></code> to C++ namespace + <code><i>cns</i></code>. Repeat this option to specify mapping for more + than one XML Schema namespace. For example, the following option: + + <p class="code"><code><b>--namespace-map + http://example.com/foo/bar=foo::bar</b></code></p> + + <p>Will map the <code><b>http://example.com/foo/bar</b></code> XML Schema + namespace to the <code><b>foo::bar</b></code> C++ namespace.</p></dd> + + <dt><code><b>--namespace-regex</b></code> <code><i>regex</i></code></dt> + <dd>Add <code><i>regex</i></code> to the list of regular expressions used + to translate XML Schema namespace names to C++ namespace names. + <code><i>regex</i></code> is a Perl-like regular expression in the form + <code><b>/</b><i>pattern</i><b>/</b><i>replacement</i><b>/</b></code>. Any + character can be used as a delimiter instead of '<code><b>/</b></code>'. + Escaping of the delimiter character in <code><i>pattern</i></code> or + <code><i>replacement</i></code> is not supported. + + <p>All the regular expressions are pushed into a stack with the last + specified expression considered first. The first match that succeeds is + used. Regular expressions are applied to a string in the form</p> + + <p class="code"><code><i>filename</i> <i>namespace</i></code></p> + + <p>For example, if you have file <code><b>hello.xsd</b></code> with + namespace <code><b>http://example.com/hello</b></code> and you run + <code><b>xsd</b></code> on this file, then the string in question will + be:</p> + + <p class="code"><code><b>hello.xsd. + http://example.com/hello</b></code></p> + + <p>For the built-in XML Schema namespace the string is:</p> + + <p class="code"><code><b>XMLSchema.xsd + http://www.w3.org/2001/XMLSchema</b></code></p> + + <p>The following three steps are performed for each regular expression + until the match is found:</p> + + <p>1. The expression is applied and if the result is empty the next + expression is considered.</p> + + <p>2. All '<code><b>/</b></code>' are replaced with + '<code><b>::</b></code>'.</p> + + <p>3. The result is verified to be a valid C++ scope name (e.g., + <code><b>foo::bar</b></code>). If this test succeeds, the result is used + as a C++ namespace name.</p> + + <p>As an example, the following expression maps XML Schema namespaces in + the form <code><b>http://example.com/foo/bar</b></code> to C++ namespaces + in the form <code><b>foo::bar</b></code>:</p> + + <p class="code"><code><b>%.* http://example.com/(.+)%$1%</b></code></p> + + <p>See also the REGEX AND SHELL QUOTING section below.</p></dd> + + <dt><code><b>--namespace-regex-trace</b></code></dt> + <dd>Trace the process of applying regular expressions specified with the + <code><b>--namespace-regex</b></code> option. Use this option to find out + why your regular expressions don't do what you expected them to do.</dd> + + <dt><code><b>--reserved-name</b></code> <code><i>n</i></code>[=<code><i>r</i></code>]</dt> + <dd>Add name <code><i>n</i></code> to the list of names that should not be + used as identifiers. The name can optionally be followed by + <code><b>=</b></code> and the replacement name <code><i>r</i></code> that + should be used instead. All the C++ keywords are already in this + list.</dd> + + <dt><code><b>--include-with-brackets</b></code></dt> + <dd>Use angle brackets (<>) instead of quotes ("") in generated + <code><b>#include</b></code> directives.</dd> + + <dt><code><b>--include-prefix</b></code> <code><i>prefix</i></code></dt> + <dd>Add <code><i>prefix</i></code> to generated + <code><b>#include</b></code> directive paths. + + <p>For example, if you had the following import element in your schema</p> + + <p class="code"><code><b><import namespace="..." + schemaLocation="base.xsd"/></b></code></p> + + <p>and compiled this fragment with <code><b>--include-prefix + schemas/</b></code>, then the include directive in the generated code + would be:</p> + + <p class="code"><code><b>#include "schemas/base.hxx"</b></code></p></dd> + + <dt><code><b>--include-regex</b></code> <code><i>regex</i></code></dt> + <dd>Add <code><i>regex</i></code> to the list of regular expressions used + to transform <code><b>#include</b></code> directive paths. + <code><i>regex</i></code> is a Perl-like regular expression in the form + <code><b>/</b><i>pattern</i><b>/</b><i>replacement</i><b>/</b></code>. Any + character can be used as a delimiter instead of '<code><b>/</b></code>'. + Escaping of the delimiter character in <code><i>pattern</i></code> or + <code><i>replacement</i></code> is not supported. + + <p>All the regular expressions are pushed into a stack with the last + specified expression considered first. The first match that succeeds is + used.</p> + + <p>As an example, the following expression transforms paths in the form + <code><b>schemas/foo/bar</b></code> to paths in the form + <code><b>generated/foo/bar</b></code>:</p> + + <p class="code"><code><b>%schemas/(.+)%generated/$1%</b></code></p> + + <p>See also the REGEX AND SHELL QUOTING section below.</p></dd> + + <dt><code><b>--include-regex-trace</b></code></dt> + <dd>Trace the process of applying regular expressions specified with the + <code><b>--include-regex</b></code> option. Use this option to find out + why your regular expressions don't do what you expected them to do.</dd> + + <dt><code><b>--guard-prefix</b></code> <code><i>prefix</i></code></dt> + <dd>Add <code><i>prefix</i></code> to generated header inclusion guards. + The prefix is transformed to upper case and characters that are illegal in + a preprocessor macro name are replaced with underscores. If this option is + not specified then the directory part of the input schema file is used as + a prefix.</dd> + + <dt><code><b>--hxx-suffix</b></code> <code><i>suffix</i></code></dt> + <dd>Use the provided <code><i>suffix</i></code> instead of the default + <code><b>.hxx</b></code> to construct the name of the header file. Note + that this suffix is also used to construct names of header files + corresponding to included/imported schemas.</dd> + + <dt><code><b>--ixx-suffix</b></code> <code><i>suffix</i></code></dt> + <dd>Use the provided <code><i>suffix</i></code> instead of the default + <code><b>.ixx</b></code> to construct the name of the inline file.</dd> + + <dt><code><b>--cxx-suffix</b></code> <code><i>suffix</i></code></dt> + <dd>Use the provided <code><i>suffix</i></code> instead of the default + <code><b>.cxx</b></code> to construct the name of the source file.</dd> + + <dt><code><b>--fwd-suffix</b></code> <code><i>suffix</i></code></dt> + <dd>Use the provided <code><i>suffix</i></code> instead of the default + <code><b>-fwd.hxx</b></code> to construct the name of the forward + declaration file.</dd> + + <dt><code><b>--hxx-regex</b></code> <code><i>regex</i></code></dt> + <dd>Use the provided expression to construct the name of the header file. + <code><i>regex</i></code> is a Perl-like regular expression in the form + <code><b>/</b><i>pattern</i><b>/</b><i>replacement</i><b>/</b></code>. + Note that this expression is also used to construct names of header files + corresponding to included/imported schemas. See also the REGEX AND SHELL + QUOTING section below.</dd> + + <dt><code><b>--ixx-regex</b></code> <code><i>regex</i></code></dt> + <dd>Use the provided expression to construct the name of the inline file. + <code><i>regex</i></code> is a Perl-like regular expression in the form + <code><b>/</b><i>pattern</i><b>/</b><i>replacement</i><b>/</b></code>. See + also the REGEX AND SHELL QUOTING section below.</dd> + + <dt><code><b>--cxx-regex</b></code> <code><i>regex</i></code></dt> + <dd>Use the provided expression to construct the name of the source file. + <code><i>regex</i></code> is a Perl-like regular expression in the form + <code><b>/</b><i>pattern</i><b>/</b><i>replacement</i><b>/</b></code>. See + also the REGEX AND SHELL QUOTING section below.</dd> + + <dt><code><b>--fwd-regex</b></code> <code><i>regex</i></code></dt> + <dd>Use the provided expression to construct the name of the forward + declaration file. <code><i>regex</i></code> is a Perl-like regular + expression in the form + <code><b>/</b><i>pattern</i><b>/</b><i>replacement</i><b>/</b></code>. See + also the REGEX AND SHELL QUOTING section below.</dd> + + <dt><code><b>--hxx-prologue</b></code> <code><i>text</i></code></dt> + <dd>Insert <code><i>text</i></code> at the beginning of the header + file.</dd> + + <dt><code><b>--ixx-prologue</b></code> <code><i>text</i></code></dt> + <dd>Insert <code><i>text</i></code> at the beginning of the inline + file.</dd> + + <dt><code><b>--cxx-prologue</b></code> <code><i>text</i></code></dt> + <dd>Insert <code><i>text</i></code> at the beginning of the source + file.</dd> + + <dt><code><b>--fwd-prologue</b></code> <code><i>text</i></code></dt> + <dd>Insert <code><i>text</i></code> at the beginning of the forward + declaration file.</dd> + + <dt><code><b>--prologue</b></code> <code><i>text</i></code></dt> + <dd>Insert <code><i>text</i></code> at the beginning of each generated + file for which there is no file-specific prologue.</dd> + + <dt><code><b>--hxx-epilogue</b></code> <code><i>text</i></code></dt> + <dd>Insert <code><i>text</i></code> at the end of the header file.</dd> + + <dt><code><b>--ixx-epilogue</b></code> <code><i>text</i></code></dt> + <dd>Insert <code><i>text</i></code> at the end of the inline file.</dd> + + <dt><code><b>--cxx-epilogue</b></code> <code><i>text</i></code></dt> + <dd>Insert <code><i>text</i></code> at the end of the source file.</dd> + + <dt><code><b>--fwd-epilogue</b></code> <code><i>text</i></code></dt> + <dd>Insert <code><i>text</i></code> at the end of the forward declaration + file.</dd> + + <dt><code><b>--epilogue</b></code> <code><i>text</i></code></dt> + <dd>Insert <code><i>text</i></code> at the end of each generated file for + which there is no file-specific epilogue.</dd> + + <dt><code><b>--hxx-prologue-file</b></code> <code><i>file</i></code></dt> + <dd>Insert the content of the <code><i>file</i></code> at the beginning of + the header file.</dd> + + <dt><code><b>--ixx-prologue-file</b></code> <code><i>file</i></code></dt> + <dd>Insert the content of the <code><i>file</i></code> at the beginning of + the inline file.</dd> + + <dt><code><b>--cxx-prologue-file</b></code> <code><i>file</i></code></dt> + <dd>Insert the content of the <code><i>file</i></code> at the beginning of + the source file.</dd> + + <dt><code><b>--fwd-prologue-file</b></code> <code><i>file</i></code></dt> + <dd>Insert the content of the <code><i>file</i></code> at the beginning of + the forward declaration file.</dd> + + <dt><code><b>--prologue-file</b></code> <code><i>file</i></code></dt> + <dd>Insert the content of the <code><i>file</i></code> at the beginning of + each generated file for which there is no file-specific prologue + file.</dd> + + <dt><code><b>--hxx-epilogue-file</b></code> <code><i>file</i></code></dt> + <dd>Insert the content of the <code><i>file</i></code> at the end of the + header file.</dd> + + <dt><code><b>--ixx-epilogue-file</b></code> <code><i>file</i></code></dt> + <dd>Insert the content of the <code><i>file</i></code> at the end of the + inline file.</dd> + + <dt><code><b>--cxx-epilogue-file</b></code> <code><i>file</i></code></dt> + <dd>Insert the content of the <code><i>file</i></code> at the end of the + source file.</dd> + + <dt><code><b>--fwd-epilogue-file</b></code> <code><i>file</i></code></dt> + <dd>Insert the content of the <code><i>file</i></code> at the end of the + forward declaration file.</dd> + + <dt><code><b>--epilogue-file</b></code> <code><i>file</i></code></dt> + <dd>Insert the content of the <code><i>file</i></code> at the end of each + generated file for which there is no file-specific epilogue file.</dd> + + <dt><code><b>--export-symbol</b></code> <code><i>symbol</i></code></dt> + <dd>Insert <code><i>symbol</i></code> in places where DLL export/import + control statements (<code><b>__declspec(dllexport/dllimport)</b></code>) + are necessary.</dd> + + <dt><code><b>--export-xml-schema</b></code></dt> + <dd>Export/import types in the XML Schema namespace using the export + symbol provided with the <code><b>--export-symbol</b></code> option. The + <code><b>XSD_NO_EXPORT</b></code> macro can be used to omit this code + during C++ compilation, which may be useful if you would like to use the + same generated code across multiple platforms.</dd> + + <dt><code><b>--export-maps</b></code></dt> + <dd>Export polymorphism support maps from a Win32 DLL into which this + generated code is placed. This is necessary when your type hierarchy is + split across several DLLs since otherwise each DLL will have its own set + of maps. In this situation the generated code for the DLL which contains + base types and/or substitution group heads should be compiled with this + option and the generated code for all other DLLs should be compiled with + <code><b>--import-maps</b></code>. This option is only valid together with + <code><b>--generate-polymorphic</b></code>. The + <code><b>XSD_NO_EXPORT</b></code> macro can be used to omit this code + during C++ compilation, which may be useful if you would like to use the + same generated code across multiple platforms.</dd> + + <dt><code><b>--import-maps</b></code></dt> + <dd>Import polymorphism support maps to a Win32 DLL or executable into + which this generated code is linked. See the + <code><b>--export-maps</b></code> option documentation for details. This + options is only valid together with + <code><b>--generate-polymorphic</b></code>. The + <code><b>XSD_NO_EXPORT</b></code> macro can be used to omit this code + during C++ compilation, which may be useful if you would like to use the + same generated code across multiple platforms.</dd> + + <dt><code><b>--generate-dep</b></code></dt> + <dd>Generate <code><b>make</b></code> dependency information. This option + triggers the creation of the <code><b>.d</b></code> file containing the + dependencies of the generated files on the main schema file as well as all + the schema files that it includes/imports, transitively. This dependency + file is then normally included into the main <code><b>makefile</b></code> + to implement automatic dependency tracking. See also the + <code><b>--dep-*</b></code> options. + + <p>Note also that automatic dependency generation is not supported in the + file-per-type mode (<code><b>--file-per-type</b></code>). In this case, + all the generated files are produced with a single compiler invocation and + depend on all the schemas. As a result, it is easier to establish such a + dependency manually, perhaps with the help of the + <code><b>--file-list*</b></code> options.</p></dd> + + <dt><code><b>--generate-dep-only</b></code></dt> + <dd>Generate <code><b>make</b></code> dependency information only.</dd> + + <dt><code><b>--dep-phony</b></code></dt> + <dd>Generate phony targets for included/imported schema files, causing + each to depend on nothing. Such dummy rules work around + <code><b>make</b></code> errors caused by the removal of schema files + without also updating the dependency file to match.</dd> + + <dt><code><b>--dep-target</b></code> <code><i>target</i></code></dt> + <dd>Change the target of the dependency rule. By default it contains all + the generated C++ files as well as the dependency file itself, without any + directory prefixes. If you require multiple targets, then you can specify + them as a single, space-separated argument or you can repeat this option + multiple times.</dd> + + <dt><code><b>--dep-suffix</b></code> <code><i>suffix</i></code></dt> + <dd>Use <code><i>suffix</i></code> instead of the default + <code><b>.d</b></code> to construct the name of the dependency file. See + also <code><b>--dep-file</b></code>.</dd> + + <dt><code><b>--dep-file</b></code> <code><i>path</i></code></dt> + <dd>Use <code><i>path</i></code> as the generated dependency file path + instead of deriving it from the input file name. Write the dependency + information to <code><b>stdout</b></code> if <code><i>path</i></code> is + <code><b>-</b></code>. See also <code><b>--dep-regex</b></code>.</dd> + + <dt><code><b>--dep-regex</b></code> <code><i>regex</i></code></dt> + <dd>Use the provided expression to construct the name of the dependency + file. <code><i>regex</i></code> is a Perl-like regular expression in the + form + <code><b>/</b><i>pattern</i><b>/</b><i>replacement</i><b>/</b></code>. See + also the REGEX AND SHELL QUOTING section below.</dd> + + <dt><code><b>--disable-warning</b></code> <code><i>warn</i></code></dt> + <dd>Disable printing warning with id <code><i>warn</i></code>. If + <code><b>all</b></code> is specified for the warning id then all warnings + are disabled.</dd> + + <dt><code><b>--options-file</b></code> <code><i>file</i></code></dt> + <dd>Read additional options from <code><i>file</i></code>. Each option + should appearing on a separate line optionally followed by space and an + option value. Empty lines and lines starting with <code><b>#</b></code> + are ignored. Option values can be enclosed in double + (<code><b>"</b></code>) or single (<code><b>'</b></code>) quotes to + preserve leading and trailing whitespaces as well as to specify empty + values. If the value itself contains trailing or leading quotes, enclose + it with an extra pair of quotes, for example <code><b>'"x"'</b></code>. + Non-leading and non-trailing quotes are interpreted as being part of the + option value. + + <p>The semantics of providing options in a file is equivalent to providing + the same set of options in the same order on the command line at the point + where the <code><b>--options-file</b></code> option is specified except + that the shell escaping and quoting is not required. You can repeat this + option to specify more than one options file.</p></dd> + + <dt><code><b>--show-sloc</b></code></dt> + <dd>Show the number of generated physical source lines of code + (SLOC).</dd> + + <dt><code><b>--sloc-limit</b></code> <code><i>num</i></code></dt> + <dd>Check that the number of generated physical source lines of code + (SLOC) does not exceed <code><i>num</i></code>.</dd> + + <dt><code><b>--proprietary-license</b></code></dt> + <dd>Indicate that the generated code is licensed under a proprietary + license instead of the GPL.</dd> + + <dt><code><b>--custom-literals</b></code> <code><i>file</i></code></dt> + <dd>Load custom XML string to C++ literal mappings from + <code><i>file</i></code>. This mechanism can be useful if you are using a + custom character encoding and some of the strings in your schemas, for + example element/attribute names or enumeration values, contain non-ASCII + characters. In this case you will need to provide a custom mapping to C++ + literals for such strings. The format of this file is specified in the + <code><b>custom-literals.xsd</b></code> XML Schema file that can be found + in the documentation directory.</dd> + + <dt><code><b>--preserve-anonymous</b></code></dt> + <dd>Preserve anonymous types. By default anonymous types are automatically + named with names derived from the enclosing elements/attributes. Because + mappings implemented by this compiler require all types to be named, this + option is only useful if you want to make sure your schemas don't have + anonymous types.</dd> + + <dt><code><b>--show-anonymous</b></code></dt> + <dd>Show elements and attributes that are of anonymous types. This option + only makes sense together with the + <code><b>--preserve-anonymous</b></code> option.</dd> + + <dt><code><b>--anonymous-regex</b></code> <code><i>regex</i></code></dt> + <dd>Add <code><i>regex</i></code> to the list of regular expressions used + to derive names for anonymous types from the enclosing + attributes/elements. <code><i>regex</i></code> is a Perl-like regular + expression in the form + <code><b>/</b><i>pattern</i><b>/</b><i>replacement</i><b>/</b></code>. Any + character can be used as a delimiter instead of '<code><b>/</b></code>'. + Escaping of the delimiter character in <code><i>pattern</i></code> or + <code><i>replacement</i></code> is not supported. + + <p>All the regular expressions are pushed into a stack with the last + specified expression considered first. The first match that succeeds is + used. Regular expressions are applied to a string in the form</p> + + <p class="code"><code><i>filename</i> <i>namespace</i> + <i>xpath</i></code></p> + + <p>For instance:</p> + + <p class="code"><code><b>hello.xsd http://example.com/hello + element</b></code></p> + + <p class="code"><code><b>hello.xsd http://example.com/hello + type/element</b></code></p> + + <p>As an example, the following expression makes all the derived names + start with capital letters. This could be useful when your naming + convention requires type names to start with capital letters:</p> + + <p class="code"><code><b>%.* .* (.+/)*(.+)%\u$2%</b></code></p> + + <p>See also the REGEX AND SHELL QUOTING section below.</p></dd> + + <dt><code><b>--anonymous-regex-trace</b></code></dt> + <dd>Trace the process of applying regular expressions specified with the + <code><b>--anonymous-regex</b></code> option. Use this option to find out + why your regular expressions don't do what you expected them to do.</dd> + + <dt><code><b>--location-map</b></code> <code><i>ol</i></code>=<code><i>nl</i></code></dt> + <dd>Map the original schema location <code><i>ol</i></code> that is + specified in the XML Schema include or import elements to new schema + location <code><i>nl</i></code>. Repeat this option to map more than one + schema location. For example, the following option maps the + <code><b>http://example.com/foo.xsd</b></code> URL to the + <code><b>foo.xsd</b></code> local file. + + <p class="code"><code><b>--location-map + http://example.com/foo.xsd=foo.xsd</b></code></p></dd> + + <dt><code><b>--location-regex</b></code> <code><i>regex</i></code></dt> + <dd>Add <code><i>regex</i></code> to the list of regular expressions used + to map schema locations that are specified in the XML Schema include or + import elements. <code><i>regex</i></code> is a Perl-like regular + expression in the form + <code><b>/</b><i>pattern</i><b>/</b><i>replacement</i><b>/</b></code>. Any + character can be used as a delimiter instead of '<code><b>/</b></code>'. + Escaping of the delimiter character in <code><i>pattern</i></code> or + <code><i>replacement</i></code> is not supported. All the regular + expressions are pushed into a stack with the last specified expression + considered first. The first match that succeeds is used. + + <p>For example, the following expression maps URL locations in the form + <code><b>http://example.com/foo/bar.xsd</b></code> to local files in the + form <code><b>bar.xsd</b></code>:</p> + + <p class="code"><code><b>%http://.+/(.+)%$1%</b></code></p> + + <p>See also the REGEX AND SHELL QUOTING section below.</p></dd> + + <dt><code><b>--location-regex-trace</b></code></dt> + <dd>Trace the process of applying regular expressions specified with the + <code><b>--location-regex</b></code> option. Use this option to find out + why your regular expressions don't do what you expected them to do.</dd> + + <dt><code><b>--file-per-type</b></code></dt> + <dd>Generate a separate set of C++ files for each type defined in XML + Schema. Note that in this mode you only need to compile the root schema(s) + and the code will be generated for all included and imported schemas. This + compilation mode is primarily useful when some of your schemas cannot be + compiled separately or have cyclic dependencies which involve type + inheritance. Other options related to this mode are: + <code><b>--type-file-regex</b></code>, + <code><b>--schema-file-regex</b></code>, + <code><b>--fat-type-file</b></code>, and + <code><b>--file-list</b></code>.</dd> + + <dt><code><b>--type-file-regex</b></code> <code><i>regex</i></code></dt> + <dd>Add <code><i>regex</i></code> to the list of regular expressions used + to translate type names to file names when the + <code><b>--file-per-type</b></code> option is specified. + <code><i>regex</i></code> is a Perl-like regular expression in the form + <code><b>/</b><i>pattern</i><b>/</b><i>replacement</i><b>/</b></code>. Any + character can be used as a delimiter instead of '<code><b>/</b></code>'. + Escaping of the delimiter character in <code><i>pattern</i></code> or + <code><i>replacement</i></code> is not supported. All the regular + expressions are pushed into a stack with the last specified expression + considered first. The first match that succeeds is used. Regular + expressions are applied to a string in the form + + <p class="code"><code><i>namespace</i> <i>type-name</i></code></p> + + <p>For example, the following expression maps type <code><b>foo</b></code> + that is defined in the <code><b>http://example.com/bar</b></code> + namespace to file name <code><b>bar-foo</b></code>:</p> + + <p class="code"><code><b>%http://example.com/(.+) + (.+)%$1-$2%</b></code></p> + + <p>See also the REGEX AND SHELL QUOTING section below.</p></dd> + + <dt><code><b>--type-file-regex-trace</b></code></dt> + <dd>Trace the process of applying regular expressions specified with the + <code><b>--type-file-regex</b></code> option. Use this option to find out + why your regular expressions don't do what you expected them to do.</dd> + + <dt><code><b>--schema-file-regex</b></code> <code><i>regex</i></code></dt> + <dd>Add <code><i>regex</i></code> to the list of regular expressions used + to translate schema file names when the + <code><b>--file-per-type</b></code> option is specified. + <code><i>regex</i></code> is a Perl-like regular expression in the form + <code><b>/</b><i>pattern</i><b>/</b><i>replacement</i><b>/</b></code>. Any + character can be used as a delimiter instead of '<code><b>/</b></code>'. + Escaping of the delimiter character in <code><i>pattern</i></code> or + <code><i>replacement</i></code> is not supported. All the regular + expressions are pushed into a stack with the last specified expression + considered first. The first match that succeeds is used. Regular + Expressions are applied to the absolute filesystem path of a schema file + and the result, including the directory part, if any, is used to derive + the <code><b>#include</b></code> directive paths as well as the generated + C++ file paths. This option, along with + <code><b>--type-file-regex</b></code> are primarily useful to place the + generated files into subdirectories or to resolve file name conflicts. + + <p>For example, the following expression maps schema files in the + <code><b>foo/1.0.0/</b></code> subdirectory to the files in the + <code><b>foo/</b></code> subdirectory. As a result, the + <code><b>#include</b></code> directive paths for such schemas will be in + the <code><b>foo/schema.hxx</b></code> form and the generated C++ files + will be placed into the <code><b>foo/</b></code> subdirectory:</p> + + <p class="code"><code><b>%.*/foo/1.0.0/(.+)%foo/$1%</b></code></p> + + <p>See also the REGEX AND SHELL QUOTING section below.</p></dd> + + <dt><code><b>--schema-file-regex-trace</b></code></dt> + <dd>Trace the process of applying regular expressions specified with the + <code><b>--schema-file-regex</b></code> option. Use this option to find + out why your regular expressions don't do what you expected them to + do.</dd> + + <dt><code><b>--fat-type-file</b></code></dt> + <dd>Generate code corresponding to global elements into type files instead + of schema files when the <code><b>--type-file-regex</b></code> option is + specified. This option is primarily useful when trying to minimize the + amount of object code that is linked to an executable by packaging + compiled generated code into a static (archive) library.</dd> + + <dt><code><b>--file-list</b></code> <code><i>file</i></code></dt> + <dd>Write a list of generated C++ files to <code><i>file</i></code> or to + <code><b>stdout</b></code> if <code><i>file</i></code> is + <code><b>-</b></code>. This option is primarily useful in the + file-per-type compilation mode (<code><b>--file-per-type</b></code>) to + create a list of generated C++ files, for example, as a makefile + fragment.</dd> + + <dt><code><b>--file-list-only</b></code></dt> + <dd>Only write the list of C++ files that would be generated without + actually generating them. This option only makes sense together with + <code><b>--file-list</b></code>.</dd> + + <dt><code><b>--file-list-prologue</b></code> <code><i>text</i></code></dt> + <dd>Insert <code><i>text</i></code> at the beginning of the file list. As + a convenience, all occurrences of the <code><b>\n</b></code> character + sequence in <code><i>text</i></code> are replaced with new lines. This + option can, for example, be used to assign the generated file list to a + makefile variable.</dd> + + <dt><code><b>--file-list-epilogue</b></code> <code><i>text</i></code></dt> + <dd>Insert <code><i>text</i></code> at the end of the file list. As a + convenience, all occurrences of the <code><b>\n</b></code> character + sequence in <code><i>text</i></code> are replaced with new lines.</dd> + + <dt><code><b>--file-list-delim</b></code> <code><i>text</i></code></dt> + <dd>Delimit file names written to the file list with + <code><i>text</i></code> instead of new lines. As a convenience, all + occurrences of the <code><b>\n</b></code> character sequence in + <code><i>text</i></code> are replaced with new lines.</dd> + </dl> + + <h2>CXX-TREE COMMAND OPTIONS</h2> + <dl class="options"> + <dt><code><b>--generate-polymorphic</b></code></dt> + <dd>Generate polymorphism-aware code. Specify this option if you use + substitution groups or <code><b>xsi:type</b></code>. Use the + <code><b>--polymorphic-type</b></code> or + <code><b>--polymorphic-type-all</b></code> option to specify which type + hierarchies are polymorphic.</dd> + + <dt><code><b>--polymorphic-type</b></code> <code><i>type</i></code></dt> + <dd>Indicate that <code><i>type</i></code> is a root of a polymorphic type + hierarchy. The compiler can often automatically determine which types are + polymorphic based on the substitution group declarations. However, you may + need to use this option if you are not using substitution groups or if + substitution groups are defined in another schema. You need to specify + this option when compiling every schema file that references + <code><i>type</i></code>. The <code><i>type</i></code> argument is an XML + Schema type name that can be optionally qualified with a namespace in the + <code><i>namespace</i><b>#</b><i>name</i></code> form.</dd> + + <dt><code><b>--polymorphic-type-all</b></code></dt> + <dd>Indicate that all types should be treated as polymorphic.</dd> + + <dt><code><b>--polymorphic-plate</b></code> <code><i>num</i></code></dt> + <dd>Specify the polymorphic map plate the generated code should register + on. This functionality is primarily useful to segregate multiple schemas + that define the same polymorphic types.</dd> + + <dt><code><b>--ordered-type</b></code> <code><i>type</i></code></dt> + <dd>Indicate that element order in <code><i>type</i></code> is + significant. An example would be a complex type with unbounded choice as a + content model where the element order in XML has application-specific + semantics. For ordered types the compiler generates a special container + data member and a corresponding set of accessors and modifiers that are + used to capture the order of elements and, for mixed content, of text. + + <p>The <code><i>type</i></code> argument is an XML Schema type name that + can be optionally qualified with a namespace in the + <code><i>namespace</i><b>#</b><i>name</i></code> form. Note also that you + will need to specify this option when compiling every schema file that has + other ordered types derived from this type.</p></dd> + + <dt><code><b>--ordered-type-derived</b></code></dt> + <dd>Automatically treat types derived from ordered bases as also ordered. + This is primarily useful if you would like to be able to iterate over the + complete content using the content order container.</dd> + + <dt><code><b>--ordered-type-mixed</b></code></dt> + <dd>Automatically treat complex types with mixed content as ordered.</dd> + + <dt><code><b>--ordered-type-all</b></code></dt> + <dd>Indicate that element order in all types is significant.</dd> + + <dt><code><b>--order-container</b></code> <code><i>type</i></code></dt> + <dd>Specify a custom class template that should be used as a container for + the content order in ordered types instead of the default + <code><b>std::vector</b></code>. See <code><b>--ordered-type</b></code> + for more information on ordered type. This option is primarily useful if + you need to perform more complex lookups in the content order container, + for example by element id. In this case, a container like Boost + multi-index may be more convenient. Note that if using a custom container, + you will also most likely need to include the relevant headers using the + <code><b>--hxx-prologue*</b></code> options.</dd> + + <dt><code><b>--generate-serialization</b></code></dt> + <dd>Generate serialization functions. Serialization functions convert the + object model back to XML.</dd> + + <dt><code><b>--generate-ostream</b></code></dt> + <dd>Generate ostream insertion operators + (<code><b>operator<<</b></code>) for generated types. This allows + one to easily print a fragment or the whole object model for debugging or + logging.</dd> + + <dt><code><b>--generate-doxygen</b></code></dt> + <dd>Generate documentation comments suitable for extraction by the Doxygen + documentation system. Documentation from annotations is added to the + comments if present in the schema.</dd> + + <dt><code><b>--generate-comparison</b></code></dt> + <dd>Generate comparison operators (<code><b>operator==</b></code> and + <code><b>operator!=</b></code>) for complex types. Comparison is performed + member-wise.</dd> + + <dt><code><b>--generate-default-ctor</b></code></dt> + <dd>Generate default constructors even for types that have required + members. Required members of an instance constructed using such a + constructor are not initialized and accessing them results in undefined + behavior.</dd> + + <dt><code><b>--generate-from-base-ctor</b></code></dt> + <dd>Generate constructors that expect an instance of a base type followed + by all required members.</dd> + + <dt><code><b>--suppress-assignment</b></code></dt> + <dd>Suppress the generation of copy assignment operators for complex + types. If this option is specified, the copy assignment operators for such + types are declared private and left unimplemented.</dd> + + <dt><code><b>--generate-detach</b></code></dt> + <dd>Generate detach functions for required elements and attributes. Detach + functions for optional and sequence cardinalities are provided by the + respective containers. These functions, for example, allow you to move + sub-trees in the object model either within the same tree or between + different trees.</dd> + + <dt><code><b>--generate-wildcard</b></code></dt> + <dd>Generate accessors and modifiers as well as parsing and serialization + code for XML Schema wildcards (<code><b>any</b></code> and + <code><b>anyAttribute</b></code>). XML content matched by wildcards is + presented as DOM fragments. Note that you need to initialize the + Xerces-C++ runtime if you are using this option.</dd> + + <dt><code><b>--generate-any-type</b></code></dt> + <dd>Extract and store content of the XML Schema + <code><b>anyType</b></code> type as a DOM fragment. Note that you need to + initialize the Xerces-C++ runtime if you are using this option.</dd> + + <dt><code><b>--generate-insertion</b></code> <code><i>os</i></code></dt> + <dd>Generate data representation stream insertion operators for the + <code><i>os</i></code> output stream type. Repeat this option to specify + more than one stream type. The ACE CDR stream + (<code><b>ACE_OutputCDR</b></code>) and RPC XDR are recognized by the + compiler and the necessary <code><b>#include</b></code> directives are + automatically generated. For custom stream types use the + <code><b>--hxx-prologue*</b></code> options to provide the necessary + declarations.</dd> + + <dt><code><b>--generate-extraction</b></code> <code><i>is</i></code></dt> + <dd>Generate data representation stream extraction constructors for the + <code><i>is</i></code> input stream type. Repeat this option to specify + more than one stream type. The ACE CDR stream + (<code><b>ACE_InputCDR</b></code>) and RPC XDR are recognized by the + compiler and the necessary <code><b>#include</b></code> directives are + automatically generated. For custom stream types use the + <code><b>--hxx-prologue*</b></code> options to provide the necessary + declarations.</dd> + + <dt><code><b>--generate-forward</b></code></dt> + <dd>Generate a separate header file with forward declarations for the + types being generated.</dd> + + <dt><code><b>--suppress-parsing</b></code></dt> + <dd>Suppress the generation of the parsing functions and constructors. Use + this option to reduce the generated code size when parsing from XML is not + needed.</dd> + + <dt><code><b>--generate-element-type</b></code></dt> + <dd>Generate types instead of parsing and serialization functions for root + elements. This is primarily useful to distinguish object models with the + same root type but with different root elements.</dd> + + <dt><code><b>--generate-element-map</b></code></dt> + <dd>Generate a root element map that allows uniform parsing and + serialization of multiple root elements. This option is only valid + together with <code><b>--generate-element-type</b></code>.</dd> + + <dt><code><b>--generate-intellisense</b></code></dt> + <dd>Generate workarounds for IntelliSense bugs in Visual Studio 2005 + (8.0). When this option is used, the resulting code is slightly more + verbose. IntelliSense in Visual Studio 2008 (9.0) and later does not + require these workarounds. Support for IntelliSense in Visual Studio 2003 + (7.1) is improved with this option but is still incomplete.</dd> + + <dt><code><b>--omit-default-attributes</b></code></dt> + <dd>Omit attributes with default and fixed values from serialized XML + documents.</dd> + + <dt><code><b>--type-naming</b></code> <code><i>style</i></code></dt> + <dd>Specify the type naming convention that should be used in the + generated code. Valid styles are <code><b>knr</b></code> (default), + <code><b>ucc</b></code>, and <code><b>java</b></code>. See the NAMING + CONVENTION section below for more information.</dd> + + <dt><code><b>--function-naming</b></code> <code><i>style</i></code></dt> + <dd>Specify the function naming convention that should be used in the + generated code. Valid styles are <code><b>knr</b></code> (default), + <code><b>lcc</b></code>, <code><b>ucc</b></code>, and + <code><b>java</b></code>. See the NAMING CONVENTION section below for more + information.</dd> + + <dt><code><b>--type-regex</b></code> <code><i>regex</i></code></dt> + <dd>Add <code><i>regex</i></code> to the list of regular expressions used + to translate XML Schema type names to C++ type names. See the NAMING + CONVENTION section below for more information.</dd> + + <dt><code><b>--accessor-regex</b></code> <code><i>regex</i></code></dt> + <dd>Add <code><i>regex</i></code> to the list of regular expressions used + to translate XML Schema names of elements/attributes to C++ accessor + function names. See the NAMING CONVENTION section below for more + information.</dd> + + <dt><code><b>--one-accessor-regex</b></code> <code><i>regex</i></code></dt> + <dd>Add <code><i>regex</i></code> to the list of regular expressions used + to translate XML Schema names of elements/attributes with cardinality one + to C++ accessor function names. See the NAMING CONVENTION section below + for more information.</dd> + + <dt><code><b>--opt-accessor-regex</b></code> <code><i>regex</i></code></dt> + <dd>Add <code><i>regex</i></code> to the list of regular expressions used + to translate XML Schema names of elements/attributes with cardinality + optional to C++ accessor function names. See the NAMING CONVENTION section + below for more information.</dd> + + <dt><code><b>--seq-accessor-regex</b></code> <code><i>regex</i></code></dt> + <dd>Add <code><i>regex</i></code> to the list of regular expressions used + to translate XML Schema names of elements/attributes with cardinality + sequence to C++ accessor function names. See the NAMING CONVENTION section + below for more information.</dd> + + <dt><code><b>--modifier-regex</b></code> <code><i>regex</i></code></dt> + <dd>Add <code><i>regex</i></code> to the list of regular expressions used + to translate XML Schema names of elements/attributes to C++ modifier + function names. See the NAMING CONVENTION section below for more + information.</dd> + + <dt><code><b>--one-modifier-regex</b></code> <code><i>regex</i></code></dt> + <dd>Add <code><i>regex</i></code> to the list of regular expressions used + to translate XML Schema names of elements/attributes with cardinality one + to C++ modifier function names. See the NAMING CONVENTION section below + for more information.</dd> + + <dt><code><b>--opt-modifier-regex</b></code> <code><i>regex</i></code></dt> + <dd>Add <code><i>regex</i></code> to the list of regular expressions used + to translate XML Schema names of elements/attributes with cardinality + optional to C++ modifier function names. See the NAMING CONVENTION section + below for more information.</dd> + + <dt><code><b>--seq-modifier-regex</b></code> <code><i>regex</i></code></dt> + <dd>Add <code><i>regex</i></code> to the list of regular expressions used + to translate XML Schema names of elements/attributes with cardinality + sequence to C++ modifier function names. See the NAMING CONVENTION section + below for more information.</dd> + + <dt><code><b>--parser-regex</b></code> <code><i>regex</i></code></dt> + <dd>Add <code><i>regex</i></code> to the list of regular expressions used + to translate XML Schema element names to C++ parsing function names. See + the NAMING CONVENTION section below for more information.</dd> + + <dt><code><b>--serializer-regex</b></code> <code><i>regex</i></code></dt> + <dd>Add <code><i>regex</i></code> to the list of regular expressions used + to translate XML Schema element names to C++ serialization function names. + See the NAMING CONVENTION section below for more information.</dd> + + <dt><code><b>--const-regex</b></code> <code><i>regex</i></code></dt> + <dd>Add <code><i>regex</i></code> to the list of regular expressions used + to translate XML Schema-derived names to C++ constant names. See the + NAMING CONVENTION section below for more information.</dd> + + <dt><code><b>--enumerator-regex</b></code> <code><i>regex</i></code></dt> + <dd>Add <code><i>regex</i></code> to the list of regular expressions used + to translate XML Schema enumeration values to C++ enumerator names. See + the NAMING CONVENTION section below for more information.</dd> + + <dt><code><b>--element-type-regex</b></code> <code><i>regex</i></code></dt> + <dd>Add <code><i>regex</i></code> to the list of regular expressions used + to translate XML Schema element names to C++ element type names. See the + NAMING CONVENTION section below for more information.</dd> + + <dt><code><b>--name-regex-trace</b></code></dt> + <dd>Trace the process of applying regular expressions specified with the + name transformation options. Use this option to find out why your regular + expressions don't do what you expected them to do.</dd> + + <dt><code><b>--root-element-first</b></code></dt> + <dd>Treat only the first global element as a document root. By default all + global elements are considered document roots.</dd> + + <dt><code><b>--root-element-last</b></code></dt> + <dd>Treat only the last global element as a document root. By default all + global elements are considered document roots.</dd> + + <dt><code><b>--root-element-all</b></code></dt> + <dd>Treat all global elements as document roots. This is the default + behavior. By explicitly specifying this option you can suppress the + warning that is issued if more than one global element is defined.</dd> + + <dt><code><b>--root-element-none</b></code></dt> + <dd>Do not treat any global elements as document roots. By default all + global elements are considered document roots.</dd> + + <dt><code><b>--root-element</b></code> <code><i>element</i></code></dt> + <dd>Treat only <code><i>element</i></code> as a document root. Repeat this + option to specify more than one root element.</dd> + + <dt><code><b>--custom-type</b></code> <code><i>map</i></code></dt> + <dd>Use a custom C++ type instead of the generated class. The + <code><i>map</i></code> argument is in the form + <code><i>name</i>[<b>=</b><i>type</i>[<b>/</b><i>base</i>]]</code>, where + <i>name</i> is a type name as defined in XML Schema and <i>type</i> is a + C++ type name that should be used instead. If <i>type</i> is not present + or empty then the custom type is assumed to have the same name and be + defined in the same namespace as the generated class would have. If + <i>base</i> is specified then the generated class is still generated but + with that name.</dd> + + <dt><code><b>--custom-type-regex</b></code> <code><i>regex</i></code></dt> + <dd>Use custom C++ types instead of the generated classes. The + <code><i>regex</i></code> argument is in the form + <code><b>/</b><i>name-pat</i><b>/</b>[<i>type-sub</i><b>/</b>[<i>base-sub</i><b>/</b>]]</code>, + where <i>name-pat</i> is a regex pattern that will be matched against type + names as defined in XML Schema and <i>type-sub</i> is a C++ type name + substitution that should be used instead. If <i>type-sub</i> is not + present or its substitution results in an empty string then the custom + type is assumed to have the same name and be defined in the same namespace + as the generated class would have. If <i>base-sub</i> is present and its + substitution results in a non-empty string then the generated class is + still generated but with the result of this substitution as its name. The + pattern and substitutions are in the Perl regular expression format. See + also the REGEX AND SHELL QUOTING section below.</dd> + + <dt><code><b>--parts</b></code> <code><i>num</i></code></dt> + <dd>Split generated source code into <code><i>num</i></code> parts. This + is useful when translating large, monolithic schemas and a C++ compiler is + not able to compile the resulting source code at once (usually due to + insufficient memory).</dd> + + <dt><code><b>--parts-suffix</b></code> <code><i>suffix</i></code></dt> + <dd>Use <code><i>suffix</i></code> instead of the default + '<code><b>-</b></code>' to separate the file name from the part + number.</dd> + </dl> + + <h2>CXX-PARSER COMMAND OPTIONS</h2> + <dl class="options"> + <dt><code><b>--type-map</b></code> <code><i>mapfile</i></code></dt> + <dd>Read XML Schema to C++ type mapping information from + <code><i>mapfile</i></code>. Repeat this option to specify several type + maps. Type maps are considered in order of appearance and the first match + is used. By default all user-defined types are mapped to + <code><b>void</b></code>. See the TYPE MAP section below for more + information.</dd> + + <dt><code><b>--xml-parser</b></code> <code><i>parser</i></code></dt> + <dd>Use <code><i>parser</i></code> as the underlying XML parser. Valid + values are <code><b>xerces</b></code> for Xerces-C++ (default) and + <code><b>expat</b></code> for Expat.</dd> + + <dt><code><b>--generate-validation</b></code></dt> + <dd>Generate validation code. The validation code ("perfect parser") + ensures that instance documents conform to the schema. Validation code is + generated by default when the selected underlying XML parser is + non-validating (<code><b>expat</b></code>).</dd> + + <dt><code><b>--suppress-validation</b></code></dt> + <dd>Suppress the generation of validation code. Validation is suppressed + by default when the selected underlying XML parser is validating + (<code><b>xerces</b></code>).</dd> + + <dt><code><b>--generate-polymorphic</b></code></dt> + <dd>Generate polymorphism-aware code. Specify this option if you use + substitution groups or <code><b>xsi:type</b></code>.</dd> + + <dt><code><b>--generate-noop-impl</b></code></dt> + <dd>Generate a sample parser implementation that does nothing (no + operation). The sample implementation can then be filled with the + application-specific code. For an input file in the form + <code><b>name.xsd</b></code> this option triggers the generation of two + additional C++ files in the form: <code><b>name-pimpl.hxx</b></code> + (parser implementation header file) and <code><b>name-pimpl.cxx</b></code> + (parser implementation source file).</dd> + + <dt><code><b>--generate-print-impl</b></code></dt> + <dd>Generate a sample parser implementation that prints the XML data to + <code>STDOUT</code>. For an input file in the form + <code><b>name.xsd</b></code> this option triggers the generation of two + additional C++ files in the form: <code><b>name-pimpl.hxx</b></code> + (parser implementation header file) and <code><b>name-pimpl.cxx</b></code> + (parser implementation source file).</dd> + + <dt><code><b>--generate-test-driver</b></code></dt> + <dd>Generate a test driver for the sample parser implementation. For an + input file in the form <code><b>name.xsd</b></code> this option triggers + the generation of an additional C++ file in the form + <code><b>name-driver.cxx</b></code>.</dd> + + <dt><code><b>--force-overwrite</b></code></dt> + <dd>Force overwriting of the existing implementation and test driver + files. Use this option only if you do not mind loosing the changes you + have made in the sample implementation or test driver files.</dd> + + <dt><code><b>--root-element-first</b></code></dt> + <dd>Indicate that the first global element is the document root. This + information is used to generate the test driver for the sample + implementation.</dd> + + <dt><code><b>--root-element-last</b></code></dt> + <dd>Indicate that the last global element is the document root. This + information is used to generate the test driver for the sample + implementation.</dd> + + <dt><code><b>--root-element</b></code> <code><i>element</i></code></dt> + <dd>Indicate that <code><i>element</i></code> is the document root. This + information is used to generate the test driver for the sample + implementation.</dd> + + <dt><code><b>--skel-type-suffix</b></code> <code><i>suffix</i></code></dt> + <dd>Use the provided <code><i>suffix</i></code> instead of the default + <code><b>_pskel</b></code> to construct the names of the generated parser + skeletons.</dd> + + <dt><code><b>--skel-file-suffix</b></code> <code><i>suffix</i></code></dt> + <dd>Use the provided <code><i>suffix</i></code> instead of the default + <code><b>-pskel</b></code> to construct the names of the generated parser + skeleton files.</dd> + + <dt><code><b>--impl-type-suffix</b></code> <code><i>suffix</i></code></dt> + <dd>Use the provided <code><i>suffix</i></code> instead of the default + <code><b>_pimpl</b></code> to construct the names of the parser + implementations for the built-in XML Schema types as well as sample parser + implementations.</dd> + + <dt><code><b>--impl-file-suffix</b></code> <code><i>suffix</i></code></dt> + <dd>Use the provided <code><i>suffix</i></code> instead of the default + <code><b>-pimpl</b></code> to construct the names of the generated sample + parser implementation files.</dd> + </dl> + + <h1>NAMING CONVENTION</h1> + + <p>The compiler can be instructed to use a particular naming + convention in the generated code. A number of widely-used + conventions can be selected using the <code><b>--type-naming</b></code> + and <code><b>--function-naming</b></code> options. A custom + naming convention can be achieved using the + <code><b>--type-regex</b></code>, + <code><b>--accessor-regex</b></code>, + <code><b>--one-accessor-regex</b></code>, + <code><b>--opt-accessor-regex</b></code>, + <code><b>--seq-accessor-regex</b></code>, + <code><b>--modifier-regex</b></code>, + <code><b>--one-modifier-regex</b></code>, + <code><b>--opt-modifier-regex</b></code>, + <code><b>--seq-modifier-regex</b></code>, + <code><b>--parser-regex</b></code>, + <code><b>--serializer-regex</b></code>, + <code><b>--const-regex</b></code>, + <code><b>--enumerator-regex</b></code>, and + <code><b>--element-type-regex</b></code> options. + </p> + + <p>The <code><b>--type-naming</b></code> option specifies the + convention that should be used for naming C++ types. Possible + values for this option are <code><b>knr</b></code> (default), + <code><b>ucc</b></code>, and <code><b>java</b></code>. The + <code><b>knr</b></code> value (stands for K&R) signifies + the standard, lower-case naming convention with the underscore + used as a word delimiter, for example: <code>foo</code>, + <code>foo_bar</code>. The <code><b>ucc</b></code> (stands + for upper-camel-case) and + <code><b>java</b></code> values a synonyms for the same + naming convention where the first letter of each word in the + name is capitalized, for example: <code>Foo</code>, + <code>FooBar</code>.</p> + + <p>Similarly, the <code><b>--function-naming</b></code> option + specifies the convention that should be used for naming C++ + functions. Possible values for this option are <code><b>knr</b></code> + (default), <code><b>lcc</b></code>, <code><b>ucc</b></code>, and + <code><b>java</b></code>. The <code><b>knr</b></code> value (stands + for K&R) signifies the standard, lower-case naming convention + with the underscore used as a word delimiter, for example: + <code>foo()</code>, <code>foo_bar()</code>. The <code><b>lcc</b></code> + value (stands for lower-camel-case) signifies a naming convention + where the first letter of each word except the first is capitalized, + for example: <code>foo()</code>, <code>fooBar()</code>. The + <code><b>ucc</b></code> value (stands for upper-camel-case) signifies + a naming convention where the first letter of each word is capitalized, + for example: <code>Foo()</code>, <code>FooBar()</code>. + The <code><b>java</b></code> naming convention is similar to + the lower-camel-case one except that accessor functions are prefixed + with <code>get</code>, modifier functions are prefixed + with <code>set</code>, parsing functions are prefixed + with <code>parse</code>, and serialization functions are + prefixed with <code>serialize</code>, for example: + <code>getFoo()</code>, <code>setFooBar()</code>, + <code>parseRoot()</code>, <code>serializeRoot()</code>.</p> + + <p>Note that the naming conventions specified with the + <code><b>--type-naming</b></code> and + <code><b>--function-naming</b></code> options perform only limited + transformations on the names that come from the schema in the + form of type, attribute, and element names. In other words, to + get consistent results, your schemas should follow a similar + naming convention as the one you would like to have in the + generated code. Alternatively, you can use the + <code><b>--*-regex</b></code> options (discussed below) + to perform further transformations on the names that come from + the schema.</p> + + <p>The + <code><b>--type-regex</b></code>, + <code><b>--accessor-regex</b></code>, + <code><b>--one-accessor-regex</b></code>, + <code><b>--opt-accessor-regex</b></code>, + <code><b>--seq-accessor-regex</b></code>, + <code><b>--modifier-regex</b></code>, + <code><b>--one-modifier-regex</b></code>, + <code><b>--opt-modifier-regex</b></code>, + <code><b>--seq-modifier-regex</b></code>, + <code><b>--parser-regex</b></code>, + <code><b>--serializer-regex</b></code>, + <code><b>--const-regex</b></code>, + <code><b>--enumerator-regex</b></code>, and + <code><b>--element-type-regex</b></code> options allow you to + specify extra regular expressions for each name category in + addition to the predefined set that is added depending on + the <code><b>--type-naming</b></code> and + <code><b>--function-naming</b></code> options. Expressions + that are provided with the <code><b>--*-regex</b></code> + options are evaluated prior to any predefined expressions. + This allows you to selectively override some or all of the + predefined transformations. When debugging your own expressions, + it is often useful to see which expressions match which names. + The <code><b>--name-regex-trace</b></code> option allows you + to trace the process of applying regular expressions to + names.</p> + + <p>The value for the <code><b>--*-regex</b></code> options should be + a perl-like regular expression in the form + <code><b>/</b><i>pattern</i><b>/</b><i>replacement</i><b>/</b></code>. + Any character can be used as a delimiter instead of <code><b>/</b></code>. + Escaping of the delimiter character in <code><i>pattern</i></code> or + <code><i>replacement</i></code> is not supported. + All the regular expressions for each category are pushed into a + category-specific stack with the last specified expression + considered first. The first match that succeeds is used. For the + <code><b>--one-accessor-regex</b></code> (accessors with cardinality one), + <code><b>--opt-accessor-regex</b></code> (accessors with cardinality optional), and + <code><b>--seq-accessor-regex</b></code> (accessors with cardinality sequence) + categories the <code><b>--accessor-regex</b></code> expressions are + used as a fallback. For the + <code><b>--one-modifier-regex</b></code>, + <code><b>--opt-modifier-regex</b></code>, and + <code><b>--seq-modifier-regex</b></code> + categories the <code><b>--modifier-regex</b></code> expressions are + used as a fallback. For the <code><b>--element-type-regex</b></code> + category the <code><b>--type-regex</b></code> expressions are + used as a fallback.</p> + + <p>The type name expressions (<code><b>--type-regex</b></code>) + are evaluated on the name string that has the following + format:</p> + + <p><code>[<i>namespace</i> ]<i>name</i>[,<i>name</i>][,<i>name</i>][,<i>name</i>]</code></p> + + <p>The element type name expressions + (<code><b>--element-type-regex</b></code>), effective only when + the <code><b>--generate-element-type</b></code> option is specified, + are evaluated on the name string that has the following + format:</p> + + <p><code><i>namespace</i> <i>name</i></code></p> + + <p>In the type name format the <code><i>namespace</i></code> part + followed by a space is only present for global type names. For + global types and elements defined in schemas without a target + namespace, the <code><i>namespace</i></code> part is empty but + the space is still present. In the type name format after the + initial <code><i>name</i></code> component, up to three additional + <code><i>name</i></code> components can be present, separated + by commas. For example:</p> + + <p><code><b>http://example.com/hello type</b></code></p> + <p><code><b>foo</b></code></p> + <p><code><b>foo,iterator</b></code></p> + <p><code><b>foo,const,iterator</b></code></p> + + <p>The following set of predefined regular expressions is used to + transform type names when the upper-camel-case naming convention + is selected:</p> + + <p><code><b>/(?:[^ ]* )?([^,]+)/\u$1/</b></code></p> + <p><code><b>/(?:[^ ]* )?([^,]+),([^,]+)/\u$1\u$2/</b></code></p> + <p><code><b>/(?:[^ ]* )?([^,]+),([^,]+),([^,]+)/\u$1\u$2\u$3/</b></code></p> + <p><code><b>/(?:[^ ]* )?([^,]+),([^,]+),([^,]+),([^,]+)/\u$1\u$2\u$3\u$4/</b></code></p> + + <p>The accessor and modifier expressions + (<code><b>--*accessor-regex</b></code> and + <code><b>--*modifier-regex</b></code>) are evaluated on the name string + that has the following format:</p> + + <p><code><i>name</i>[,<i>name</i>][,<i>name</i>]</code></p> + + <p>After the initial <code><i>name</i></code> component, up to two + additional <code><i>name</i></code> components can be present, + separated by commas. For example:</p> + + <p><code><b>foo</b></code></p> + <p><code><b>dom,document</b></code></p> + <p><code><b>foo,default,value</b></code></p> + + <p>The following set of predefined regular expressions is used to + transform accessor names when the <code><b>java</b></code> naming + convention is selected:</p> + + <p><code><b>/([^,]+)/get\u$1/</b></code></p> + <p><code><b>/([^,]+),([^,]+)/get\u$1\u$2/</b></code></p> + <p><code><b>/([^,]+),([^,]+),([^,]+)/get\u$1\u$2\u$3/</b></code></p> + + <p>For the parser, serializer, and enumerator categories, the + corresponding regular expressions are evaluated on local names of + elements and on enumeration values, respectively. For example, the + following predefined regular expression is used to transform parsing + function names when the <code><b>java</b></code> naming convention + is selected:</p> + + <p><code><b>/(.+)/parse\u$1/</b></code></p> + + <p>The const category is used to create C++ constant names for the + element/wildcard/text content ids in ordered types.</p> + + <p>See also the REGEX AND SHELL QUOTING section below.</p> + + <h1>TYPE MAP</h1> + + <p>Type map files are used in C++/Parser to define a mapping between + XML Schema and C++ types. The compiler uses this information + to determine the return types of <code><b>post_*</b></code> + functions in parser skeletons corresponding to XML Schema + types as well as argument types for callbacks corresponding + to elements and attributes of these types.</p> + + <p>The compiler has a set of predefined mapping rules that map + built-in XML Schema types to suitable C++ types (discussed + below) and all other types to <code><b>void</b></code>. + By providing your own type maps you can override these predefined + rules. The format of the type map file is presented below: + </p> + + <pre> +namespace <schema-namespace> [<cxx-namespace>] +{ + (include <file-name>;)* + ([type] <schema-type> <cxx-ret-type> [<cxx-arg-type>];)* +} + </pre> + + <p>Both <code><i><schema-namespace></i></code> and + <code><i><schema-type></i></code> are regex patterns while + <code><i><cxx-namespace></i></code>, + <code><i><cxx-ret-type></i></code>, and + <code><i><cxx-arg-type></i></code> are regex pattern + substitutions. All names can be optionally enclosed in + <code><b>" "</b></code>, for example, to include white-spaces.</p> + + <p><code><i><schema-namespace></i></code> determines XML + Schema namespace. Optional <code><i><cxx-namespace></i></code> + is prefixed to every C++ type name in this namespace declaration. + <code><i><cxx-ret-type></i></code> is a C++ type name that is + used as a return type for the <code><b>post_*</b></code> functions. + Optional <code><i><cxx-arg-type></i></code> is an argument + type for callback functions corresponding to elements and attributes + of this type. If + <code><i><cxx-arg-type></i></code> is not specified, it defaults + to <code><i><cxx-ret-type></i></code> if <code><i><cxx-ret-type></i></code> + ends with <code><b>*</b></code> or <code><b>&</b></code> (that is, + it is a pointer or a reference) and + <code><b>const</b> <i><cxx-ret-type></i><b>&</b></code> + otherwise. + <code><i><file-name></i></code> is a file name either in the + <code><b>" "</b></code> or <code><b>< ></b></code> format + and is added with the <code><b>#include</b></code> directive to + the generated code.</p> + + <p>The <code><b>#</b></code> character starts a comment that ends + with a new line or end of file. To specify a name that contains + <code><b>#</b></code> enclose it in <code><b>" "</b></code>. + For example:</p> + + <pre> +namespace http://www.example.com/xmlns/my my +{ + include "my.hxx"; + + # Pass apples by value. + # + apple apple; + + # Pass oranges as pointers. + # + orange orange_t*; +} + </pre> + + <p>In the example above, for the + <code><b>http://www.example.com/xmlns/my#orange</b></code> + XML Schema type, the <code><b>my::orange_t*</b></code> C++ type will + be used as both return and argument types.</p> + + <p>Several namespace declarations can be specified in a single + file. The namespace declaration can also be completely + omitted to map types in a schema without a namespace. For + instance:</p> + + <pre> +include "my.hxx"; +apple apple; + +namespace http://www.example.com/xmlns/my +{ + orange "const orange_t*"; +} + </pre> + + <p>The compiler has a number of predefined mapping rules that can be + presented as the following map files. The string-based XML Schema + built-in types are mapped to either <code><b>std::string</b></code> + or <code><b>std::wstring</b></code> depending on the character type + selected with the <code><b>--char-type</b></code> option + (<code><b>char</b></code> by default). The binary XML Schema types are + mapped to either <code>std::unique_ptr<xml_schema::buffer></code> + or <code>std::auto_ptr<xml_schema::buffer></code> depending on the C++ + standard selected with the <code><b>--std</b></code> option + (<code><b>c++11</b></code> by default).</p> + + <pre> +namespace http://www.w3.org/2001/XMLSchema +{ + boolean bool bool; + + byte "signed char" "signed char"; + unsignedByte "unsigned char" "unsigned char"; + + short short short; + unsignedShort "unsigned short" "unsigned short"; + + int int int; + unsignedInt "unsigned int" "unsigned int"; + + long "long long" "long long"; + unsignedLong "unsigned long long" "unsigned long long"; + + integer "long long" "long long"; + + negativeInteger "long long" "long long"; + nonPositiveInteger "long long" "long long"; + + positiveInteger "unsigned long long" "unsigned long long"; + nonNegativeInteger "unsigned long long" "unsigned long long"; + + float float float; + double double double; + decimal double double; + + string std::string; + normalizedString std::string; + token std::string; + Name std::string; + NMTOKEN std::string; + NCName std::string; + ID std::string; + IDREF std::string; + language std::string; + anyURI std::string; + + NMTOKENS xml_schema::string_sequence; + IDREFS xml_schema::string_sequence; + + QName xml_schema::qname; + + base64Binary std::[unique|auto]_ptr<xml_schema::buffer> + std::[unique|auto]_ptr<xml_schema::buffer>; + hexBinary std::[unique|auto]_ptr<xml_schema::buffer> + std::[unique|auto]_ptr<xml_schema::buffer>; + + date xml_schema::date; + dateTime xml_schema::date_time; + duration xml_schema::duration; + gDay xml_schema::gday; + gMonth xml_schema::gmonth; + gMonthDay xml_schema::gmonth_day; + gYear xml_schema::gyear; + gYearMonth xml_schema::gyear_month; + time xml_schema::time; +} + </pre> + + <p>The last predefined rule maps anything that wasn't mapped by + previous rules to <code><b>void</b></code>:</p> + + <pre> +namespace .* +{ + .* void void; +} + </pre> + + + <p>When you provide your own type maps with the + <code><b>--type-map</b></code> option, they are evaluated first. + This allows you to selectively override predefined rules.</p> + + <h1>REGEX AND SHELL QUOTING</h1> + + <p>When entering a regular expression argument in the shell + command line it is often necessary to use quoting (enclosing + the argument in <code><b>" "</b></code> or + <code><b>' '</b></code>) in order to prevent the shell + from interpreting certain characters, for example, spaces as + argument separators and <code><b>$</b></code> as variable + expansions.</p> + + <p>Unfortunately it is hard to achieve this in a manner that is + portable across POSIX shells, such as those found on + GNU/Linux and UNIX, and Windows shell. For example, if you + use <code><b>" "</b></code> for quoting you will get a + wrong result with POSIX shells if your expression contains + <code><b>$</b></code>. The standard way of dealing with this + on POSIX systems is to use <code><b>' '</b></code> instead. + Unfortunately, Windows shell does not remove <code><b>' '</b></code> + from arguments when they are passed to applications. As a result you + may have to use <code><b>' '</b></code> for POSIX and + <code><b>" "</b></code> for Windows (<code><b>$</b></code> is + not treated as a special character on Windows).</p> + + <p>Alternatively, you can save regular expression options into + a file, one option per line, and use this file with the + <code><b>--options-file</b></code> option. With this approach + you don't need to worry about shell quoting.</p> + + <h1>DIAGNOSTICS</h1> + + <p>If the input file is not a valid W3C XML Schema definition, + <code><b>xsd</b></code> will issue diagnostic messages to STDERR + and exit with non-zero exit code.</p> + + <h1>BUGS</h1> + + <p>Send bug reports to the + <a href="mailto:xsd-users@codesynthesis.com">xsd-users@codesynthesis.com</a> mailing list.</p> + + </div> + <div id="footer"> + Copyright © 2005-2023 Code Synthesis. + + <div id="terms"> + Permission is granted to copy, distribute and/or modify this + document under the terms of the + <a href="https://www.codesynthesis.com/licenses/fdl-1.2.txt">GNU Free + Documentation License, version 1.2</a>; with no Invariant Sections, + no Front-Cover Texts and no Back-Cover Texts. + </div> + </div> +</div> +</body> +</html> diff --git a/xsd/doc/xsd-epilogue.1 b/xsd/doc/xsd-epilogue.1 new file mode 100644 index 0000000..9ab1952 --- /dev/null +++ b/xsd/doc/xsd-epilogue.1 @@ -0,0 +1,576 @@ +\" +\" NAMING CONVENTION +\" + +.SH NAMING CONVENTION +The compiler can be instructed to use a particular naming convention in +the generated code. A number of widely-used conventions can be selected +using the +.B --type-naming +and +.B --function-naming +options. A custom naming convention can be achieved using the +.BR --type-regex , +.BR --accessor-regex , +.BR --one-accessor-regex , +.BR --opt-accessor-regex , +.BR --seq-accessor-regex , +.BR --modifier-regex , +.BR --one-modifier-regex , +.BR --opt-modifier-regex , +.BR --seq-modifier-regex , +.BR --parser-regex , +.BR --serializer-regex , +.BR --const-regex , +.BR --enumerator-regex , +and +.B --element-type-regex +options. + +The +.B --type-naming +option specifies the convention that should be used for naming C++ types. +Possible values for this option are +.B knr +(default), +.BR ucc , +and +.BR java . +The +.B knr +value (stands for K&R) signifies the standard, lower-case naming convention +with the underscore used as a word delimiter, for example: foo, foo_bar. +The +.B ucc +(stands for upper-camel-case) and +.B java +values a synonyms for the same naming convention where the first letter +of each word in the name is capitalized, for example: Foo, FooBar. + +Similarly, the +.B --function-naming +option specifies the convention that should be used for naming C++ functions. +Possible values for this option are +.B knr +(default), +.BR lcc , +and +.BR java . +The +.B knr +value (stands for K&R) signifies the standard, lower-case naming convention +with the underscore used as a word delimiter, for example: foo(), foo_bar(). +The +.B lcc +value (stands for lower-camel-case) signifies a naming convention where the +first letter of each word except the first is capitalized, for example: foo(), +fooBar(). The +.B ucc +value (stands for upper-camel-case) signifies a naming convention where the +first letter of each word is capitalized, for example: Foo(), FooBar(). The +.B java +naming convention is similar to the lower-camel-case one except that accessor +functions are prefixed with get, modifier functions are prefixed with set, +parsing functions are prefixed with parse, and serialization functions are +prefixed with serialize, for example: getFoo(), setFooBar(), parseRoot(), +serializeRoot(). + +Note that the naming conventions specified with the +.B --type-naming +and +.B --function-naming +options perform only limited transformations on the +names that come from the schema in the form of type, attribute, and element +names. In other words, to get consistent results, your schemas should follow +a similar naming convention as the one you would like to have in the generated +code. Alternatively, you can use the +.B --*-regex +options (discussed below) to perform further transformations on the names +that come from the schema. + +The +.BR --type-regex , +.BR --accessor-regex , +.BR --one-accessor-regex , +.BR --opt-accessor-regex , +.BR --seq-accessor-regex , +.BR --modifier-regex , +.BR --one-modifier-regex , +.BR --opt-modifier-regex , +.BR --seq-modifier-regex , +.BR --parser-regex , +.BR --serializer-regex , +.BR --const-regex , +.BR --enumerator-regex , +and +.B --element-type-regex +options allow you to specify extra regular expressions for each name +category in addition to the predefined set that is added depending on +the +.B --type-naming +and +.B --function-naming +options. Expressions that are provided with the +.B --*-regex +options are evaluated prior to any predefined expressions. This allows +you to selectively override some or all of the predefined transformations. +When debugging your own expressions, it is often useful to see which +expressions match which names. The +.B --name-regex-trace +option allows you to trace the process of applying +regular expressions to names. + +The value for the +.B --*-regex +options should be a perl-like regular expression in the form +.BI / pattern / replacement /\fR. +Any character can be used as a delimiter instead of +.BR / . +Escaping of the delimiter character in +.I pattern +or +.I replacement +is not supported. All the regular expressions for each category are pushed +into a category-specific stack with the last specified expression +considered first. The first match that succeeds is used. For the +.B --one-accessor-regex +(accessors with cardinality one), +.B --opt-accessor-regex +(accessors with cardinality optional), and +.B --seq-accessor-regex +(accessors with cardinality sequence) categories the +.B --accessor-regex +expressions are used as a fallback. For the +.BR --one-modifier-regex , +.BR --opt-modifier-regex , +and +.B --seq-modifier-regex +categories the +.B --modifier-regex +expressions are used as a fallback. For the +.B --element-type-regex +category the +.B --type-regex +expressions are used as a fallback. + +The type name expressions +.RB ( --type-regex ) +are evaluated on the name string that has the following format: + +[\fInamespace \fR]\fIname\fR[\fB,\fIname\fR][\fB,\fIname\fR][\fB,\fIname\fR] + +The element type name expressions +.RB ( --element-type-regex ), +effective only when the +.B --generate-element-type +option is specified, are evaluated on the name string that has the following +format: + +.I namespace name + +In the type name format the +.I namespace +part followed by a space is only present for global type names. For global +types and elements defined in schemas without a target namespace, the +.I namespace +part is empty but the space is still present. In the type name format after +the initial +.I name +component, up to three additional +.I name +components can be present, separated by commas. For example: + +.B http://example.com/hello type + +.B foo + +.B foo,iterator + +.B foo,const,iterator + +The following set of predefined regular expressions is used to transform +type names when the upper-camel-case naming convention is selected: + +.B /(?:[^ ]* )?([^,]+)/\\\\u$1/ + +.B /(?:[^ ]* )?([^,]+),([^,]+)/\\\\u$1\\\\u$2/ + +.B /(?:[^ ]* )?([^,]+),([^,]+),([^,]+)/\\\\u$1\\\\u$2\\\\u$3/ + +.B /(?:[^ ]* )?([^,]+),([^,]+),([^,]+),([^,]+)/\\\\u$1\\\\u$2\\\\u$3\\\\u$4/ + +The accessor and modifier expressions +.RB ( --*accessor-regex +and +.BR --*modifier-regex ) +are evaluated on the name string that has the following format: + +\fIname\fR[\fB,\fIname\fR][\fB,\fIname\fR] + +After the initial +.I name +component, up to two additional +.I name +components can be present, separated by commas. For example: + +.B foo + +.B dom,document + +.B foo,default,value + +The following set of predefined regular expressions is used to transform +accessor names when the +.B java +naming convention is selected: + +.B /([^,]+)/get\\\\u$1/ + +.B /([^,]+),([^,]+)/get\\\\u$1\\\\u$2/ + +.B /([^,]+),([^,]+),([^,]+)/get\\\\u$1\\\\u$2\\\\u$3/ + +For the parser, serializer, and enumerator categories, the corresponding +regular expressions are evaluated on local names of elements and on +enumeration values, respectively. For example, the following predefined +regular expression is used to transform parsing function names when the +.B java +naming convention is selected: + +.B /(.+)/parse\\\\u$1/ + +The const category is used to create C++ constant names for the +element/wildcard/text content ids in ordered types. + +See also the REGEX AND SHELL QUOTING section below. + +\" +\" TYPE MAP +\" +.SH TYPE MAP +Type map files are used in C++/Parser to define a mapping between XML +Schema and C++ types. The compiler uses this information to determine +the return types of +.B post_* +functions in parser skeletons corresponding to XML Schema types +as well as argument types for callbacks corresponding to elements +and attributes of these types. + +The compiler has a set of predefined mapping rules that map built-in +XML Schema types to suitable C++ types (discussed below) and all +other types to +.BR void . +By providing your own type maps you can override these predefined rules. +The format of the type map file is presented below: + +.RS +.B namespace +.I schema-namespace +[ +.I cxx-namespace +] +.br +.B { +.br + ( +.B include +.IB file-name ; +)* +.br + ([ +.B type +] +.I schema-type cxx-ret-type +[ +.I cxx-arg-type +.RB ] ; +)* +.br +.B } +.br +.RE + +Both +.I schema-namespace +and +.I schema-type +are regex patterns while +.IR cxx-namespace , +.IR cxx-ret-type , +and +.I cxx-arg-type +are regex pattern substitutions. All names can be optionally enclosed +in \fR" "\fR, for example, to include white-spaces. + +.I schema-namespace +determines XML Schema namespace. Optional +.I cxx-namespace +is prefixed to every C++ type name in this namespace declaration. +.I cxx-ret-type +is a C++ type name that is used as a return type for the +.B post_* +functions. Optional +.I cxx-arg-type +is an argument type for callback functions corresponding to elements and +attributes of this type. If +.I cxx-arg-type +is not specified, it defaults to +.I cxx-ret-type +if +.I cxx-ret-type +ends with +.B * +or +.B & +(that is, it is a pointer or a reference) and +.B const +\fIcxx-ret-type\fB&\fR otherwise. +.I file-name +is a file name either in the \fR" "\fR or < > format and is added with the +.B #include +directive to the generated code. + +The \fB#\fR character starts a comment that ends with a new line or end of +file. To specify a name that contains \fB#\fR enclose it in \fR" "\fR. For +example: + +.RS +namespace http://www.example.com/xmlns/my my +.br +{ +.br + include "my.hxx"; +.br + + # Pass apples by value. + # + apple apple; +.br + + # Pass oranges as pointers. + # + orange orange_t*; +.br +} +.br +.RE + +In the example above, for the +.B http://www.example.com/xmlns/my#orange +XML Schema type, the +.B my::orange_t* +C++ type will be used as both return and argument types. + +Several namespace declarations can be specified in a single file. +The namespace declaration can also be completely omitted to map +types in a schema without a namespace. For instance: + +.RS +include "my.hxx"; +.br +apple apple; +.br + +namespace http://www.example.com/xmlns/my +.br +{ +.br + orange "const orange_t*"; +.br +} +.br +.RE + +The compiler has a number of predefined mapping rules that can be +presented as the following map files. The string-based XML Schema +built-in types are mapped to either +.B std::string +or +.B std::wstring +depending on the character type selected with the +.B --char-type +option +.RB ( char +by default). The binary XML Schema types are mapped to either +.B std::unique_ptr<xml_schema::buffer> +or +.B std::auto_ptr<xml_schema::buffer> +depending on the C++ standard selected with the +.B --std +option +.RB ( c++11 +by default). + +.RS +namespace http://www.w3.org/2001/XMLSchema +.br +{ +.br + boolean bool bool; +.br + + byte "signed char" "signed char"; +.br + unsignedByte "unsigned char" "unsigned char"; +.br + + short short short; +.br + unsignedShort "unsigned short" "unsigned short"; +.br + + int int int; +.br + unsignedInt "unsigned int" "unsigned int"; +.br + + long "long long" "long long"; +.br + unsignedLong "unsigned long long" "unsigned long long"; +.br + + integer "long long" "long long"; +.br + + negativeInteger "long long" "long long"; +.br + nonPositiveInteger "long long" "long long"; +.br + + positiveInteger "unsigned long long" "unsigned long long"; +.br + nonNegativeInteger "unsigned long long" "unsigned long long"; +.br + + float float float; +.br + double double double; +.br + decimal double double; +.br + + string std::string; +.br + normalizedString std::string; +.br + token std::string; +.br + Name std::string; +.br + NMTOKEN std::string; +.br + NCName std::string; +.br + ID std::string; +.br + IDREF std::string; +.br + language std::string; +.br + anyURI std::string; +.br + + NMTOKENS xml_schema::string_sequence; +.br + IDREFS xml_schema::string_sequence; +.br + + QName xml_schema::qname; +.br + + base64Binary std::[unique|auto]_ptr<xml_schema::buffer> +.br + std::[unique|auto]_ptr<xml_schema::buffer>; +.br + hexBinary std::[unique|auto]_ptr<xml_schema::buffer> +.br + std::[unique|auto]_ptr<xml_schema::buffer>; +.br + + date xml_schema::date; +.br + dateTime xml_schema::date_time; +.br + duration xml_schema::duration; +.br + gDay xml_schema::gday; +.br + gMonth xml_schema::gmonth; +.br + gMonthDay xml_schema::gmonth_day; +.br + gYear xml_schema::gyear; +.br + gYearMonth xml_schema::gyear_month; +.br + time xml_schema::time; +.br +} +.br +.RE + + +The last predefined rule maps anything that wasn't mapped by previous +rules to +.BR void : + +.RS +namespace .* +.br +{ +.br + .* void void; +.br +} +.br +.RE + +When you provide your own type maps with the +.B --type-map +option, they are evaluated first. This allows you to selectively override +predefined rules. + +.\" +.\" REGEX AND SHELL QUOTING +.\" +.SH REGEX AND SHELL QUOTING +When entering a regular expression argument in the shell command line +it is often necessary to use quoting (enclosing the argument in " " +or ' ') in order to prevent the shell from interpreting certain +characters, for example, spaces as argument separators and $ as +variable expansions. + +Unfortunately it is hard to achieve this in a manner that is portable +across POSIX shells, such as those found on GNU/Linux and UNIX, and +Windows shell. For example, if you use " " for quoting you will get +a wrong result with POSIX shells if your expression contains $. The +standard way of dealing with this on POSIX systems is to use ' ' +instead. Unfortunately, Windows shell does not remove ' ' from +arguments when they are passed to applications. As a result you may +have to use ' ' for POSIX and " " for Windows ($ is not treated as +a special character on Windows). + +Alternatively, you can save regular expression options into a file, +one option per line, and use this file with the +.B --options-file +option. With this approach you don't need to worry about shell quoting. + +.\" +.\" DIAGNOSTICS +.\" +.SH DIAGNOSTICS +If the input file is not a valid W3C XML Schema definition, +.B xsd +will issue diagnostic messages to +.B STDERR +and exit with non-zero exit code. +.SH BUGS +Send bug reports to the xsd-users@codesynthesis.com mailing list. +.SH COPYRIGHT +Copyright (c) $copyright$. + +Permission is granted to copy, distribute and/or modify this +document under the terms of the GNU Free Documentation License, +version 1.2; with no Invariant Sections, no Front-Cover Texts and +no Back-Cover Texts. Copy of the license can be obtained from +https://www.codesynthesis.com/licenses/fdl-1.2.txt diff --git a/xsd/doc/xsd-epilogue.xhtml b/xsd/doc/xsd-epilogue.xhtml new file mode 100644 index 0000000..178cf8b --- /dev/null +++ b/xsd/doc/xsd-epilogue.xhtml @@ -0,0 +1,429 @@ + <h1>NAMING CONVENTION</h1> + + <p>The compiler can be instructed to use a particular naming + convention in the generated code. A number of widely-used + conventions can be selected using the <code><b>--type-naming</b></code> + and <code><b>--function-naming</b></code> options. A custom + naming convention can be achieved using the + <code><b>--type-regex</b></code>, + <code><b>--accessor-regex</b></code>, + <code><b>--one-accessor-regex</b></code>, + <code><b>--opt-accessor-regex</b></code>, + <code><b>--seq-accessor-regex</b></code>, + <code><b>--modifier-regex</b></code>, + <code><b>--one-modifier-regex</b></code>, + <code><b>--opt-modifier-regex</b></code>, + <code><b>--seq-modifier-regex</b></code>, + <code><b>--parser-regex</b></code>, + <code><b>--serializer-regex</b></code>, + <code><b>--const-regex</b></code>, + <code><b>--enumerator-regex</b></code>, and + <code><b>--element-type-regex</b></code> options. + </p> + + <p>The <code><b>--type-naming</b></code> option specifies the + convention that should be used for naming C++ types. Possible + values for this option are <code><b>knr</b></code> (default), + <code><b>ucc</b></code>, and <code><b>java</b></code>. The + <code><b>knr</b></code> value (stands for K&R) signifies + the standard, lower-case naming convention with the underscore + used as a word delimiter, for example: <code>foo</code>, + <code>foo_bar</code>. The <code><b>ucc</b></code> (stands + for upper-camel-case) and + <code><b>java</b></code> values a synonyms for the same + naming convention where the first letter of each word in the + name is capitalized, for example: <code>Foo</code>, + <code>FooBar</code>.</p> + + <p>Similarly, the <code><b>--function-naming</b></code> option + specifies the convention that should be used for naming C++ + functions. Possible values for this option are <code><b>knr</b></code> + (default), <code><b>lcc</b></code>, <code><b>ucc</b></code>, and + <code><b>java</b></code>. The <code><b>knr</b></code> value (stands + for K&R) signifies the standard, lower-case naming convention + with the underscore used as a word delimiter, for example: + <code>foo()</code>, <code>foo_bar()</code>. The <code><b>lcc</b></code> + value (stands for lower-camel-case) signifies a naming convention + where the first letter of each word except the first is capitalized, + for example: <code>foo()</code>, <code>fooBar()</code>. The + <code><b>ucc</b></code> value (stands for upper-camel-case) signifies + a naming convention where the first letter of each word is capitalized, + for example: <code>Foo()</code>, <code>FooBar()</code>. + The <code><b>java</b></code> naming convention is similar to + the lower-camel-case one except that accessor functions are prefixed + with <code>get</code>, modifier functions are prefixed + with <code>set</code>, parsing functions are prefixed + with <code>parse</code>, and serialization functions are + prefixed with <code>serialize</code>, for example: + <code>getFoo()</code>, <code>setFooBar()</code>, + <code>parseRoot()</code>, <code>serializeRoot()</code>.</p> + + <p>Note that the naming conventions specified with the + <code><b>--type-naming</b></code> and + <code><b>--function-naming</b></code> options perform only limited + transformations on the names that come from the schema in the + form of type, attribute, and element names. In other words, to + get consistent results, your schemas should follow a similar + naming convention as the one you would like to have in the + generated code. Alternatively, you can use the + <code><b>--*-regex</b></code> options (discussed below) + to perform further transformations on the names that come from + the schema.</p> + + <p>The + <code><b>--type-regex</b></code>, + <code><b>--accessor-regex</b></code>, + <code><b>--one-accessor-regex</b></code>, + <code><b>--opt-accessor-regex</b></code>, + <code><b>--seq-accessor-regex</b></code>, + <code><b>--modifier-regex</b></code>, + <code><b>--one-modifier-regex</b></code>, + <code><b>--opt-modifier-regex</b></code>, + <code><b>--seq-modifier-regex</b></code>, + <code><b>--parser-regex</b></code>, + <code><b>--serializer-regex</b></code>, + <code><b>--const-regex</b></code>, + <code><b>--enumerator-regex</b></code>, and + <code><b>--element-type-regex</b></code> options allow you to + specify extra regular expressions for each name category in + addition to the predefined set that is added depending on + the <code><b>--type-naming</b></code> and + <code><b>--function-naming</b></code> options. Expressions + that are provided with the <code><b>--*-regex</b></code> + options are evaluated prior to any predefined expressions. + This allows you to selectively override some or all of the + predefined transformations. When debugging your own expressions, + it is often useful to see which expressions match which names. + The <code><b>--name-regex-trace</b></code> option allows you + to trace the process of applying regular expressions to + names.</p> + + <p>The value for the <code><b>--*-regex</b></code> options should be + a perl-like regular expression in the form + <code><b>/</b><i>pattern</i><b>/</b><i>replacement</i><b>/</b></code>. + Any character can be used as a delimiter instead of <code><b>/</b></code>. + Escaping of the delimiter character in <code><i>pattern</i></code> or + <code><i>replacement</i></code> is not supported. + All the regular expressions for each category are pushed into a + category-specific stack with the last specified expression + considered first. The first match that succeeds is used. For the + <code><b>--one-accessor-regex</b></code> (accessors with cardinality one), + <code><b>--opt-accessor-regex</b></code> (accessors with cardinality optional), and + <code><b>--seq-accessor-regex</b></code> (accessors with cardinality sequence) + categories the <code><b>--accessor-regex</b></code> expressions are + used as a fallback. For the + <code><b>--one-modifier-regex</b></code>, + <code><b>--opt-modifier-regex</b></code>, and + <code><b>--seq-modifier-regex</b></code> + categories the <code><b>--modifier-regex</b></code> expressions are + used as a fallback. For the <code><b>--element-type-regex</b></code> + category the <code><b>--type-regex</b></code> expressions are + used as a fallback.</p> + + <p>The type name expressions (<code><b>--type-regex</b></code>) + are evaluated on the name string that has the following + format:</p> + + <p><code>[<i>namespace</i> ]<i>name</i>[,<i>name</i>][,<i>name</i>][,<i>name</i>]</code></p> + + <p>The element type name expressions + (<code><b>--element-type-regex</b></code>), effective only when + the <code><b>--generate-element-type</b></code> option is specified, + are evaluated on the name string that has the following + format:</p> + + <p><code><i>namespace</i> <i>name</i></code></p> + + <p>In the type name format the <code><i>namespace</i></code> part + followed by a space is only present for global type names. For + global types and elements defined in schemas without a target + namespace, the <code><i>namespace</i></code> part is empty but + the space is still present. In the type name format after the + initial <code><i>name</i></code> component, up to three additional + <code><i>name</i></code> components can be present, separated + by commas. For example:</p> + + <p><code><b>http://example.com/hello type</b></code></p> + <p><code><b>foo</b></code></p> + <p><code><b>foo,iterator</b></code></p> + <p><code><b>foo,const,iterator</b></code></p> + + <p>The following set of predefined regular expressions is used to + transform type names when the upper-camel-case naming convention + is selected:</p> + + <p><code><b>/(?:[^ ]* )?([^,]+)/\u$1/</b></code></p> + <p><code><b>/(?:[^ ]* )?([^,]+),([^,]+)/\u$1\u$2/</b></code></p> + <p><code><b>/(?:[^ ]* )?([^,]+),([^,]+),([^,]+)/\u$1\u$2\u$3/</b></code></p> + <p><code><b>/(?:[^ ]* )?([^,]+),([^,]+),([^,]+),([^,]+)/\u$1\u$2\u$3\u$4/</b></code></p> + + <p>The accessor and modifier expressions + (<code><b>--*accessor-regex</b></code> and + <code><b>--*modifier-regex</b></code>) are evaluated on the name string + that has the following format:</p> + + <p><code><i>name</i>[,<i>name</i>][,<i>name</i>]</code></p> + + <p>After the initial <code><i>name</i></code> component, up to two + additional <code><i>name</i></code> components can be present, + separated by commas. For example:</p> + + <p><code><b>foo</b></code></p> + <p><code><b>dom,document</b></code></p> + <p><code><b>foo,default,value</b></code></p> + + <p>The following set of predefined regular expressions is used to + transform accessor names when the <code><b>java</b></code> naming + convention is selected:</p> + + <p><code><b>/([^,]+)/get\u$1/</b></code></p> + <p><code><b>/([^,]+),([^,]+)/get\u$1\u$2/</b></code></p> + <p><code><b>/([^,]+),([^,]+),([^,]+)/get\u$1\u$2\u$3/</b></code></p> + + <p>For the parser, serializer, and enumerator categories, the + corresponding regular expressions are evaluated on local names of + elements and on enumeration values, respectively. For example, the + following predefined regular expression is used to transform parsing + function names when the <code><b>java</b></code> naming convention + is selected:</p> + + <p><code><b>/(.+)/parse\u$1/</b></code></p> + + <p>The const category is used to create C++ constant names for the + element/wildcard/text content ids in ordered types.</p> + + <p>See also the REGEX AND SHELL QUOTING section below.</p> + + <h1>TYPE MAP</h1> + + <p>Type map files are used in C++/Parser to define a mapping between + XML Schema and C++ types. The compiler uses this information + to determine the return types of <code><b>post_*</b></code> + functions in parser skeletons corresponding to XML Schema + types as well as argument types for callbacks corresponding + to elements and attributes of these types.</p> + + <p>The compiler has a set of predefined mapping rules that map + built-in XML Schema types to suitable C++ types (discussed + below) and all other types to <code><b>void</b></code>. + By providing your own type maps you can override these predefined + rules. The format of the type map file is presented below: + </p> + + <pre> +namespace <schema-namespace> [<cxx-namespace>] +{ + (include <file-name>;)* + ([type] <schema-type> <cxx-ret-type> [<cxx-arg-type>];)* +} + </pre> + + <p>Both <code><i><schema-namespace></i></code> and + <code><i><schema-type></i></code> are regex patterns while + <code><i><cxx-namespace></i></code>, + <code><i><cxx-ret-type></i></code>, and + <code><i><cxx-arg-type></i></code> are regex pattern + substitutions. All names can be optionally enclosed in + <code><b>" "</b></code>, for example, to include white-spaces.</p> + + <p><code><i><schema-namespace></i></code> determines XML + Schema namespace. Optional <code><i><cxx-namespace></i></code> + is prefixed to every C++ type name in this namespace declaration. + <code><i><cxx-ret-type></i></code> is a C++ type name that is + used as a return type for the <code><b>post_*</b></code> functions. + Optional <code><i><cxx-arg-type></i></code> is an argument + type for callback functions corresponding to elements and attributes + of this type. If + <code><i><cxx-arg-type></i></code> is not specified, it defaults + to <code><i><cxx-ret-type></i></code> if <code><i><cxx-ret-type></i></code> + ends with <code><b>*</b></code> or <code><b>&</b></code> (that is, + it is a pointer or a reference) and + <code><b>const</b> <i><cxx-ret-type></i><b>&</b></code> + otherwise. + <code><i><file-name></i></code> is a file name either in the + <code><b>" "</b></code> or <code><b>< ></b></code> format + and is added with the <code><b>#include</b></code> directive to + the generated code.</p> + + <p>The <code><b>#</b></code> character starts a comment that ends + with a new line or end of file. To specify a name that contains + <code><b>#</b></code> enclose it in <code><b>" "</b></code>. + For example:</p> + + <pre> +namespace http://www.example.com/xmlns/my my +{ + include "my.hxx"; + + # Pass apples by value. + # + apple apple; + + # Pass oranges as pointers. + # + orange orange_t*; +} + </pre> + + <p>In the example above, for the + <code><b>http://www.example.com/xmlns/my#orange</b></code> + XML Schema type, the <code><b>my::orange_t*</b></code> C++ type will + be used as both return and argument types.</p> + + <p>Several namespace declarations can be specified in a single + file. The namespace declaration can also be completely + omitted to map types in a schema without a namespace. For + instance:</p> + + <pre> +include "my.hxx"; +apple apple; + +namespace http://www.example.com/xmlns/my +{ + orange "const orange_t*"; +} + </pre> + + <p>The compiler has a number of predefined mapping rules that can be + presented as the following map files. The string-based XML Schema + built-in types are mapped to either <code><b>std::string</b></code> + or <code><b>std::wstring</b></code> depending on the character type + selected with the <code><b>--char-type</b></code> option + (<code><b>char</b></code> by default). The binary XML Schema types are + mapped to either <code>std::unique_ptr<xml_schema::buffer></code> + or <code>std::auto_ptr<xml_schema::buffer></code> depending on the C++ + standard selected with the <code><b>--std</b></code> option + (<code><b>c++11</b></code> by default).</p> + + <pre> +namespace http://www.w3.org/2001/XMLSchema +{ + boolean bool bool; + + byte "signed char" "signed char"; + unsignedByte "unsigned char" "unsigned char"; + + short short short; + unsignedShort "unsigned short" "unsigned short"; + + int int int; + unsignedInt "unsigned int" "unsigned int"; + + long "long long" "long long"; + unsignedLong "unsigned long long" "unsigned long long"; + + integer "long long" "long long"; + + negativeInteger "long long" "long long"; + nonPositiveInteger "long long" "long long"; + + positiveInteger "unsigned long long" "unsigned long long"; + nonNegativeInteger "unsigned long long" "unsigned long long"; + + float float float; + double double double; + decimal double double; + + string std::string; + normalizedString std::string; + token std::string; + Name std::string; + NMTOKEN std::string; + NCName std::string; + ID std::string; + IDREF std::string; + language std::string; + anyURI std::string; + + NMTOKENS xml_schema::string_sequence; + IDREFS xml_schema::string_sequence; + + QName xml_schema::qname; + + base64Binary std::[unique|auto]_ptr<xml_schema::buffer> + std::[unique|auto]_ptr<xml_schema::buffer>; + hexBinary std::[unique|auto]_ptr<xml_schema::buffer> + std::[unique|auto]_ptr<xml_schema::buffer>; + + date xml_schema::date; + dateTime xml_schema::date_time; + duration xml_schema::duration; + gDay xml_schema::gday; + gMonth xml_schema::gmonth; + gMonthDay xml_schema::gmonth_day; + gYear xml_schema::gyear; + gYearMonth xml_schema::gyear_month; + time xml_schema::time; +} + </pre> + + <p>The last predefined rule maps anything that wasn't mapped by + previous rules to <code><b>void</b></code>:</p> + + <pre> +namespace .* +{ + .* void void; +} + </pre> + + + <p>When you provide your own type maps with the + <code><b>--type-map</b></code> option, they are evaluated first. + This allows you to selectively override predefined rules.</p> + + <h1>REGEX AND SHELL QUOTING</h1> + + <p>When entering a regular expression argument in the shell + command line it is often necessary to use quoting (enclosing + the argument in <code><b>" "</b></code> or + <code><b>' '</b></code>) in order to prevent the shell + from interpreting certain characters, for example, spaces as + argument separators and <code><b>$</b></code> as variable + expansions.</p> + + <p>Unfortunately it is hard to achieve this in a manner that is + portable across POSIX shells, such as those found on + GNU/Linux and UNIX, and Windows shell. For example, if you + use <code><b>" "</b></code> for quoting you will get a + wrong result with POSIX shells if your expression contains + <code><b>$</b></code>. The standard way of dealing with this + on POSIX systems is to use <code><b>' '</b></code> instead. + Unfortunately, Windows shell does not remove <code><b>' '</b></code> + from arguments when they are passed to applications. As a result you + may have to use <code><b>' '</b></code> for POSIX and + <code><b>" "</b></code> for Windows (<code><b>$</b></code> is + not treated as a special character on Windows).</p> + + <p>Alternatively, you can save regular expression options into + a file, one option per line, and use this file with the + <code><b>--options-file</b></code> option. With this approach + you don't need to worry about shell quoting.</p> + + <h1>DIAGNOSTICS</h1> + + <p>If the input file is not a valid W3C XML Schema definition, + <code><b>xsd</b></code> will issue diagnostic messages to STDERR + and exit with non-zero exit code.</p> + + <h1>BUGS</h1> + + <p>Send bug reports to the + <a href="mailto:xsd-users@codesynthesis.com">xsd-users@codesynthesis.com</a> mailing list.</p> + + </div> + <div id="footer"> + Copyright © $copyright$. + + <div id="terms"> + Permission is granted to copy, distribute and/or modify this + document under the terms of the + <a href="https://www.codesynthesis.com/licenses/fdl-1.2.txt">GNU Free + Documentation License, version 1.2</a>; with no Invariant Sections, + no Front-Cover Texts and no Back-Cover Texts. + </div> + </div> +</div> +</body> +</html> diff --git a/xsd/doc/xsd-parser-header.1 b/xsd/doc/xsd-parser-header.1 new file mode 100644 index 0000000..e0cf84e --- /dev/null +++ b/xsd/doc/xsd-parser-header.1 @@ -0,0 +1,4 @@ +\" +\" C++/Parser +\" +.SS cxx-parser command options diff --git a/xsd/doc/xsd-parser-header.xhtml b/xsd/doc/xsd-parser-header.xhtml new file mode 100644 index 0000000..94fa2c1 --- /dev/null +++ b/xsd/doc/xsd-parser-header.xhtml @@ -0,0 +1 @@ + <h2>CXX-PARSER COMMAND OPTIONS</h2> diff --git a/xsd/doc/xsd-prologue.1 b/xsd/doc/xsd-prologue.1 new file mode 100644 index 0000000..33f039e --- /dev/null +++ b/xsd/doc/xsd-prologue.1 @@ -0,0 +1,119 @@ +.\" Process this file with +.\" groff -man -Tascii xsd.1 +.\" +.TH XSD 1 "$date$" "$project$ $version$" +.SH NAME +xsd \- W3C XML Schema to C++ Compiler +.\" +.\" +.\" +.\"-------------------------------------------------------------------- +.SH SYNOPSIS +.\"-------------------------------------------------------------------- +.B xsd +.I command +.B [ +.I options +.B ] +.I file +.B [ +.I file +.B ...] +.in +.B xsd help +.B [ +.I command +.B ] +.in +.B xsd version +.\" +.\" +.\" +.\"-------------------------------------------------------------------- +.SH DESCRIPTION +.\"-------------------------------------------------------------------- +.B xsd +generates vocabulary-specific, statically-typed C++ mapping from W3C XML +Schema definitions. Particular mapping to produce is selected by a +.IR command . +Each mapping has a number of mapping-specific +.I options +that should appear, if any, after the +.IR command . +Input files should be W3C XML Schema definitions. The exact set of the +generated files depends on the selected mapping and options. +.\" +.\" +.\" +.\"-------------------------------------------------------------------- +.SH COMMANDS +.\"-------------------------------------------------------------------- +.IP \fBcxx-tree\fR +Generate the C++/Tree mapping. For each input file in the form +.B name.xsd +the following C++ files are generated: +.B name.hxx +(header file), +.B name.ixx +(inline file, generated only if the +.B --generate-inline +option is specified), +.B name.cxx +(source file), and +.B name-fwd.hxx +(forward declaration file, generated only if the +.B --generate-forward +option is specified). + +.IP \fBcxx-parser\fR +Generate the C++/Parser mapping. For each input file in the form +.B name.xsd +the following C++ files are generated: +.B name-pskel.hxx +(parser skeleton header file), +.B name-pskel.ixx +(parser skeleton inline file, generated only if the +.B --generate-inline +option is specified), and +.B name-pskel.cxx +(parser skeleton source file). If the +.B --generate-noop-impl +or +.B --generate-print-impl +option is specified, the following additional sample implementation files +are generated: +.B name-pimpl.hxx +(parser implementation header file) and +.B name-pimpl.cxx +(parser implementation source file). If the +.B --generate-test-driver +option is specified, the additional +.B name-driver.cxx +test driver file is generated. + +.IP \fBhelp\fR +Print usage information and exit. Use +.PP +.RS +.RS 3 +.B xsd help +.I command +.RE +.PP +for command-specific help. +.RE +.IP \fBversion\fR +Print version and exit. +.\"-------------------------------------------------------------------- +.SH OPTIONS +.\"-------------------------------------------------------------------- +Command-specific +.IR options , +if any, should appear after the corresponding +.IR command . + +.\" +.\" Common options. +.\" +.SS common options +. diff --git a/xsd/doc/xsd-prologue.xhtml b/xsd/doc/xsd-prologue.xhtml new file mode 100644 index 0000000..6782a32 --- /dev/null +++ b/xsd/doc/xsd-prologue.xhtml @@ -0,0 +1,122 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> + <title>$project$ $version$ Compiler Command Line Manual</title> + + <meta charset="UTF-8"/> + <meta name="version" content="$version$"/> + <meta name="copyright" content="© $copyright$"/> + <meta name="keywords" content="xsd,xml,schema,c++,mapping,data,binding,code,generator,manual,man,page"/> + <meta name="description" content="XSD Compiler Command Line Manual"/> + + <link rel="stylesheet" type="text/css" href="default.css" /> + +<style type="text/css"> + + #synopsis { + list-style-type: none; + } + + #synopsis li { + padding-top : 0.0em; + padding-bottom : 0.0em; + } + + #commands dt { + padding-top : 0.4em; + } + + #commands dd { + padding-bottom : 0.4em; + padding-left : 2em; + } + + .options { + margin: 1em 0 1em 0; + } + + .options dt { + margin: 1em 0 0 0; + } + + .options dd { + margin: .1em 0 0 4.5em; + } + +</style> +</head> + +<body> +<div id="container"> + <div id="content"> + + <h1>NAME</h1> + + <p>xsd - W3C XML Schema to C++ Compiler</p> + + <h1>SYNOPSIS</h1> + + <dl id="synopsis"> + <dt><code><b>xsd</b> <i>command</i> [<i>options</i>] <i>file</i> [<i>file</i> ...]</code></dt> + <dt><code><b>xsd help</b> [<i>command</i>]</code></dt> + <dt><code><b>xsd version</b></code></dt> + </dl> + + <h1>DESCRIPTION</h1> + + <p><code><b>xsd</b></code> generates vocabulary-specific, statically-typed + C++ mapping from W3C XML Schema definitions. Particular mapping to + produce is selected by a <code><i>command</i></code>. Each mapping has + a number of mapping-specific <code><i>options</i></code> that should + appear, if any, after the <code><i>command</i></code>. Input files should + be W3C XML Schema definitions. The exact set of the generated files depends + on the selected mapping and options.</p> + + <h1>COMMANDS</h1> + + <dl id="commands"> + <dt><code><b>cxx-tree</b></code></dt> + <dd>Generate the C++/Tree mapping. For each input file in the form + <code><b>name.xsd</b></code> the following C++ files are generated: + <code><b>name.hxx</b></code> (header file), + <code><b>name.ixx</b></code> (inline file, generated only if the + <code><b>--generate-inline</b></code> option is specified), + <code><b>name.cxx</b></code> (source file), and + <code><b>name-fwd.hxx</b></code> (forward declaration file, generated + only if the <code><b>--generate-forward</b></code> option is + specified).</dd> + + <dt><code><b>cxx-parser</b></code></dt> + <dd>Generate the C++/Parser mapping. For each input file in the form + <code><b>name.xsd</b></code> the following C++ files are generated: + <code><b>name-pskel.hxx</b></code> (parser skeleton header file), + <code><b>name-pskel.ixx</b></code> (parser skeleton inline file, + generated only if the <code><b>--generate-inline</b></code> + option is specified), and + <code><b>name-pskel.cxx</b></code> (parser skeleton source file). + If the <code><b>--generate-noop-impl</b></code> or + <code><b>--generate-print-impl</b></code> option is specified, + the following additional sample implementation files are generated: + <code><b>name-pimpl.hxx</b></code> (parser implementation header + file) and + <code><b>name-pimpl.cxx</b></code> (parser implementation source + file). If the <code><b>--generate-test-driver</b></code> option + is specified, the additional <code><b>name-driver.cxx</b></code> + test driver file is generated.</dd> + + <dt><code><b>help</b></code></dt> + <dd>Print usage information and exit. Use + <p><code><b>xsd help</b> <i>command</i></code></p> + for command-specific help. + </dd> + + <dt><code><b>version</b></code></dt> + <dd>Print version and exit.</dd> + </dl> + + <h1>OPTIONS</h1> + + <p>Command-specific <code><i>options</i></code>, if any, should appear + after the corresponding <code><i>command</i></code>.</p> + + <h2>COMMON OPTIONS</h2> diff --git a/xsd/doc/xsd-tree-header.1 b/xsd/doc/xsd-tree-header.1 new file mode 100644 index 0000000..b9146a7 --- /dev/null +++ b/xsd/doc/xsd-tree-header.1 @@ -0,0 +1,4 @@ +.\" +.\" C++/Tree options. +.\" +.SS cxx-tree command options diff --git a/xsd/doc/xsd-tree-header.xhtml b/xsd/doc/xsd-tree-header.xhtml new file mode 100644 index 0000000..73f9c99 --- /dev/null +++ b/xsd/doc/xsd-tree-header.xhtml @@ -0,0 +1 @@ + <h2>CXX-TREE COMMAND OPTIONS</h2> diff --git a/xsd/makefile b/xsd/makefile deleted file mode 100644 index 55a99ef..0000000 --- a/xsd/makefile +++ /dev/null @@ -1,190 +0,0 @@ -# file : xsd/makefile -# license : GNU GPL v2 + exceptions; see accompanying LICENSE file - -include $(dir $(lastword $(MAKEFILE_LIST)))../build/bootstrap.make - -cxx_tun := xsd.cxx - -cxx_tun += cxx/elements.cxx \ - cxx/literal-map.cxx \ - cxx/option-types.cxx - -cxx_tun += cxx/parser/elements.cxx \ - cxx/parser/validator.cxx \ - cxx/parser/name-processor.cxx \ - cxx/parser/type-processor.cxx \ - cxx/parser/state-processor.cxx \ - cxx/parser/generator.cxx \ - cxx/parser/parser-header.cxx \ - cxx/parser/parser-inline.cxx \ - cxx/parser/parser-source.cxx \ - cxx/parser/parser-forward.cxx \ - cxx/parser/impl-header.cxx \ - cxx/parser/impl-source.cxx \ - cxx/parser/driver-source.cxx \ - cxx/parser/element-validation-source.cxx \ - cxx/parser/attribute-validation-source.cxx \ - cxx/parser/characters-validation-source.cxx - -cxx_tun += cxx/tree/elements.cxx \ - cxx/tree/validator.cxx \ - cxx/tree/counter.cxx \ - cxx/tree/name-processor.cxx \ - cxx/tree/order-processor.cxx \ - cxx/tree/polymorphism-processor.cxx \ - cxx/tree/default-value.cxx \ - cxx/tree/generator.cxx \ - cxx/tree/tree-forward.cxx \ - cxx/tree/tree-header.cxx \ - cxx/tree/tree-inline.cxx \ - cxx/tree/tree-source.cxx \ - cxx/tree/parser-header.cxx \ - cxx/tree/parser-source.cxx \ - cxx/tree/stream-header.cxx \ - cxx/tree/stream-source.cxx \ - cxx/tree/serialization-header.cxx \ - cxx/tree/serialization-source.cxx \ - cxx/tree/stream-insertion-header.cxx \ - cxx/tree/stream-insertion-source.cxx \ - cxx/tree/stream-extraction-source.cxx - - -# Type map. -# -cxx_tun += type-map/lexer.cxx \ - type-map/parser.cxx - -# Processing. -# -cxx_tun += processing/cardinality/processor.cxx \ - processing/inheritance/processor.cxx - -# Options file. -# -cli_tun := options.cli \ - cxx/options.cli \ - cxx/tree/options.cli \ - cxx/parser/options.cli - -cxx_obj := $(addprefix $(out_base)/,$(cxx_tun:.cxx=.o) $(cli_tun:.cli=.o)) -cxx_od := $(cxx_obj:.o=.o.d) - -xsd := $(out_base)/xsd -install := $(out_base)/.install -dist := $(out_base)/.dist -dist-win := $(out_base)/.dist-win -clean := $(out_base)/.clean - -# Import. -# -$(call import,\ - $(scf_root)/import/cli/stub.make,\ - cli: cli,cli-rules: cli_rules) - -$(call import,\ - $(scf_root)/import/libcutl/stub.make,\ - l: cutl.l,cpp-options: cutl.l.cpp-options) - -$(call import,\ - $(scf_root)/import/libxsd-frontend/stub.make,\ - l: xsd_fe.l,cpp-options: xsd_fe.l.cpp-options) - -$(call import,\ - $(scf_root)/import/libxerces-c/stub.make,\ - l: xerces_c.l,cpp-options: xerces_c.l.cpp-options) - -# Build. -# -$(xsd): $(cxx_obj) $(xsd_fe.l) $(cutl.l) $(xerces_c.l) - -$(cxx_obj) $(cxx_od): cpp_options := -I$(out_base) -I$(src_base) -$(cxx_obj) $(cxx_od): \ - $(xsd_fe.l.cpp-options) \ - $(cutl.l.cpp-options) \ - $(xerces_c.l.cpp-options) - -genf := $(cli_tun:.cli=.hxx) $(cli_tun:.cli=.ixx) $(cli_tun:.cli=.cxx) -gen := $(addprefix $(out_base)/,$(genf)) - -# Don't depend on installed executable since it may not exist. -# -ifneq ($(cli),cli) -$(gen): $(cli) -endif -$(gen): cli := $(cli) -$(gen): cli_options += \ --I $(src_base) \ ---generate-specifier \ ---ostream-type ::std::wostream \ ---exclude-base \ ---suppress-undocumented \ ---generate-file-scanner \ ---include-with-brackets \ ---option-length 28 \ ---cxx-prologue '\#include <options-parser.hxx>' - -#--include-prefix xsd -#--guard-prefix XSD - -$(addprefix $(out_base)/cxx/options,.hxx .ixx .cxx): $(src_base)/options.cli -$(addprefix $(out_base)/cxx/options,.hxx .ixx .cxx): cli_options += \ ---include-prefix cxx --guard-prefix CXX - -$(addprefix $(out_base)/cxx/tree/options,.hxx .ixx .cxx): \ -$(src_base)/options.cli $(src_base)/cxx/options.cli -$(addprefix $(out_base)/cxx/tree/options,.hxx .ixx .cxx): cli_options += \ ---include-prefix cxx/tree --guard-prefix CXX_TREE - -$(addprefix $(out_base)/cxx/parser/options,.hxx .ixx .cxx): \ -$(src_base)/options.cli $(src_base)/cxx/options.cli -$(addprefix $(out_base)/cxx/parser/options,.hxx .ixx .cxx): cli_options += \ ---include-prefix cxx/parser --guard-prefix CXX_PARSER - -$(call include-dep,$(cxx_od),$(cxx_obj),$(gen)) - -# Alias for default target. -# -$(out_base)/: $(xsd) - -# Install -# -$(install): $(xsd) - $(call install-exec,$<,$(install_bin_dir)/xsd) - -# Dist. -# -$(dist): $(xsd) - $(call install-exec,$<,$(dist_prefix)/bin/xsd) - -$(dist-win): $(xsd) - $(call install-exec,$<,$(dist_prefix)/bin/xsd.exe) - -# Clean. -# -$(clean): \ - $(xsd).o.clean \ - $(addsuffix .cxx.clean,$(cxx_obj)) \ - $(addsuffix .cxx.clean,$(cxx_od)) - -ifneq ($(xsd_clean_gen),n) -$(clean): $(addprefix $(out_base)/,$(cli_tun:.cli=.cxx.cli.clean)) -endif - -# Generated .gitignore. -# -ifeq ($(out_base),$(src_base)) -$(xsd): | $(out_base)/.gitignore - -$(out_base)/.gitignore: files := xsd $(genf) -$(clean): $(out_base)/.gitignore.clean - -$(call include,$(bld_root)/git/gitignore.make) -endif - -# How to. -# -$(call include,$(cli_rules)) -$(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,$(bld_root)/install.make) diff --git a/xsd/manifest b/xsd/manifest new file mode 100644 index 0000000..8ae3ef5 --- /dev/null +++ b/xsd/manifest @@ -0,0 +1,162 @@ +: 1 +name: xsd +version: 4.2.1-a.0.z +language: c++ +summary: XML Schema to C++ data binding compiler +license: other: GPL-2.0-only with Xerces-C++ linking exception and FLOSS exception +topics: C++, XML, XML Schema, XML parser, source code generation +description-file: README.md +package-description-file: PACKAGE-README.md +changes-file: NEWS +url: https://www.codesynthesis.com/products/xsd/ +doc-url: https://www.codesynthesis.com/products/xsd/ +src-url: https://git.codesynthesis.com/cgit/xsd/xsd/ +email: xsd-users@codesynthesis.com ; Mailing list +build-warning-email: builds@codesynthesis.com +requires: host +requires: c++11 +depends: * build2 >= 0.16.0 +depends: * bpkg >= 0.16.0 +depends: libxsd-frontend ^2.1.0 +depends: libcutl ^1.11.0 +depends: libxerces-c ^3.0.0 +depends: * cli ^1.2.0- ? ($config.xsd.develop) +tests: * xsd-tests == $ +examples: * xsd-examples == $ + +# Binary distribution packages. Overall notes: +# +# - Link dependencies that don't come from system packages statically. +# +# - We suppress generating binary packages for dependecies (libcutl, +# libxsd-frontend) with --recursive=auto since they are linked statically. +# +# - For archives we strip the default compiler name from metadata since +# it's unimportant (we link the C++ runtime statically). +# +# - We disable warning emails for configurations that build Xerces-C++. + +# Note that the Xerces-C++ package is in the unsupported `universe` section on +# Ubuntu so we have a separate configuration for it where we build Xerces-C++ +# ourselves. +# +bindist-debian-builds: bindist +bindist-debian-build-include: linux_debian*-** +bindist-debian-build-exclude: ** +bindist-debian-build-config: +\ ++bpkg.bindist.debian: ++bbot.bindist.upload: +bpkg.bindist.debian:--recursive=auto +bpkg.create:config.bin.lib=static +bpkg.create:config.bin.liba.lib="shared static" +?sys:libxerces-c +\ + +bindist-ubuntu-builds: bindist +bindist-ubuntu-build-include: linux_ubuntu*-** +bindist-ubuntu-build-exclude: ** +bindist-ubuntu-build-config: +\ ++bpkg.bindist.debian: ++bbot.bindist.upload: +bpkg.bindist.debian:--recursive=auto +bpkg.create:config.bin.lib=static +bpkg.create:config.bin.liba.lib="shared static" +?sys:libicuuc +?sys:libicui18n +\ +#bindist-ubuntu-build-error-email: builds@codesynthesis.com + +# Note that there is no Xerces-C++ package in RHEL (only in EPEL) so we +# have a separate configuration for RHEL. +# +bindist-fedora-builds: bindist +bindist-fedora-build-include: linux_fedora*-** +bindist-fedora-build-exclude: ** +bindist-fedora-build-config: +\ ++bpkg.bindist.fedora: ++bbot.bindist.upload: +bpkg.bindist.fedora:--recursive=auto +bpkg.create:config.bin.lib=static +bpkg.create:config.bin.liba.lib="shared static" +?sys:libxerces-c +\ + +bindist-rhel-builds: bindist +bindist-rhel-build-include: linux_rhel*-** +bindist-rhel-build-exclude: ** +bindist-rhel-build-config: +\ ++bpkg.bindist.fedora: ++bbot.bindist.upload: +bpkg.bindist.fedora:--recursive=auto +bpkg.create:config.bin.lib=static +bpkg.create:config.bin.liba.lib="shared static" +?sys:libicuuc +?sys:libicui18n +\ +#bindist-rhel-build-error-email: builds@codesynthesis.com + +# Note: use static runtime since the DLL runtime is not universally +# pre-installed. +# +bindist-windows-builds: bindist +bindist-windows-build-include: windows*-** +bindist-windows-build-exclude: ** +bindist-windows-build-config: +\ ++bpkg.bindist.archive: ++bbot.bindist.upload: +bpkg.bindist.archive:--recursive=auto +bpkg.bindist.archive:--archive-lang-impl=cc= +bpkg.bindist.archive:config.install.relocatable=true +bpkg.create:config.bin.lib=static +bpkg.create:config.bin.liba.lib="shared static" +bpkg.create:config.cc.coptions+="/MT" +b.create:config.cc.coptions="/W2 /O2" +\ +#bindist-windows-build-error-email: builds@codesynthesis.com + +# Note that /usr/lib/libc++.1.dylib is pre-installed and appears to be +# reasonably compatible (even forward-compatible) so we don't bother +# with linking it statically for now. +# +bindist-macos-builds: bindist +bindist-macos-build-include: macos*-** +bindist-macos-build-exclude: ** +bindist-macos-build-config: +\ ++bpkg.bindist.archive: ++bbot.bindist.upload: +bpkg.bindist.archive:--recursive=auto +bpkg.bindist.archive:--archive-lang-impl=cc= +bpkg.bindist.archive:config.install.relocatable=true +bpkg.create:config.bin.lib=static +bpkg.create:config.bin.liba.lib="shared static" +b.create:config.cc.coptions="-Wall -O3" +\ +#bindist-macos-build-error-email: builds@codesynthesis.com + +# Generic linux package (built using oldest Debian we support). +# +# Note: update glibc version if changing build configuration. +# +bindist-linux-glibc2.31-builds: bindist +bindist-linux-glibc2.31-build-include: linux_debian_11-gcc_10.2-bindist +bindist-linux-glibc2.31-build-exclude: ** +bindist-linux-glibc2.31-build-config: +\ ++bpkg.bindist.archive: ++bbot.bindist.upload: +bpkg.bindist.archive:--recursive=auto +bpkg.bindist.archive:--archive-no-os +bpkg.bindist.archive:--archive-lang-impl=cc= +bpkg.bindist.archive:--archive-build-meta=+linux-glibc2.31 +bpkg.bindist.archive:config.install.relocatable=true +bpkg.create:config.bin.lib=static +bpkg.create:config.bin.liba.lib="shared static" +config.cc.loptions+="-static-libstdc++ -static-libgcc" +\ +#bindist-linux-glibc2.31-build-error-email: builds@codesynthesis.com diff --git a/xsd/processing/cardinality/processor.hxx b/xsd/processing/cardinality/processor.hxx deleted file mode 100644 index f09155e..0000000 --- a/xsd/processing/cardinality/processor.hxx +++ /dev/null @@ -1,28 +0,0 @@ -// file : processing/cardinality/processor.hxx -// license : GNU GPL v2 + exceptions; see accompanying LICENSE file - -#ifndef PROCESSING_CARDINALITY_PROCESSOR_HXX -#define PROCESSING_CARDINALITY_PROCESSOR_HXX - -#include <xsd-frontend/semantic-graph/elements.hxx> // Path -#include <xsd-frontend/semantic-graph/schema.hxx> - -#include <types.hxx> - -namespace Processing -{ - namespace Cardinality - { - class Processor - { - public: - struct Failed {}; - - void - process (XSDFrontend::SemanticGraph::Schema&, - XSDFrontend::SemanticGraph::Path const& file); - }; - } -} - -#endif // PROCESSING_CARDINALITY_PROCESSOR_HXX diff --git a/xsd/processing/inheritance/processor.hxx b/xsd/processing/inheritance/processor.hxx deleted file mode 100644 index f0a881f..0000000 --- a/xsd/processing/inheritance/processor.hxx +++ /dev/null @@ -1,28 +0,0 @@ -// file : processing/inheritance/processor.hxx -// license : GNU GPL v2 + exceptions; see accompanying LICENSE file - -#ifndef PROCESSING_INHERITANCE_PROCESSOR_HXX -#define PROCESSING_INHERITANCE_PROCESSOR_HXX - -#include <xsd-frontend/semantic-graph/elements.hxx> // Path -#include <xsd-frontend/semantic-graph/schema.hxx> - -#include <types.hxx> - -namespace Processing -{ - namespace Inheritance - { - class Processor - { - public: - struct Failed {}; - - void - process (XSDFrontend::SemanticGraph::Schema&, - XSDFrontend::SemanticGraph::Path const& file); - }; - } -} - -#endif // PROCESSING_INHERITANCE_PROCESSOR_HXX diff --git a/xsd/tests/.gitignore b/xsd/tests/.gitignore new file mode 100644 index 0000000..35ec43f --- /dev/null +++ b/xsd/tests/.gitignore @@ -0,0 +1,2 @@ +test/ +test-*/ diff --git a/xsd/tests/build/.gitignore b/xsd/tests/build/.gitignore new file mode 100644 index 0000000..4a730a3 --- /dev/null +++ b/xsd/tests/build/.gitignore @@ -0,0 +1,3 @@ +config.build +root/ +bootstrap/ diff --git a/xsd/tests/build/bootstrap.build b/xsd/tests/build/bootstrap.build new file mode 100644 index 0000000..33c8d02 --- /dev/null +++ b/xsd/tests/build/bootstrap.build @@ -0,0 +1,8 @@ +# file : tests/build/bootstrap.build +# license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +project = # Unnamed subproject. + +using config +using dist +using test diff --git a/xsd/tests/build/root.build b/xsd/tests/build/root.build new file mode 100644 index 0000000..dd7abe5 --- /dev/null +++ b/xsd/tests/build/root.build @@ -0,0 +1,16 @@ +# file : tests/build/root.build +# license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +# We need to configure C++ module to obtain the target information (see +# below). +# +using cxx.config + +# Import the XSD compiler we will be testing. +# +import! [metadata] xsd = xsd%exe{xsd} +testscript{*}: test = $xsd + +# Specify the test target for cross-testing. +# +test.target = $cxx.target diff --git a/xsd/tests/buildfile b/xsd/tests/buildfile new file mode 100644 index 0000000..201b1d7 --- /dev/null +++ b/xsd/tests/buildfile @@ -0,0 +1,4 @@ +# file : tests/buildfile +# license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +./: testscript $xsd diff --git a/xsd/tests/testscript b/xsd/tests/testscript new file mode 100644 index 0000000..7570d4d --- /dev/null +++ b/xsd/tests/testscript @@ -0,0 +1,26 @@ +# file : tests/testscript +# license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +: version +: +$* --version >>~/EOO/ +/CodeSynthesis XSD XML Schema to C\+\+ compiler .+/ +/.*/* +EOO + +: basics +: +cat <<EOI >=test.xsd; +<?xml version="1.0"?> +<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"> + <xsd:complexType name="hello_t"> + <xsd:sequence> + <xsd:element name="greeting" type="xsd:string"/> + <xsd:element name="name" type="xsd:string" maxOccurs="unbounded"/> + </xsd:sequence> + </xsd:complexType> + <xsd:element name="hello" type="hello_t"/> +</xsd:schema> +EOI +$* cxx-tree --generate-inline test.xsd &test.hxx &test.ixx &test.cxx; +test -f test.hxx && test -f test.ixx && test -f test.cxx diff --git a/xsd/xsd/.gitignore b/xsd/xsd/.gitignore new file mode 100644 index 0000000..8c86c4a --- /dev/null +++ b/xsd/xsd/.gitignore @@ -0,0 +1,3 @@ +/xsd +/version.hxx +/options.?xx diff --git a/xsd/xsd/buildfile b/xsd/xsd/buildfile new file mode 100644 index 0000000..d4e7af5 --- /dev/null +++ b/xsd/xsd/buildfile @@ -0,0 +1,121 @@ +# file : xsd/buildfile +# license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +import libs = libxsd-frontend%lib{xsd-frontend} +import libs += libcutl%lib{cutl} +import libs += libxerces-c%lib{xerces-c} + +ops = options cxx/options cxx/parser/options cxx/tree/options + +./: exe{xsd}: {hxx ixx txx cxx}{** -version -{$ops} -pregenerated/**} \ + {hxx}{version} \ + $libs + +# Target metadata, see also --build2-metadata in xsd.cxx. +# +# Note that xsd does not query any environment variables. +# +exe{xsd}: +{ + export.metadata = 1 xsd + xsd.name = [string] xsd + xsd.version = [string] $version + xsd.checksum = [string] $version +} + +hxx{version}: in{version} $src_root/manifest + +## Consumption build ($develop == false). +# + +# Use pregenerated versions in the consumption build. +# +exe{xsd}: pregenerated/{hxx ixx cxx}{**}: include = (!$develop) + +if! $develop + cxx.poptions =+ "-I($src_base/pregenerated)" # Note: must come first. + +# Distribute pregenerated versions only in the consumption build. +# +pregenerated/{hxx ixx cxx}{*}: dist = (!$develop) + +# +## + +## Development build ($develop == true). +# + +exe{xsd}: {hxx ixx cxx}{$ops}: include = $develop + +if $develop + import! [metadata] cli = cli%exe{cli} + +# In the development build distribute regenerated {hxx ixx cxx}{options}, +# remapping their locations to the paths of the pregenerated versions (which +# are only distributed in the consumption build; see above). This way we make +# sure that the distributed files are always up-to-date. +# +for f: $ops +{ + d = $directory($f) # empty, cxx/, etc. + + <{hxx ixx cxx}{$f}>: cli{$f} + { + dist = ($develop ? $relative([dir_path] "pregenerated/xsd/$d", $d) : false) + + # Symlink the generated code in src for convenience of development. + # + backlink = true + } +} + +<hxx{~'/(.*)/'} ixx{~'/\1/'} cxx{~'/\1/'}>: cli{~'/\1/'} $cli +% +if $develop +{{ + t = $path($>[0]).t + + depdb dyndep --byproduct --file $t + + h = $path($>[0]) + i = $path($>[1]) + c = $path($>[2]) + + d = $directory($h) + p = $string($leaf($d, $out_root)) # xsd, xsd/cxx, etc + + options = --std c++11 -I $src_root --include-prefix $p \ + --guard-prefix $regex.replace($ucase($p), '[/\\]', '_') \ + --generate-specifier --generate-file-scanner \ + --suppress-undocumented --ostream-type ::std::wostream \ + --exclude-base --include-with-brackets --option-length 28 \ + --cxx-prologue '#include <xsd/options-parser.hxx>' + + $cli $options --generate-dep --dep-file $t -o $d $path($<[0]) + + # If the result differs from the pregenerated version, copy it over. + # + d = [dir_path] $src_base/pregenerated/$p + + dh = $d/$leaf($h) + di = $d/$leaf($i) + dc = $d/$leaf($c) + + if diff $dh $h >- && \ + diff $di $i >- && \ + diff $dc $c >- + exit + end + + cp $h $dh + cp $i $di + cp $c $dc +}} + +# +## + +# Pass the copyright notice extracted from the LICENSE file. +# +obj{xsd cxx/parser/generator cxx/tree/generator}: \ + cxx.poptions += -DXSD_COPYRIGHT=\"$copyright\" diff --git a/xsd/xsd/cxx/.gitignore b/xsd/xsd/cxx/.gitignore new file mode 100644 index 0000000..c6e608b --- /dev/null +++ b/xsd/xsd/cxx/.gitignore @@ -0,0 +1 @@ +options.?xx diff --git a/xsd/cxx/elements.cxx b/xsd/xsd/cxx/elements.cxx index 5ead15f..02a768e 100644 --- a/xsd/cxx/elements.cxx +++ b/xsd/xsd/cxx/elements.cxx @@ -1,7 +1,7 @@ // file : xsd/cxx/elements.cxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#include <cxx/elements.hxx> +#include <xsd/cxx/elements.hxx> #include <cctype> // std::toupper #include <memory> @@ -102,6 +102,36 @@ namespace CXX L"xor", L"xor_eq" }; + + // Note: excluding "identifiers with special meaning" in certain contexts + // ("final", "override") since they shouldn't cause any issues. + // + wchar_t const* keywords_cxx11[] = { + L"alignas", + L"alignof", + L"char16_t", + L"char32_t", + L"constexpr", + L"decltype", + L"noexcept", + L"nullptr", + L"static_assert", + L"thread_local" + }; + + // Note: excluding "identifiers with special meaning" in certain contexts + // ("import", "module") since they shouldn't cause any issues. + // + wchar_t const* keywords_cxx20[] = { + L"char8_t", + L"concept", + L"consteval", + L"constinit", + L"co_await", + L"co_return", + L"co_yield", + L"requires" + }; } // Context @@ -268,8 +298,21 @@ namespace CXX // Populate the keyword set. // - for (size_t i (0); i < sizeof (keywords) / sizeof (char*); ++i) + for (size_t i (0); i < sizeof (keywords) / sizeof (wchar_t*); ++i) keyword_set_.insert (keywords[i]); + + if (std >= cxx_version::cxx11) + { + for (size_t i (0); i < sizeof (keywords_cxx11) / sizeof (wchar_t*); ++i) + keyword_set_.insert (keywords_cxx11[i]); + } + + if (std >= cxx_version::cxx20) + { + for (size_t i (0); i < sizeof (keywords_cxx20) / sizeof (wchar_t*); ++i) + keyword_set_.insert (keywords_cxx20[i]); + } + } String Context:: @@ -877,16 +920,19 @@ namespace CXX tmp[3] = (u | 0x80UL) & 0xBFUL; u >>= 6; } + // Fall through. case 3: { tmp[2] = (u | 0x80UL) & 0xBFUL; u >>= 6; } + // Fall through. case 2: { tmp[1] = (u | 0x80UL) & 0xBFUL; u >>= 6; } + // Fall through. case 1: { tmp[0] = u | utf8_first_char_mask[count]; diff --git a/xsd/cxx/elements.hxx b/xsd/xsd/cxx/elements.hxx index a316a0c..62ba97c 100644 --- a/xsd/cxx/elements.hxx +++ b/xsd/xsd/cxx/elements.hxx @@ -1,24 +1,24 @@ // file : xsd/cxx/elements.hxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#ifndef CXX_ELEMENTS_HXX -#define CXX_ELEMENTS_HXX +#ifndef XSD_CXX_ELEMENTS_HXX +#define XSD_CXX_ELEMENTS_HXX #include <set> #include <map> #include <vector> #include <ostream> -#include <cutl/re.hxx> +#include <libcutl/re.hxx> -#include <xsd-frontend/semantic-graph.hxx> -#include <xsd-frontend/traversal.hxx> +#include <libxsd-frontend/semantic-graph.hxx> +#include <libxsd-frontend/traversal.hxx> -#include <types.hxx> -#include <elements.hxx> +#include <xsd/types.hxx> +#include <xsd/elements.hxx> -#include <cxx/options.hxx> -#include <cxx/literal-map.hxx> +#include <xsd/cxx/options.hxx> +#include <xsd/cxx/literal-map.hxx> namespace CXX { @@ -623,4 +623,4 @@ namespace CXX }; } -#endif // CXX_TREE_ELEMENTS_HXX +#endif // XSD_CXX_TREE_ELEMENTS_HXX diff --git a/xsd/cxx/literal-map.cxx b/xsd/xsd/cxx/literal-map.cxx index f2515fe..b81f249 100644 --- a/xsd/cxx/literal-map.cxx +++ b/xsd/xsd/cxx/literal-map.cxx @@ -1,7 +1,7 @@ // file : xsd/cxx/literal-map.cxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#include <memory> // std::auto_ptr +#include <memory> // std::unique_ptr #include <cstddef> // std::size_t #include <fstream> #include <iostream> @@ -16,9 +16,9 @@ #include <xercesc/sax2/SAX2XMLReader.hpp> #include <xercesc/sax2/XMLReaderFactory.hpp> -#include <xsd-frontend/xml.hxx> +#include <libxsd-frontend/xml.hxx> -#include <cxx/literal-map.hxx> +#include <xsd/cxx/literal-map.hxx> using namespace std; using namespace xercesc; @@ -237,7 +237,7 @@ namespace CXX LocalFileInputSource is (XML::XMLChString (wfile).c_str ()); Handler h (wfile, map); - auto_ptr<SAX2XMLReader> parser ( + unique_ptr<SAX2XMLReader> parser ( XMLReaderFactory::createXMLReader ()); parser->setFeature (XMLUni::fgSAX2CoreNameSpaces, true); diff --git a/xsd/cxx/literal-map.hxx b/xsd/xsd/cxx/literal-map.hxx index cce9bf5..bc8fabb 100644 --- a/xsd/cxx/literal-map.hxx +++ b/xsd/xsd/cxx/literal-map.hxx @@ -1,12 +1,12 @@ // file : xsd/cxx/literal-map.hxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#ifndef CXX_LITERAL_MAP_HXX -#define CXX_LITERAL_MAP_HXX +#ifndef XSD_CXX_LITERAL_MAP_HXX +#define XSD_CXX_LITERAL_MAP_HXX #include <map> -#include <types.hxx> +#include <xsd/types.hxx> namespace CXX { @@ -16,4 +16,4 @@ namespace CXX read_literal_map (NarrowString const& file, StringLiteralMap& map); } -#endif // CXX_LITERAL_MAP_HXX +#endif // XSD_CXX_LITERAL_MAP_HXX diff --git a/xsd/cxx/option-types.cxx b/xsd/xsd/cxx/option-types.cxx index ec49d29..8744d7f 100644 --- a/xsd/cxx/option-types.cxx +++ b/xsd/xsd/cxx/option-types.cxx @@ -4,7 +4,7 @@ #include <istream> #include <ostream> -#include <cxx/option-types.hxx> +#include <xsd/cxx/option-types.hxx> using namespace std; @@ -17,7 +17,11 @@ namespace CXX static const char* cxx_version_[] = { "c++98", - "c++11" + "c++11", + "c++14", + "c++17", + "c++20", + "c++23", }; string cxx_version:: @@ -38,6 +42,14 @@ namespace CXX v = cxx_version::cxx98; else if (s == "c++11") v = cxx_version::cxx11; + else if (s == "c++14") + v = cxx_version::cxx14; + else if (s == "c++17") + v = cxx_version::cxx17; + else if (s == "c++20") + v = cxx_version::cxx20; + else if (s == "c++23") + v = cxx_version::cxx23; else is.setstate (istream::failbit); } diff --git a/xsd/cxx/option-types.hxx b/xsd/xsd/cxx/option-types.hxx index f36a6ca..98a493a 100644 --- a/xsd/cxx/option-types.hxx +++ b/xsd/xsd/cxx/option-types.hxx @@ -1,8 +1,8 @@ // file : xsd/cxx/option-types.hxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#ifndef XSD_OPTION_TYPES_HXX -#define XSD_OPTION_TYPES_HXX +#ifndef XSD_XSD_OPTION_TYPES_HXX +#define XSD_XSD_OPTION_TYPES_HXX #include <iosfwd> #include <string> @@ -14,10 +14,14 @@ namespace CXX enum value { cxx98, - cxx11 + cxx11, + cxx14, + cxx17, + cxx20, + cxx23 }; - cxx_version (value v = value (0)) : v_ (v) {} + cxx_version (value v) : v_ (v) {} operator value () const {return v_;} std::string @@ -31,4 +35,4 @@ namespace CXX operator>> (std::istream&, cxx_version&); } -#endif // XSD_OPTION_TYPES_HXX +#endif // XSD_XSD_OPTION_TYPES_HXX diff --git a/xsd/cxx/options.cli b/xsd/xsd/cxx/options.cli index 6e25949..1be7607 100644 --- a/xsd/cxx/options.cli +++ b/xsd/xsd/cxx/options.cli @@ -3,11 +3,11 @@ include <cstddef>; // std::size_t -include <types.hxx>; // NarrowString, NarrowStrings +include <xsd/types.hxx>; // NarrowString, NarrowStrings -include <cxx/option-types.hxx>; +include <xsd/cxx/option-types.hxx>; -include <options.cli>; +include <xsd/options.cli>; namespace CXX { @@ -15,17 +15,19 @@ namespace CXX { // Language. // - cxx_version --std = cxx_version::cxx98 + cxx_version --std = cxx_version::cxx11 { "<version>", "Specify the C++ standard that the generated code should conform to. - Valid values are \cb{c++98} (default) and \cb{c++11}. + Valid values are \cb{c++98}, \cb{c++11} (default), \cb{c++14}, + \cb{c++17}, \cb{c++20}, and \cb{c++23}. The C++ standard affects various aspects of the generated code that are discussed in more detail in various mapping-specific documentation. Overall, when C++11 is selected, the generated code relies on the move semantics and uses \cb{std::unique_ptr} - instead of deprecated \cb{std::auto_ptr}. + instead of deprecated \cb{std::auto_ptr}. Currently, there is no + difference between the C++11 and the later standards modes. When the C++11 mode is selected, you normally don't need to perform any extra steps other than enable C++11 in your C++ @@ -498,7 +500,7 @@ namespace CXX generated files on the main schema file as well as all the schema files that it includes/imports, transitively. This dependency file is then normally included into the main \cb{makefile} to implement - automatic dependency tracking. + automatic dependency tracking. See also the \cb{--dep-*} options. Note also that automatic dependency generation is not supported in the file-per-type mode (\cb{--file-per-type}). In this case, all @@ -534,8 +536,16 @@ namespace CXX NarrowString --dep-suffix = ".d" { "<suffix>", - "Use the provided <suffix> instead of the default \cb{.d} to - construct the name of the dependency file." + "Use <suffix> instead of the default \cb{.d} to construct the name of + the dependency file. See also \cb{--dep-file}." + }; + + NarrowString --dep-file + { + "<path>", + "Use <path> as the generated dependency file path instead of deriving + it from the input file name. Write the dependency information to + \cb{stdout} if <path> is \cb{-}. See also \cb{--dep-regex}." }; NarrowString --dep-regex diff --git a/xsd/cxx/parser/attribute-validation-source.cxx b/xsd/xsd/cxx/parser/attribute-validation-source.cxx index 76a3923..1c873fd 100644 --- a/xsd/cxx/parser/attribute-validation-source.cxx +++ b/xsd/xsd/cxx/parser/attribute-validation-source.cxx @@ -1,10 +1,10 @@ // file : xsd/cxx/parser/attribute-validation-source.cxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#include <cxx/parser/attribute-validation-source.hxx> +#include <xsd/cxx/parser/attribute-validation-source.hxx> -#include <xsd-frontend/semantic-graph.hxx> -#include <xsd-frontend/traversal.hxx> +#include <libxsd-frontend/semantic-graph.hxx> +#include <libxsd-frontend/traversal.hxx> namespace CXX { diff --git a/xsd/cxx/parser/attribute-validation-source.hxx b/xsd/xsd/cxx/parser/attribute-validation-source.hxx index 25d7d96..1f19bed 100644 --- a/xsd/cxx/parser/attribute-validation-source.hxx +++ b/xsd/xsd/cxx/parser/attribute-validation-source.hxx @@ -1,10 +1,10 @@ // file : xsd/cxx/parser/attribute-validation-source.hxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#ifndef CXX_PARSER_ATTRIBUTE_VALIDATION_SOURCE_HXX -#define CXX_PARSER_ATTRIBUTE_VALIDATION_SOURCE_HXX +#ifndef XSD_CXX_PARSER_ATTRIBUTE_VALIDATION_SOURCE_HXX +#define XSD_CXX_PARSER_ATTRIBUTE_VALIDATION_SOURCE_HXX -#include <cxx/parser/elements.hxx> +#include <xsd/cxx/parser/elements.hxx> namespace CXX { @@ -15,4 +15,4 @@ namespace CXX } } -#endif // CXX_PARSER_ATTRIBUTE_VALIDATION_SOURCE_HXX +#endif // XSD_CXX_PARSER_ATTRIBUTE_VALIDATION_SOURCE_HXX diff --git a/xsd/cxx/parser/characters-validation-source.cxx b/xsd/xsd/cxx/parser/characters-validation-source.cxx index 3f3e88c..749a4cc 100644 --- a/xsd/cxx/parser/characters-validation-source.cxx +++ b/xsd/xsd/cxx/parser/characters-validation-source.cxx @@ -1,10 +1,10 @@ // file : xsd/cxx/parser/characters-validation-source.cxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#include <cxx/parser/characters-validation-source.hxx> +#include <xsd/cxx/parser/characters-validation-source.hxx> -#include <xsd-frontend/semantic-graph.hxx> -#include <xsd-frontend/traversal.hxx> +#include <libxsd-frontend/semantic-graph.hxx> +#include <libxsd-frontend/traversal.hxx> namespace CXX { diff --git a/xsd/cxx/parser/characters-validation-source.hxx b/xsd/xsd/cxx/parser/characters-validation-source.hxx index d0c73c4..909901b 100644 --- a/xsd/cxx/parser/characters-validation-source.hxx +++ b/xsd/xsd/cxx/parser/characters-validation-source.hxx @@ -1,10 +1,10 @@ // file : xsd/cxx/parser/characters-validation-source.hxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#ifndef CXX_PARSER_CHARACTERS_VALIDATION_SOURCE_HXX -#define CXX_PARSER_CHARACTERS_VALIDATION_SOURCE_HXX +#ifndef XSD_CXX_PARSER_CHARACTERS_VALIDATION_SOURCE_HXX +#define XSD_CXX_PARSER_CHARACTERS_VALIDATION_SOURCE_HXX -#include <cxx/parser/elements.hxx> +#include <xsd/cxx/parser/elements.hxx> namespace CXX { @@ -15,4 +15,4 @@ namespace CXX } } -#endif // CXX_PARSER_CHARACTERS_VALIDATION_SOURCE_HXX +#endif // XSD_CXX_PARSER_CHARACTERS_VALIDATION_SOURCE_HXX diff --git a/xsd/cxx/parser/driver-source.cxx b/xsd/xsd/cxx/parser/driver-source.cxx index 48775eb..d1e6b7f 100644 --- a/xsd/cxx/parser/driver-source.cxx +++ b/xsd/xsd/cxx/parser/driver-source.cxx @@ -5,11 +5,11 @@ #include <map> #include <sstream> -#include <cxx/parser/driver-source.hxx> -#include <cxx/parser/print-impl-common.hxx> +#include <xsd/cxx/parser/driver-source.hxx> +#include <xsd/cxx/parser/print-impl-common.hxx> -#include <xsd-frontend/semantic-graph.hxx> -#include <xsd-frontend/traversal.hxx> +#include <libxsd-frontend/semantic-graph.hxx> +#include <libxsd-frontend/traversal.hxx> using namespace std; diff --git a/xsd/cxx/parser/driver-source.hxx b/xsd/xsd/cxx/parser/driver-source.hxx index d1c7f91..154091f 100644 --- a/xsd/cxx/parser/driver-source.hxx +++ b/xsd/xsd/cxx/parser/driver-source.hxx @@ -1,10 +1,10 @@ // file : xsd/cxx/parser/driver-source.hxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#ifndef CXX_PARSER_DRIVER_SOURCE_HXX -#define CXX_PARSER_DRIVER_SOURCE_HXX +#ifndef XSD_CXX_PARSER_DRIVER_SOURCE_HXX +#define XSD_CXX_PARSER_DRIVER_SOURCE_HXX -#include <cxx/parser/elements.hxx> +#include <xsd/cxx/parser/elements.hxx> namespace CXX { @@ -15,4 +15,4 @@ namespace CXX } } -#endif // CXX_PARSER_DRIVER_SOURCE_HXX +#endif // XSD_CXX_PARSER_DRIVER_SOURCE_HXX diff --git a/xsd/cxx/parser/element-validation-source.cxx b/xsd/xsd/cxx/parser/element-validation-source.cxx index b34b3dd..b5e1e9d 100644 --- a/xsd/cxx/parser/element-validation-source.cxx +++ b/xsd/xsd/cxx/parser/element-validation-source.cxx @@ -3,10 +3,10 @@ #include <vector> -#include <cxx/parser/element-validation-source.hxx> +#include <xsd/cxx/parser/element-validation-source.hxx> -#include <xsd-frontend/semantic-graph.hxx> -#include <xsd-frontend/traversal.hxx> +#include <libxsd-frontend/semantic-graph.hxx> +#include <libxsd-frontend/traversal.hxx> using namespace std; @@ -710,9 +710,9 @@ namespace CXX os << "count = 0;" << "state = " << next_state_ << "UL;" - << "// Fall through." << endl - << "}" // else - << "}"; // case + << "}" // else + << "}" // case + << "// Fall through." << endl; } virtual void @@ -831,9 +831,9 @@ namespace CXX os << "count = 0;" << "state = " << next_state_ << "UL;" - << "// Fall through." << endl - << "}" // else - << "}"; // case + << "}" // else + << "}" // case + << "// Fall through." << endl; } private: diff --git a/xsd/cxx/parser/element-validation-source.hxx b/xsd/xsd/cxx/parser/element-validation-source.hxx index fcdbf88..b358aee 100644 --- a/xsd/cxx/parser/element-validation-source.hxx +++ b/xsd/xsd/cxx/parser/element-validation-source.hxx @@ -1,10 +1,10 @@ // file : xsd/cxx/parser/element-validation-source.hxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#ifndef CXX_PARSER_ELEMENT_VALIDATION_SOURCE_HXX -#define CXX_PARSER_ELEMENT_VALIDATION_SOURCE_HXX +#ifndef XSD_CXX_PARSER_ELEMENT_VALIDATION_SOURCE_HXX +#define XSD_CXX_PARSER_ELEMENT_VALIDATION_SOURCE_HXX -#include <cxx/parser/elements.hxx> +#include <xsd/cxx/parser/elements.hxx> namespace CXX { @@ -15,4 +15,4 @@ namespace CXX } } -#endif // CXX_PARSER_ELEMENT_VALIDATION_SOURCE_HXX +#endif // XSD_CXX_PARSER_ELEMENT_VALIDATION_SOURCE_HXX diff --git a/xsd/cxx/parser/elements.cxx b/xsd/xsd/cxx/parser/elements.cxx index 6ab2a4b..63fb3d5 100644 --- a/xsd/cxx/parser/elements.cxx +++ b/xsd/xsd/cxx/parser/elements.cxx @@ -1,7 +1,7 @@ // file : xsd/cxx/parser/elements.cxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#include <cxx/parser/elements.hxx> +#include <xsd/cxx/parser/elements.hxx> namespace CXX { diff --git a/xsd/cxx/parser/elements.hxx b/xsd/xsd/cxx/parser/elements.hxx index 80656c2..0015923 100644 --- a/xsd/cxx/parser/elements.hxx +++ b/xsd/xsd/cxx/parser/elements.hxx @@ -1,18 +1,18 @@ // file : xsd/cxx/parser/elements.hxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#ifndef CXX_PARSER_ELEMENTS_HXX -#define CXX_PARSER_ELEMENTS_HXX +#ifndef XSD_CXX_PARSER_ELEMENTS_HXX +#define XSD_CXX_PARSER_ELEMENTS_HXX #include <sstream> -#include <cutl/re.hxx> +#include <libcutl/re.hxx> -#include <types.hxx> +#include <xsd/types.hxx> -#include <cxx/elements.hxx> +#include <xsd/cxx/elements.hxx> -#include <cxx/parser/options.hxx> +#include <xsd/cxx/parser/options.hxx> namespace CXX { @@ -312,4 +312,4 @@ namespace CXX } } -#endif // CXX_PARSER_ELEMENTS_HXX +#endif // XSD_CXX_PARSER_ELEMENTS_HXX diff --git a/xsd/cxx/parser/generator.cxx b/xsd/xsd/cxx/parser/generator.cxx index 6c87117..b1acdbb 100644 --- a/xsd/cxx/parser/generator.cxx +++ b/xsd/xsd/cxx/parser/generator.cxx @@ -5,42 +5,42 @@ #include <iostream> #include <fstream> -#include <cutl/re.hxx> +#include <libcutl/re.hxx> -#include <cutl/compiler/code-stream.hxx> -#include <cutl/compiler/cxx-indenter.hxx> -#include <cutl/compiler/sloc-counter.hxx> +#include <libcutl/compiler/code-stream.hxx> +#include <libcutl/compiler/cxx-indenter.hxx> +#include <libcutl/compiler/sloc-counter.hxx> -#include <xsd-frontend/semantic-graph.hxx> +#include <libxsd-frontend/semantic-graph.hxx> -#include <type-map/lexer.hxx> -#include <type-map/parser.hxx> -#include <type-map/type-map.hxx> +#include <xsd/version.hxx> -#include <cxx/parser/elements.hxx> -#include <cxx/parser/generator.hxx> +#include <xsd/type-map/lexer.hxx> +#include <xsd/type-map/parser.hxx> +#include <xsd/type-map/type-map.hxx> -#include <cxx/parser/validator.hxx> -#include <cxx/parser/name-processor.hxx> -#include <cxx/parser/state-processor.hxx> -#include <cxx/parser/type-processor.hxx> +#include <xsd/cxx/parser/elements.hxx> +#include <xsd/cxx/parser/generator.hxx> -#include <cxx/parser/parser-header.hxx> -#include <cxx/parser/parser-inline.hxx> -#include <cxx/parser/parser-source.hxx> -#include <cxx/parser/parser-forward.hxx> +#include <xsd/cxx/parser/validator.hxx> +#include <xsd/cxx/parser/name-processor.hxx> +#include <xsd/cxx/parser/state-processor.hxx> +#include <xsd/cxx/parser/type-processor.hxx> -#include <cxx/parser/impl-header.hxx> -#include <cxx/parser/impl-source.hxx> -#include <cxx/parser/driver-source.hxx> +#include <xsd/cxx/parser/parser-header.hxx> +#include <xsd/cxx/parser/parser-inline.hxx> +#include <xsd/cxx/parser/parser-source.hxx> +#include <xsd/cxx/parser/parser-forward.hxx> -#include <cxx/parser/element-validation-source.hxx> -#include <cxx/parser/attribute-validation-source.hxx> -#include <cxx/parser/characters-validation-source.hxx> +#include <xsd/cxx/parser/impl-header.hxx> +#include <xsd/cxx/parser/impl-source.hxx> +#include <xsd/cxx/parser/driver-source.hxx> -#include <cxx/parser/options.hxx> +#include <xsd/cxx/parser/element-validation-source.hxx> +#include <xsd/cxx/parser/attribute-validation-source.hxx> +#include <xsd/cxx/parser/characters-validation-source.hxx> -#include "../../../libxsd/xsd/cxx/version.hxx" +#include <xsd/cxx/parser/options.hxx> using std::endl; using std::wcerr; @@ -59,7 +59,7 @@ namespace CXX namespace { char const copyright_gpl[] = - "// Copyright (c) 2005-2020 Code Synthesis Tools CC.\n" + "// Copyright (c) " XSD_COPYRIGHT ".\n" "//\n" "// This program was generated by CodeSynthesis XSD, an XML Schema to\n" "// C++ data binding compiler.\n" @@ -77,29 +77,28 @@ namespace CXX "// along with this program; if not, write to the Free Software\n" "// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\n" "//\n" - "// In addition, as a special exception, Code Synthesis Tools CC gives\n" - "// permission to link this program with the Xerces-C++ library (or with\n" - "// modified versions of Xerces-C++ that use the same license as Xerces-C++),\n" - "// and distribute linked combinations including the two. You must obey\n" - "// the GNU General Public License version 2 in all respects for all of\n" - "// the code used other than Xerces-C++. If you modify this copy of the\n" - "// program, you may extend this exception to your version of the program,\n" - "// but you are not obligated to do so. If you do not wish to do so, delete\n" - "// this exception statement from your version.\n" + "// In addition, as a special exception, Code Synthesis gives permission\n" + "// to link this program with the Xerces-C++ library (or with modified\n" + "// versions of Xerces-C++ that use the same license as Xerces-C++), and\n" + "// distribute linked combinations including the two. You must obey the GNU\n" + "// General Public License version 2 in all respects for all of the code\n" + "// used other than Xerces-C++. If you modify this copy of the program, you\n" + "// may extend this exception to your version of the program, but you are\n" + "// not obligated to do so. If you do not wish to do so, delete this\n" + "// exception statement from your version.\n" "//\n" - "// Furthermore, Code Synthesis Tools CC makes a special exception for\n" - "// the Free/Libre and Open Source Software (FLOSS) which is described\n" - "// in the accompanying FLOSSE file.\n" + "// Furthermore, Code Synthesis makes a special exception for the Free/Libre\n" + "// and Open Source Software (FLOSS) which is described in the accompanying\n" + "// FLOSSE file.\n" "//\n\n"; char const copyright_proprietary[] = - "// Copyright (c) 2005-2020 Code Synthesis Tools CC.\n" + "// Copyright (c) " XSD_COPYRIGHT ".\n" "//\n" "// This program was generated by CodeSynthesis XSD, an XML Schema\n" "// to C++ data binding compiler, in the Proprietary License mode.\n" "// You should have received a proprietary license from Code Synthesis\n" - "// Tools CC prior to generating this code. See the license text for\n" - "// conditions.\n" + "// prior to generating this code. See the license text for conditions.\n" "//\n\n"; char const copyright_impl[] = @@ -232,8 +231,11 @@ namespace CXX throw Failed (); } + bool gen_cxx (!ops.file_list_only ()); + // Process names. // + if (gen_cxx) { NameProcessor proc; proc.process (ops, schema, file_path, string_literal_map); @@ -245,7 +247,7 @@ namespace CXX // Compute state machine info. // - if (validation) + if (gen_cxx && validation) { StateProcessor proc; proc.process (schema, file_path); @@ -254,6 +256,7 @@ namespace CXX // Read-in type maps. // TypeMap::Namespaces type_map; + if (gen_cxx) { using namespace TypeMap; @@ -376,6 +379,7 @@ namespace CXX // Process types. // + if (gen_cxx) { TypeProcessor proc; proc.process (ops, schema, gen_driver, type_map); @@ -559,135 +563,165 @@ namespace CXX if (impl) { - if (!ops.force_overwrite ()) + if (gen_cxx) { - WideInputFileStream tmp ( - hxx_impl_path.string ().c_str (), ios_base::in); + if (!ops.force_overwrite ()) + { + WideInputFileStream tmp ( + hxx_impl_path.string ().c_str (), ios_base::in); - if (tmp.is_open ()) + if (tmp.is_open ()) + { + wcerr << hxx_impl_path << ": error: cowardly refusing to " << + "overwrite an existing file" << endl; + throw Failed (); + } + + tmp.close (); + } + + hxx_impl.open (hxx_impl_path.string ().c_str (), ios_base::out); + + if (!hxx_impl.is_open ()) { - wcerr << hxx_impl_path << ": error: cowardly refusing to " << - "overwrite an existing file" << endl; + wcerr << hxx_impl_path << ": error: unable to open in write mode" + << endl; throw Failed (); } - tmp.close (); + unlinks.add (hxx_impl_path); } - hxx_impl.open (hxx_impl_path.string ().c_str (), ios_base::out); + file_list.push_back (hxx_impl_path.string ()); - if (!hxx_impl.is_open ()) + if (gen_cxx) { - wcerr << hxx_impl_path << ": error: unable to open in write mode" - << endl; - throw Failed (); - } + if (!ops.force_overwrite ()) + { + WideInputFileStream tmp ( + cxx_impl_path.string ().c_str (), ios_base::in); - unlinks.add (hxx_impl_path); - file_list.push_back (hxx_impl_path.string ()); + if (tmp.is_open ()) + { + wcerr << cxx_impl_path << ": error: cowardly refusing to " << + "overwrite an existing file" << endl; + throw Failed (); + } - if (!ops.force_overwrite ()) - { - WideInputFileStream tmp ( - cxx_impl_path.string ().c_str (), ios_base::in); + tmp.close (); + } - if (tmp.is_open ()) + cxx_impl.open (cxx_impl_path.string ().c_str (), ios_base::out); + + if (!cxx_impl.is_open ()) { - wcerr << cxx_impl_path << ": error: cowardly refusing to " << - "overwrite an existing file" << endl; + wcerr << cxx_impl_path << ": error: unable to open in write mode" + << endl; throw Failed (); } - tmp.close (); - } - - cxx_impl.open (cxx_impl_path.string ().c_str (), ios_base::out); - - if (!cxx_impl.is_open ()) - { - wcerr << cxx_impl_path << ": error: unable to open in write mode" - << endl; - throw Failed (); + unlinks.add (cxx_impl_path); } - unlinks.add (cxx_impl_path); file_list.push_back (cxx_impl_path.string ()); } if (driver) { - if (!ops.force_overwrite ()) + if (gen_cxx) { - WideInputFileStream tmp ( - cxx_driver_path.string ().c_str (), ios_base::in); - - if (tmp.is_open ()) + if (!ops.force_overwrite ()) { - wcerr << cxx_driver_path << ": error: cowardly refusing to " << - "overwrite an existing file" << endl; - throw Failed (); + WideInputFileStream tmp ( + cxx_driver_path.string ().c_str (), ios_base::in); + + if (tmp.is_open ()) + { + wcerr << cxx_driver_path << ": error: cowardly refusing to " << + "overwrite an existing file" << endl; + throw Failed (); + } + + tmp.close (); } - tmp.close (); - } + cxx_driver.open (cxx_driver_path.string ().c_str (), ios_base::out); - cxx_driver.open (cxx_driver_path.string ().c_str (), ios_base::out); + if (!cxx_driver.is_open ()) + { + wcerr << cxx_driver_path << ": error: unable to open in write " << + "mode" << endl; + throw Failed (); + } - if (!cxx_driver.is_open ()) - { - wcerr << cxx_driver_path << ": error: unable to open in write " << - "mode" << endl; - throw Failed (); + unlinks.add (cxx_driver_path); } - unlinks.add (cxx_driver_path); file_list.push_back (cxx_driver_path.string ()); } // Open the skel files. // - WideOutputFileStream hxx (hxx_path.string ().c_str (), ios_base::out); + WideOutputFileStream hxx; WideOutputFileStream ixx; WideOutputFileStream cxx; - if (!hxx.is_open ()) + if (gen_cxx) { - wcerr << hxx_path << ": error: unable to open in write mode" << endl; - throw Failed (); + hxx.open (hxx_path.string ().c_str (), ios_base::out); + + if (!hxx.is_open ()) + { + wcerr << hxx_path << ": error: unable to open in write mode" << endl; + throw Failed (); + } + + unlinks.add (hxx_path); } - unlinks.add (hxx_path); file_list.push_back (hxx_path.string ()); if (inline_) { - ixx.open (ixx_path.string ().c_str (), ios_base::out); - - if (!ixx.is_open ()) + if (gen_cxx) { - wcerr << ixx_path << ": error: unable to open in write mode" << endl; - throw Failed (); + ixx.open (ixx_path.string ().c_str (), ios_base::out); + + if (!ixx.is_open ()) + { + wcerr << ixx_path << ": error: unable to open in write mode" + << endl; + throw Failed (); + } + + unlinks.add (ixx_path); } - unlinks.add (ixx_path); file_list.push_back (ixx_path.string ()); } - if (source) { - cxx.open (cxx_path.string ().c_str (), ios_base::out); - - if (!cxx.is_open ()) + if (gen_cxx) { - wcerr << cxx_path << ": error: unable to open in write mode" << endl; - throw Failed (); + cxx.open (cxx_path.string ().c_str (), ios_base::out); + + if (!cxx.is_open ()) + { + wcerr << cxx_path << ": error: unable to open in write mode" + << endl; + throw Failed (); + } + + unlinks.add (cxx_path); } - unlinks.add (cxx_path); file_list.push_back (cxx_path.string ()); } + if (!gen_cxx) + return 0; + // Print copyright and license. // char const* copyright ( @@ -801,7 +835,7 @@ namespace CXX // hxx << "#include <xsd/cxx/config.hxx>" << endl << endl - << "#if (XSD_INT_VERSION != " << XSD_INT_VERSION << "L)" << endl + << "#if (LIBXSD_VERSION != " << XSD_VERSION << "L)" << endl << "#error XSD runtime version mismatch" << endl << "#endif" << endl << endl; diff --git a/xsd/cxx/parser/generator.hxx b/xsd/xsd/cxx/parser/generator.hxx index 6fd984b..150cd74 100644 --- a/xsd/cxx/parser/generator.hxx +++ b/xsd/xsd/cxx/parser/generator.hxx @@ -1,17 +1,17 @@ // file : xsd/cxx/parser/generator.hxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#ifndef CXX_PARSER_GENERATOR_HXX -#define CXX_PARSER_GENERATOR_HXX +#ifndef XSD_CXX_PARSER_GENERATOR_HXX +#define XSD_CXX_PARSER_GENERATOR_HXX -#include <xsd-frontend/semantic-graph/elements.hxx> // Path -#include <xsd-frontend/semantic-graph/schema.hxx> +#include <libxsd-frontend/semantic-graph/elements.hxx> // Path +#include <libxsd-frontend/semantic-graph/schema.hxx> -#include <xsd.hxx> -#include <types.hxx> +#include <xsd/xsd.hxx> +#include <xsd/types.hxx> -#include <cxx/literal-map.hxx> -#include <cxx/parser/options.hxx> +#include <xsd/cxx/literal-map.hxx> +#include <xsd/cxx/parser/options.hxx> namespace CXX { @@ -42,4 +42,4 @@ namespace CXX } } -#endif // CXX_PARSER_GENERATOR_HXX +#endif // XSD_CXX_PARSER_GENERATOR_HXX diff --git a/xsd/cxx/parser/impl-header.cxx b/xsd/xsd/cxx/parser/impl-header.cxx index 03106ca..be14dfa 100644 --- a/xsd/cxx/parser/impl-header.cxx +++ b/xsd/xsd/cxx/parser/impl-header.cxx @@ -1,10 +1,10 @@ // file : xsd/cxx/parser/impl-header.cxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#include <cxx/parser/impl-header.hxx> +#include <xsd/cxx/parser/impl-header.hxx> -#include <xsd-frontend/semantic-graph.hxx> -#include <xsd-frontend/traversal.hxx> +#include <libxsd-frontend/semantic-graph.hxx> +#include <libxsd-frontend/traversal.hxx> namespace CXX { diff --git a/xsd/cxx/parser/impl-header.hxx b/xsd/xsd/cxx/parser/impl-header.hxx index f22678a..1939e05 100644 --- a/xsd/cxx/parser/impl-header.hxx +++ b/xsd/xsd/cxx/parser/impl-header.hxx @@ -1,10 +1,10 @@ // file : xsd/cxx/parser/impl-header.hxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#ifndef CXX_PARSER_IMPL_HEADER_HXX -#define CXX_PARSER_IMPL_HEADER_HXX +#ifndef XSD_CXX_PARSER_IMPL_HEADER_HXX +#define XSD_CXX_PARSER_IMPL_HEADER_HXX -#include <cxx/parser/elements.hxx> +#include <xsd/cxx/parser/elements.hxx> namespace CXX { @@ -15,4 +15,4 @@ namespace CXX } } -#endif // CXX_PARSER_IMPL_HEADER_HXX +#endif // XSD_CXX_PARSER_IMPL_HEADER_HXX diff --git a/xsd/cxx/parser/impl-source.cxx b/xsd/xsd/cxx/parser/impl-source.cxx index 592c956..80a9644 100644 --- a/xsd/cxx/parser/impl-source.cxx +++ b/xsd/xsd/cxx/parser/impl-source.cxx @@ -1,11 +1,11 @@ // file : xsd/cxx/parser/impl-source.cxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#include <cxx/parser/impl-source.hxx> -#include <cxx/parser/print-impl-common.hxx> +#include <xsd/cxx/parser/impl-source.hxx> +#include <xsd/cxx/parser/print-impl-common.hxx> -#include <xsd-frontend/semantic-graph.hxx> -#include <xsd-frontend/traversal.hxx> +#include <libxsd-frontend/semantic-graph.hxx> +#include <libxsd-frontend/traversal.hxx> namespace CXX { diff --git a/xsd/cxx/parser/impl-source.hxx b/xsd/xsd/cxx/parser/impl-source.hxx index 2fa5183..0fc8060 100644 --- a/xsd/cxx/parser/impl-source.hxx +++ b/xsd/xsd/cxx/parser/impl-source.hxx @@ -1,10 +1,10 @@ // file : xsd/cxx/parser/impl-source.hxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#ifndef CXX_PARSER_IMPL_SOURCE_HXX -#define CXX_PARSER_IMPL_SOURCE_HXX +#ifndef XSD_CXX_PARSER_IMPL_SOURCE_HXX +#define XSD_CXX_PARSER_IMPL_SOURCE_HXX -#include <cxx/parser/elements.hxx> +#include <xsd/cxx/parser/elements.hxx> namespace CXX { @@ -15,4 +15,4 @@ namespace CXX } } -#endif // CXX_PARSER_IMPL_SOURCE_HXX +#endif // XSD_CXX_PARSER_IMPL_SOURCE_HXX diff --git a/xsd/cxx/parser/name-processor.cxx b/xsd/xsd/cxx/parser/name-processor.cxx index a06f1e3..73710ba 100644 --- a/xsd/cxx/parser/name-processor.cxx +++ b/xsd/xsd/cxx/parser/name-processor.cxx @@ -6,10 +6,10 @@ #include <sstream> #include <iostream> -#include <cxx/parser/name-processor.hxx> +#include <xsd/cxx/parser/name-processor.hxx> -#include <xsd-frontend/semantic-graph.hxx> -#include <xsd-frontend/traversal.hxx> +#include <libxsd-frontend/semantic-graph.hxx> +#include <libxsd-frontend/traversal.hxx> using namespace std; diff --git a/xsd/cxx/parser/name-processor.hxx b/xsd/xsd/cxx/parser/name-processor.hxx index f7f988f..f8ac28c 100644 --- a/xsd/cxx/parser/name-processor.hxx +++ b/xsd/xsd/cxx/parser/name-processor.hxx @@ -1,15 +1,15 @@ // file : xsd/cxx/parser/name-processor.hxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#ifndef CXX_PARSER_NAME_PROCESSOR_HXX -#define CXX_PARSER_NAME_PROCESSOR_HXX +#ifndef XSD_CXX_PARSER_NAME_PROCESSOR_HXX +#define XSD_CXX_PARSER_NAME_PROCESSOR_HXX -#include <xsd-frontend/semantic-graph.hxx> +#include <libxsd-frontend/semantic-graph.hxx> -#include <types.hxx> +#include <xsd/types.hxx> -#include <cxx/elements.hxx> -#include <cxx/parser/options.hxx> +#include <xsd/cxx/elements.hxx> +#include <xsd/cxx/parser/options.hxx> namespace CXX { @@ -27,4 +27,4 @@ namespace CXX } } -#endif // CXX_PARSER_NAME_PROCESSOR_HXX +#endif // XSD_CXX_PARSER_NAME_PROCESSOR_HXX diff --git a/xsd/cxx/parser/options.cli b/xsd/xsd/cxx/parser/options.cli index 11312ed..e430333 100644 --- a/xsd/cxx/parser/options.cli +++ b/xsd/xsd/cxx/parser/options.cli @@ -3,9 +3,9 @@ include <cstddef>; // std::size_t -include <types.hxx>; // NarrowString, NarrowStrings +include <xsd/types.hxx>; // NarrowString, NarrowStrings -include <cxx/options.cli>; +include <xsd/cxx/options.cli>; namespace CXX { diff --git a/xsd/cxx/parser/parser-forward.cxx b/xsd/xsd/cxx/parser/parser-forward.cxx index 09a055b..65603fd 100644 --- a/xsd/cxx/parser/parser-forward.cxx +++ b/xsd/xsd/cxx/parser/parser-forward.cxx @@ -1,10 +1,10 @@ // file : xsd/cxx/parser/parser-forward.cxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#include <cxx/parser/parser-forward.hxx> +#include <xsd/cxx/parser/parser-forward.hxx> -#include <xsd-frontend/semantic-graph.hxx> -#include <xsd-frontend/traversal.hxx> +#include <libxsd-frontend/semantic-graph.hxx> +#include <libxsd-frontend/traversal.hxx> namespace CXX { diff --git a/xsd/cxx/parser/parser-forward.hxx b/xsd/xsd/cxx/parser/parser-forward.hxx index 7796532..b5345a5 100644 --- a/xsd/cxx/parser/parser-forward.hxx +++ b/xsd/xsd/cxx/parser/parser-forward.hxx @@ -1,10 +1,10 @@ // file : xsd/cxx/parser/parser-forward.hxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#ifndef CXX_PARSER_PARSER_FORWARD_HXX -#define CXX_PARSER_PARSER_FORWARD_HXX +#ifndef XSD_CXX_PARSER_PARSER_FORWARD_HXX +#define XSD_CXX_PARSER_PARSER_FORWARD_HXX -#include <cxx/parser/elements.hxx> +#include <xsd/cxx/parser/elements.hxx> namespace CXX { @@ -15,4 +15,4 @@ namespace CXX } } -#endif // CXX_PARSER_PARSER_FORWARD_HXX +#endif // XSD_CXX_PARSER_PARSER_FORWARD_HXX diff --git a/xsd/cxx/parser/parser-header.cxx b/xsd/xsd/cxx/parser/parser-header.cxx index ad7767a..327bb07 100644 --- a/xsd/cxx/parser/parser-header.cxx +++ b/xsd/xsd/cxx/parser/parser-header.cxx @@ -3,10 +3,10 @@ #include <set> -#include <cxx/parser/parser-header.hxx> +#include <xsd/cxx/parser/parser-header.hxx> -#include <xsd-frontend/semantic-graph.hxx> -#include <xsd-frontend/traversal.hxx> +#include <libxsd-frontend/semantic-graph.hxx> +#include <libxsd-frontend/traversal.hxx> using namespace std; @@ -1189,7 +1189,7 @@ namespace CXX names (ns); - os << "// Exceptions. See libxsd/xsd/cxx/parser/exceptions.hxx " << + os << "// Exceptions. See xsd/cxx/parser/exceptions.hxx " << "for details." << endl << "//" << endl << "typedef ::xsd::cxx::parser::exception< " << @@ -1205,7 +1205,7 @@ namespace CXX << endl; os << "// Error handler. See " << - "libxsd/xsd/cxx/xml/error-handler.hxx for details." << endl + "xsd/cxx/xml/error-handler.hxx for details." << endl << "//" << endl << "typedef ::xsd::cxx::xml::error_handler< " << c << " > error_handler;" @@ -1219,14 +1219,14 @@ namespace CXX if (xml_parser == L"xerces") { os << "// Parsing flags. See " << - "libxsd/xsd/cxx/parser/xerces/elements.hxx" << endl + "xsd/cxx/parser/xerces/elements.hxx" << endl << "// for details." << endl << "//" << endl << "typedef ::xsd::cxx::parser::xerces::flags flags;" << endl; os << "// Parsing properties. See " << - "libxsd/xsd/cxx/parser/xerces/elements.hxx" << endl + "xsd/cxx/parser/xerces/elements.hxx" << endl << "// for details." << endl << "//" << endl << "typedef ::xsd::cxx::parser::xerces::properties< " << c << @@ -1234,7 +1234,7 @@ namespace CXX << endl; os << "// Document type. See " << - "libxsd/xsd/cxx/parser/xerces/elements.hxx" << endl + "xsd/cxx/parser/xerces/elements.hxx" << endl << "// for details." << endl << "//" << endl << "typedef ::xsd::cxx::parser::xerces::document< " << c << @@ -1245,7 +1245,7 @@ namespace CXX else if (xml_parser == L"expat") { os << "// Document type. See " << - "libxsd/xsd/cxx/parser/expat/elements.hxx" << endl + "xsd/cxx/parser/expat/elements.hxx" << endl << "// for details." << endl << "//" << endl << "typedef ::xsd::cxx::parser::expat::document< " << c << diff --git a/xsd/cxx/parser/parser-header.hxx b/xsd/xsd/cxx/parser/parser-header.hxx index 2656fff..642da40 100644 --- a/xsd/cxx/parser/parser-header.hxx +++ b/xsd/xsd/cxx/parser/parser-header.hxx @@ -1,10 +1,10 @@ // file : xsd/cxx/parser/parser-header.hxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#ifndef CXX_PARSER_PARSER_HEADER_HXX -#define CXX_PARSER_PARSER_HEADER_HXX +#ifndef XSD_CXX_PARSER_PARSER_HEADER_HXX +#define XSD_CXX_PARSER_PARSER_HEADER_HXX -#include <cxx/parser/elements.hxx> +#include <xsd/cxx/parser/elements.hxx> namespace CXX { @@ -15,4 +15,4 @@ namespace CXX } } -#endif // CXX_PARSER_PARSER_HEADER_HXX +#endif // XSD_CXX_PARSER_PARSER_HEADER_HXX diff --git a/xsd/cxx/parser/parser-inline.cxx b/xsd/xsd/cxx/parser/parser-inline.cxx index fb7558e..6705d5b 100644 --- a/xsd/cxx/parser/parser-inline.cxx +++ b/xsd/xsd/cxx/parser/parser-inline.cxx @@ -1,10 +1,10 @@ // file : xsd/cxx/parser/parser-inline.cxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#include <cxx/parser/parser-inline.hxx> +#include <xsd/cxx/parser/parser-inline.hxx> -#include <xsd-frontend/semantic-graph.hxx> -#include <xsd-frontend/traversal.hxx> +#include <libxsd-frontend/semantic-graph.hxx> +#include <libxsd-frontend/traversal.hxx> namespace CXX { diff --git a/xsd/cxx/parser/parser-inline.hxx b/xsd/xsd/cxx/parser/parser-inline.hxx index 7c732fc..aee0cdf 100644 --- a/xsd/cxx/parser/parser-inline.hxx +++ b/xsd/xsd/cxx/parser/parser-inline.hxx @@ -1,10 +1,10 @@ // file : xsd/cxx/parser/parser-inline.hxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#ifndef CXX_PARSER_PARSER_INLINE_HXX -#define CXX_PARSER_PARSER_INLINE_HXX +#ifndef XSD_CXX_PARSER_PARSER_INLINE_HXX +#define XSD_CXX_PARSER_PARSER_INLINE_HXX -#include <cxx/parser/elements.hxx> +#include <xsd/cxx/parser/elements.hxx> namespace CXX { @@ -15,4 +15,4 @@ namespace CXX } } -#endif // CXX_PARSER_PARSER_INLINE_HXX +#endif // XSD_CXX_PARSER_PARSER_INLINE_HXX diff --git a/xsd/cxx/parser/parser-source.cxx b/xsd/xsd/cxx/parser/parser-source.cxx index 64c0075..2887f96 100644 --- a/xsd/cxx/parser/parser-source.cxx +++ b/xsd/xsd/cxx/parser/parser-source.cxx @@ -1,10 +1,10 @@ // file : xsd/cxx/parser/parser-source.cxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#include <cxx/parser/parser-source.hxx> +#include <xsd/cxx/parser/parser-source.hxx> -#include <xsd-frontend/semantic-graph.hxx> -#include <xsd-frontend/traversal.hxx> +#include <libxsd-frontend/semantic-graph.hxx> +#include <libxsd-frontend/traversal.hxx> namespace CXX { diff --git a/xsd/cxx/parser/parser-source.hxx b/xsd/xsd/cxx/parser/parser-source.hxx index 0f8f57e..3598a00 100644 --- a/xsd/cxx/parser/parser-source.hxx +++ b/xsd/xsd/cxx/parser/parser-source.hxx @@ -1,10 +1,10 @@ // file : xsd/cxx/parser/parser-source.hxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#ifndef CXX_PARSER_PARSER_SOURCE_HXX -#define CXX_PARSER_PARSER_SOURCE_HXX +#ifndef XSD_CXX_PARSER_PARSER_SOURCE_HXX +#define XSD_CXX_PARSER_PARSER_SOURCE_HXX -#include <cxx/parser/elements.hxx> +#include <xsd/cxx/parser/elements.hxx> namespace CXX { @@ -15,4 +15,4 @@ namespace CXX } } -#endif // CXX_PARSER_PARSER_SOURCE_HXX +#endif // XSD_CXX_PARSER_PARSER_SOURCE_HXX diff --git a/xsd/cxx/parser/print-impl-common.hxx b/xsd/xsd/cxx/parser/print-impl-common.hxx index 66379f0..14bfbc2 100644 --- a/xsd/cxx/parser/print-impl-common.hxx +++ b/xsd/xsd/cxx/parser/print-impl-common.hxx @@ -1,13 +1,13 @@ // file : xsd/cxx/parser/print-impl-common.hxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#ifndef CXX_PARSER_PRINT_IMPL_COMMON_HXX -#define CXX_PARSER_PRINT_IMPL_COMMON_HXX +#ifndef XSD_CXX_PARSER_PRINT_IMPL_COMMON_HXX +#define XSD_CXX_PARSER_PRINT_IMPL_COMMON_HXX -#include <xsd-frontend/semantic-graph.hxx> -#include <xsd-frontend/traversal.hxx> +#include <libxsd-frontend/semantic-graph.hxx> +#include <libxsd-frontend/traversal.hxx> -#include <cxx/parser/elements.hxx> +#include <xsd/cxx/parser/elements.hxx> namespace CXX { @@ -638,4 +638,4 @@ namespace CXX } } -#endif // CXX_PARSER_PRINT_IMPL_COMMON_HXX +#endif // XSD_CXX_PARSER_PRINT_IMPL_COMMON_HXX diff --git a/xsd/cxx/parser/state-processor.cxx b/xsd/xsd/cxx/parser/state-processor.cxx index 423d0d8..a2b8fbf 100644 --- a/xsd/cxx/parser/state-processor.cxx +++ b/xsd/xsd/cxx/parser/state-processor.cxx @@ -4,12 +4,12 @@ #include <vector> #include <iostream> -#include <cxx/parser/state-processor.hxx> +#include <xsd/cxx/parser/state-processor.hxx> -#include <cxx/parser/elements.hxx> +#include <xsd/cxx/parser/elements.hxx> -#include <xsd-frontend/semantic-graph.hxx> -#include <xsd-frontend/traversal.hxx> +#include <libxsd-frontend/semantic-graph.hxx> +#include <libxsd-frontend/traversal.hxx> using namespace std; @@ -156,8 +156,8 @@ namespace CXX depth_ = depth; prefixes_.insert (prefixes_.end (), - t.prefixes_.begin ().base (), - t.prefixes_.end ().base ()); + t.prefixes_.begin (), + t.prefixes_.end ()); if (min == 1 && p.context ().get<size_t> ("effective-min") == 0) @@ -231,8 +231,8 @@ namespace CXX if (prefix) { prefixes_.insert (prefixes_.end (), - t.prefixes_.begin ().base (), - t.prefixes_.end ().base ()); + t.prefixes_.begin (), + t.prefixes_.end ()); if (p.context ().get<size_t> ("effective-min") != 0) min = 1; diff --git a/xsd/cxx/parser/state-processor.hxx b/xsd/xsd/cxx/parser/state-processor.hxx index e5559b4..eacc14a 100644 --- a/xsd/cxx/parser/state-processor.hxx +++ b/xsd/xsd/cxx/parser/state-processor.hxx @@ -1,12 +1,12 @@ // file : xsd/cxx/parser/state-processor.hxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#ifndef CXX_PARSER_STATE_PROCESSOR_HXX -#define CXX_PARSER_STATE_PROCESSOR_HXX +#ifndef XSD_CXX_PARSER_STATE_PROCESSOR_HXX +#define XSD_CXX_PARSER_STATE_PROCESSOR_HXX -#include <xsd-frontend/semantic-graph.hxx> +#include <libxsd-frontend/semantic-graph.hxx> -#include <types.hxx> +#include <xsd/types.hxx> namespace CXX { @@ -22,4 +22,4 @@ namespace CXX } } -#endif // CXX_PARSER_STATE_PROCESSOR_HXX +#endif // XSD_CXX_PARSER_STATE_PROCESSOR_HXX diff --git a/xsd/cxx/parser/type-processor.cxx b/xsd/xsd/cxx/parser/type-processor.cxx index d1b2e68..6496b2a 100644 --- a/xsd/cxx/parser/type-processor.cxx +++ b/xsd/xsd/cxx/parser/type-processor.cxx @@ -3,11 +3,11 @@ #include <set> -#include <cxx/parser/elements.hxx> -#include <cxx/parser/type-processor.hxx> +#include <xsd/cxx/parser/elements.hxx> +#include <xsd/cxx/parser/type-processor.hxx> -#include <xsd-frontend/semantic-graph.hxx> -#include <xsd-frontend/traversal.hxx> +#include <libxsd-frontend/semantic-graph.hxx> +#include <libxsd-frontend/traversal.hxx> using namespace std; diff --git a/xsd/cxx/parser/type-processor.hxx b/xsd/xsd/cxx/parser/type-processor.hxx index 53fd970..6800024 100644 --- a/xsd/cxx/parser/type-processor.hxx +++ b/xsd/xsd/cxx/parser/type-processor.hxx @@ -1,16 +1,16 @@ // file : xsd/cxx/parser/type-processor.hxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#ifndef CXX_PARSER_TYPE_PROCESSOR_HXX -#define CXX_PARSER_TYPE_PROCESSOR_HXX +#ifndef XSD_CXX_PARSER_TYPE_PROCESSOR_HXX +#define XSD_CXX_PARSER_TYPE_PROCESSOR_HXX -#include <xsd-frontend/semantic-graph.hxx> +#include <libxsd-frontend/semantic-graph.hxx> -#include <types.hxx> +#include <xsd/types.hxx> -#include <type-map/type-map.hxx> +#include <xsd/type-map/type-map.hxx> -#include <cxx/parser/options.hxx> +#include <xsd/cxx/parser/options.hxx> namespace CXX { @@ -28,4 +28,4 @@ namespace CXX } } -#endif // CXX_PARSER_TYPE_PROCESSOR_HXX +#endif // XSD_CXX_PARSER_TYPE_PROCESSOR_HXX diff --git a/xsd/cxx/parser/validator.cxx b/xsd/xsd/cxx/parser/validator.cxx index 6bf5b48..8e8161a 100644 --- a/xsd/cxx/parser/validator.cxx +++ b/xsd/xsd/cxx/parser/validator.cxx @@ -4,12 +4,12 @@ #include <set> #include <iostream> -#include <cxx/parser/validator.hxx> +#include <xsd/cxx/parser/validator.hxx> -#include <xsd-frontend/semantic-graph.hxx> -#include <xsd-frontend/traversal.hxx> +#include <libxsd-frontend/semantic-graph.hxx> +#include <libxsd-frontend/traversal.hxx> -#include <cxx/parser/elements.hxx> +#include <xsd/cxx/parser/elements.hxx> using namespace std; @@ -255,6 +255,8 @@ namespace CXX Traversal::Element, ValidationContext { + using Schema::traverse; + Traverser (ValidationContext& c) : ValidationContext (c), any_ (c) @@ -395,6 +397,9 @@ namespace CXX Traversal::Attribute, ValidationContext { + using Schema::traverse; + using Complex::traverse; + AnonymousType (ValidationContext& c) : ValidationContext (c), anonymous_error_issued_ (false) @@ -448,7 +453,7 @@ namespace CXX virtual void traverse (SemanticGraph::Element& e) { - if (skip (e)) return; + if (skip (e)) return; if (traverse_common (e)) { diff --git a/xsd/cxx/parser/validator.hxx b/xsd/xsd/cxx/parser/validator.hxx index 5f10526..daffdc8 100644 --- a/xsd/cxx/parser/validator.hxx +++ b/xsd/xsd/cxx/parser/validator.hxx @@ -1,14 +1,14 @@ // file : xsd/cxx/parser/validator.hxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#ifndef CXX_PARSER_VALIDATOR_HXX -#define CXX_PARSER_VALIDATOR_HXX +#ifndef XSD_CXX_PARSER_VALIDATOR_HXX +#define XSD_CXX_PARSER_VALIDATOR_HXX -#include <xsd.hxx> -#include <types.hxx> +#include <xsd/xsd.hxx> +#include <xsd/types.hxx> -#include <cxx/parser/elements.hxx> -#include <cxx/parser/options.hxx> +#include <xsd/cxx/parser/elements.hxx> +#include <xsd/cxx/parser/options.hxx> namespace CXX { @@ -27,4 +27,4 @@ namespace CXX } } -#endif // CXX_PARSER_VALIDATOR_HXX +#endif // XSD_CXX_PARSER_VALIDATOR_HXX diff --git a/xsd/cxx/tree/counter.cxx b/xsd/xsd/cxx/tree/counter.cxx index a5bdbb3..3fee0b1 100644 --- a/xsd/cxx/tree/counter.cxx +++ b/xsd/xsd/cxx/tree/counter.cxx @@ -1,7 +1,7 @@ // file : xsd/cxx/tree/counter.cxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#include <cxx/tree/counter.hxx> +#include <xsd/cxx/tree/counter.hxx> #include <iostream> @@ -241,18 +241,23 @@ namespace CXX schema >> sources >> schema; - Traversal::Names schema_names; - Traversal::Namespace ns; - Traversal::Names ns_names; - GlobalType global_type (ctx, counts); - GlobalElement global_element (ctx, counts); + // The GlobalElement object destructor updates the counts, so make sure + // that this object is destroyed before we return the counts. + // + { + Traversal::Names schema_names; + Traversal::Namespace ns; + Traversal::Names ns_names; + GlobalType global_type (ctx, counts); + GlobalElement global_element (ctx, counts); - schema >> schema_names >> ns >> ns_names; + schema >> schema_names >> ns >> ns_names; - ns_names >> global_element; - ns_names >> global_type; + ns_names >> global_element; + ns_names >> global_type; - schema.dispatch (tu); + schema.dispatch (tu); + } return counts; } diff --git a/xsd/cxx/tree/counter.hxx b/xsd/xsd/cxx/tree/counter.hxx index 28dccf2..bc1dc79 100644 --- a/xsd/cxx/tree/counter.hxx +++ b/xsd/xsd/cxx/tree/counter.hxx @@ -1,11 +1,11 @@ // file : xsd/cxx/tree/counter.hxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#ifndef CXX_TREE_COUNTER_HXX -#define CXX_TREE_COUNTER_HXX +#ifndef XSD_CXX_TREE_COUNTER_HXX +#define XSD_CXX_TREE_COUNTER_HXX -#include <cxx/tree/elements.hxx> -#include <cxx/tree/options.hxx> +#include <xsd/cxx/tree/elements.hxx> +#include <xsd/cxx/tree/options.hxx> namespace CXX { @@ -22,4 +22,4 @@ namespace CXX } } -#endif // CXX_TREE_COUNTER_HXX +#endif // XSD_CXX_TREE_COUNTER_HXX diff --git a/xsd/cxx/tree/default-value.cxx b/xsd/xsd/cxx/tree/default-value.cxx index 24ec454..fd1c8c4 100644 --- a/xsd/cxx/tree/default-value.cxx +++ b/xsd/xsd/cxx/tree/default-value.cxx @@ -1,7 +1,7 @@ // file : xsd/cxx/tree/default-value.cxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#include <cxx/tree/default-value.hxx> +#include <xsd/cxx/tree/default-value.hxx> using std::hex; using std::dec; @@ -602,7 +602,7 @@ namespace CXX // Binary. // static unsigned char - base64_decode (unsigned char c) + base64_decode (wchar_t c) { unsigned char r = 0xFF; @@ -800,7 +800,7 @@ namespace CXX } static unsigned char - hex_decode (unsigned char c) + hex_decode (wchar_t c) { unsigned char r = 0xFF; diff --git a/xsd/cxx/tree/default-value.hxx b/xsd/xsd/cxx/tree/default-value.hxx index 3937d3a..149982f 100644 --- a/xsd/cxx/tree/default-value.hxx +++ b/xsd/xsd/cxx/tree/default-value.hxx @@ -1,13 +1,13 @@ // file : xsd/cxx/tree/default-value.hxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#ifndef CXX_TREE_DEFAULT_VALUE_HXX -#define CXX_TREE_DEFAULT_VALUE_HXX +#ifndef XSD_CXX_TREE_DEFAULT_VALUE_HXX +#define XSD_CXX_TREE_DEFAULT_VALUE_HXX -#include <xsd-frontend/semantic-graph.hxx> -#include <xsd-frontend/traversal.hxx> +#include <libxsd-frontend/semantic-graph.hxx> +#include <libxsd-frontend/traversal.hxx> -#include <cxx/tree/elements.hxx> +#include <xsd/cxx/tree/elements.hxx> namespace CXX { @@ -15,6 +15,8 @@ namespace CXX { struct IsLiteralValue: IsFundamentalType, Traversal::Complex { + using IsFundamentalType::traverse; + IsLiteralValue (bool& r); virtual void @@ -48,6 +50,9 @@ namespace CXX Context { + using Traversal::NodeDispatcher::dispatch; + using Traversal::EdgeDispatcher::dispatch; + LiteralValue (Context&); String @@ -214,6 +219,9 @@ namespace CXX Context { + using Traversal::NodeDispatcher::dispatch; + using Traversal::EdgeDispatcher::dispatch; + InitValue (Context&); void @@ -352,4 +360,4 @@ namespace CXX } } -#endif // CXX_TREE_DEFAULT_VALUE_HXX +#endif // XSD_CXX_TREE_DEFAULT_VALUE_HXX diff --git a/xsd/cxx/tree/elements.cxx b/xsd/xsd/cxx/tree/elements.cxx index 78281cd..fc080c8 100644 --- a/xsd/cxx/tree/elements.cxx +++ b/xsd/xsd/cxx/tree/elements.cxx @@ -1,7 +1,7 @@ // file : xsd/cxx/tree/elements.cxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#include <cxx/tree/elements.hxx> +#include <xsd/cxx/tree/elements.hxx> namespace CXX { diff --git a/xsd/cxx/tree/elements.hxx b/xsd/xsd/cxx/tree/elements.hxx index 57c3075..4d10def 100644 --- a/xsd/cxx/tree/elements.hxx +++ b/xsd/xsd/cxx/tree/elements.hxx @@ -1,8 +1,8 @@ // file : xsd/cxx/tree/elements.hxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#ifndef CXX_TREE_ELEMENTS_HXX -#define CXX_TREE_ELEMENTS_HXX +#ifndef XSD_CXX_TREE_ELEMENTS_HXX +#define XSD_CXX_TREE_ELEMENTS_HXX #include <map> #include <set> @@ -10,13 +10,13 @@ #include <vector> #include <sstream> -#include <cutl/re.hxx> +#include <libcutl/re.hxx> -#include <types.hxx> +#include <xsd/types.hxx> -#include <cxx/elements.hxx> +#include <xsd/cxx/elements.hxx> -#include <cxx/tree/options.hxx> +#include <xsd/cxx/tree/options.hxx> namespace CXX { @@ -1616,6 +1616,8 @@ namespace CXX Traversal::Attribute, Context { + using Complex::traverse; + // The second version outputs the argument name and stores // in in the base_arg string. // @@ -1776,6 +1778,8 @@ namespace CXX Traversal::Attribute, Context { + using Complex::traverse; + CtorArgsWithoutBase (Context& c, CtorArgType, bool arg, bool first); virtual void @@ -2115,4 +2119,4 @@ namespace CXX } } -#endif // CXX_TREE_ELEMENTS_HXX +#endif // XSD_CXX_TREE_ELEMENTS_HXX diff --git a/xsd/cxx/tree/fundamental-header.hxx b/xsd/xsd/cxx/tree/fundamental-header.hxx index e553d29..0ea82cf 100644 --- a/xsd/cxx/tree/fundamental-header.hxx +++ b/xsd/xsd/cxx/tree/fundamental-header.hxx @@ -1,17 +1,17 @@ // file : xsd/cxx/tree/fundamental-header.hxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#ifndef CXX_TREE_FUNDAMENTAL_HEADER_HXX -#define CXX_TREE_FUNDAMENTAL_HEADER_HXX +#ifndef XSD_CXX_TREE_FUNDAMENTAL_HEADER_HXX +#define XSD_CXX_TREE_FUNDAMENTAL_HEADER_HXX #include <set> #include <vector> #include <algorithm> -#include <xsd-frontend/semantic-graph.hxx> -#include <xsd-frontend/traversal.hxx> +#include <libxsd-frontend/semantic-graph.hxx> +#include <libxsd-frontend/traversal.hxx> -#include <cxx/tree/elements.hxx> +#include <xsd/cxx/tree/elements.hxx> namespace CXX { @@ -76,6 +76,8 @@ namespace CXX Traversal::Fundamental::Entities, Context { + using Namespace::traverse; + FundamentalNamespace (Context& c) : DocumentedNamespace (c), Context (c), @@ -1332,4 +1334,4 @@ namespace CXX } } -#endif // CXX_TREE_FUNDAMENTAL_HEADER_HXX +#endif // XSD_CXX_TREE_FUNDAMENTAL_HEADER_HXX diff --git a/xsd/cxx/tree/generator.cxx b/xsd/xsd/cxx/tree/generator.cxx index edf5523..9782b4d 100644 --- a/xsd/cxx/tree/generator.cxx +++ b/xsd/xsd/cxx/tree/generator.cxx @@ -6,47 +6,47 @@ #include <iostream> #include <fstream> -#include <cutl/re.hxx> -#include <cutl/shared-ptr.hxx> +#include <libcutl/re.hxx> +#include <libcutl/shared-ptr.hxx> -#include <cutl/compiler/code-stream.hxx> -#include <cutl/compiler/cxx-indenter.hxx> -#include <cutl/compiler/sloc-counter.hxx> +#include <libcutl/compiler/code-stream.hxx> +#include <libcutl/compiler/cxx-indenter.hxx> +#include <libcutl/compiler/sloc-counter.hxx> -#include <xsd-frontend/semantic-graph.hxx> -#include <xsd-frontend/generators/dependencies.hxx> +#include <libxsd-frontend/semantic-graph.hxx> +#include <libxsd-frontend/generators/dependencies.hxx> -#include <cxx/tree/generator.hxx> +#include <xsd/version.hxx> -#include <cxx/tree/elements.hxx> +#include <xsd/cxx/tree/generator.hxx> -#include <cxx/tree/counter.hxx> -#include <cxx/tree/validator.hxx> -#include <cxx/tree/name-processor.hxx> -#include <cxx/tree/order-processor.hxx> -#include <cxx/tree/polymorphism-processor.hxx> +#include <xsd/cxx/tree/elements.hxx> -#include <cxx/tree/tree-forward.hxx> -#include <cxx/tree/tree-header.hxx> -#include <cxx/tree/tree-inline.hxx> -#include <cxx/tree/tree-source.hxx> +#include <xsd/cxx/tree/counter.hxx> +#include <xsd/cxx/tree/validator.hxx> +#include <xsd/cxx/tree/name-processor.hxx> +#include <xsd/cxx/tree/order-processor.hxx> +#include <xsd/cxx/tree/polymorphism-processor.hxx> -#include <cxx/tree/parser-header.hxx> -#include <cxx/tree/parser-source.hxx> +#include <xsd/cxx/tree/tree-forward.hxx> +#include <xsd/cxx/tree/tree-header.hxx> +#include <xsd/cxx/tree/tree-inline.hxx> +#include <xsd/cxx/tree/tree-source.hxx> -#include <cxx/tree/stream-header.hxx> -#include <cxx/tree/stream-source.hxx> +#include <xsd/cxx/tree/parser-header.hxx> +#include <xsd/cxx/tree/parser-source.hxx> -#include <cxx/tree/serialization-header.hxx> -#include <cxx/tree/serialization-source.hxx> +#include <xsd/cxx/tree/stream-header.hxx> +#include <xsd/cxx/tree/stream-source.hxx> -#include <cxx/tree/stream-insertion-header.hxx> -#include <cxx/tree/stream-insertion-source.hxx> -#include <cxx/tree/stream-extraction-source.hxx> +#include <xsd/cxx/tree/serialization-header.hxx> +#include <xsd/cxx/tree/serialization-source.hxx> -#include <cxx/tree/options.hxx> +#include <xsd/cxx/tree/stream-insertion-header.hxx> +#include <xsd/cxx/tree/stream-insertion-source.hxx> +#include <xsd/cxx/tree/stream-extraction-source.hxx> -#include "../../../libxsd/xsd/cxx/version.hxx" +#include <xsd/cxx/tree/options.hxx> using namespace std; using namespace cutl; @@ -54,6 +54,8 @@ using namespace XSDFrontend::SemanticGraph; // // +typedef std::wostream WideOutputStream; + typedef std::wifstream WideInputFileStream; typedef std::wofstream WideOutputFileStream; @@ -62,7 +64,7 @@ namespace CXX namespace { char const copyright_gpl[] = - "// Copyright (c) 2005-2020 Code Synthesis Tools CC.\n" + "// Copyright (c) " XSD_COPYRIGHT ".\n" "//\n" "// This program was generated by CodeSynthesis XSD, an XML Schema to\n" "// C++ data binding compiler.\n" @@ -80,29 +82,28 @@ namespace CXX "// along with this program; if not, write to the Free Software\n" "// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\n" "//\n" - "// In addition, as a special exception, Code Synthesis Tools CC gives\n" - "// permission to link this program with the Xerces-C++ library (or with\n" - "// modified versions of Xerces-C++ that use the same license as Xerces-C++),\n" - "// and distribute linked combinations including the two. You must obey\n" - "// the GNU General Public License version 2 in all respects for all of\n" - "// the code used other than Xerces-C++. If you modify this copy of the\n" - "// program, you may extend this exception to your version of the program,\n" - "// but you are not obligated to do so. If you do not wish to do so, delete\n" - "// this exception statement from your version.\n" + "// In addition, as a special exception, Code Synthesis gives permission\n" + "// to link this program with the Xerces-C++ library (or with modified\n" + "// versions of Xerces-C++ that use the same license as Xerces-C++), and\n" + "// distribute linked combinations including the two. You must obey the GNU\n" + "// General Public License version 2 in all respects for all of the code\n" + "// used other than Xerces-C++. If you modify this copy of the program, you\n" + "// may extend this exception to your version of the program, but you are\n" + "// not obligated to do so. If you do not wish to do so, delete this\n" + "// exception statement from your version.\n" "//\n" - "// Furthermore, Code Synthesis Tools CC makes a special exception for\n" - "// the Free/Libre and Open Source Software (FLOSS) which is described\n" - "// in the accompanying FLOSSE file.\n" + "// Furthermore, Code Synthesis makes a special exception for the Free/Libre\n" + "// and Open Source Software (FLOSS) which is described in the accompanying\n" + "// FLOSSE file.\n" "//\n\n"; char const copyright_proprietary[] = - "// Copyright (c) 2005-2020 Code Synthesis Tools CC.\n" + "// Copyright (c) " XSD_COPYRIGHT ".\n" "//\n" "// This program was generated by CodeSynthesis XSD, an XML Schema\n" "// to C++ data binding compiler, in the Proprietary License mode.\n" "// You should have received a proprietary license from Code Synthesis\n" - "// Tools CC prior to generating this code. See the license text for\n" - "// conditions.\n" + "// prior to generating this code. See the license text for conditions.\n" "//\n\n"; } @@ -232,7 +233,7 @@ namespace CXX throw Failed (); } - bool gen_cxx (!ops.generate_dep_only ()); + bool gen_cxx (!ops.generate_dep_only () && !ops.file_list_only ()); // Process ordered types. // @@ -345,9 +346,13 @@ namespace CXX ? "#^(.+?)(\\.[^./\\\\]+)?$#$1" + fwd_suffix + "#" : ops.fwd_regex ()); - Regex dep_expr (ops.dep_regex ().empty () - ? "#^(.+?)(\\.[^./\\\\]+)?$#$1" + dep_suffix + "#" - : ops.dep_regex ()); + // @@ This will blow up if --dep-file value contains backslashes (e.g., + // it's a Windows path). + // + Regex dep_expr ( + ops.dep_regex_specified () ? ops.dep_regex () : + ops.dep_file_specified () ? "#.+#" + ops.dep_file () + "#" : + "#^(.+?)(\\.[^./\\\\]+)?$#$1" + dep_suffix + "#"); if (header && !hxx_expr.match (name)) { @@ -397,7 +402,7 @@ namespace CXX Path hxx_path (hxx_name); Path ixx_path (ixx_name); Path fwd_path (fwd_name); - Path dep_path (dep_name); + Path dep_path (dep_name != "-" ? dep_name : NarrowString ()); Paths cxx_paths; if (source) @@ -458,10 +463,11 @@ namespace CXX if (!out_dir.empty ()) { - hxx_path = out_dir / hxx_path; - ixx_path = out_dir / ixx_path; - fwd_path = out_dir / fwd_path; - dep_path = out_dir / dep_path; + if (!hxx_path.empty ()) hxx_path = out_dir / hxx_path; + if (!ixx_path.empty ()) ixx_path = out_dir / ixx_path; + if (!fwd_path.empty ()) fwd_path = out_dir / fwd_path; + if (!dep_path.empty () && + !dep_path.absolute ()) dep_path = out_dir / dep_path; for (Paths::iterator i (cxx_paths.begin ()); i != cxx_paths.end (); ++i) @@ -473,93 +479,116 @@ namespace CXX WideOutputFileStream hxx; WideOutputFileStream ixx; WideOutputFileStream fwd; - WideOutputFileStream dep; + WideOutputFileStream depf; // See dep below. WideOutputFileStreams cxx; // DEP // if (gen_dep) { - dep.open (dep_path.string ().c_str (), ios_base::out); - - if (!dep.is_open ()) + if (!dep_path.empty ()) { - wcerr << dep_path << ": error: unable to open in write mode" << endl; - throw Failed (); + depf.open (dep_path.string ().c_str (), ios_base::out); + + if (!depf.is_open ()) + { + wcerr << dep_path << ": error: unable to open in write mode" + << endl; + throw Failed (); + } + + unlinks.add (dep_path); } - unlinks.add (dep_path); - file_list.push_back (dep_path.string ()); + // Note: not adding to file_list. } + WideOutputStream& dep (gen_dep && !dep_path.empty () ? depf : wcout); + // FWD // - if (gen_cxx && forward) + if (forward) { - fwd.open (fwd_path.string ().c_str (), ios_base::out); - - if (!fwd.is_open ()) + if (gen_cxx) { - wcerr << fwd_path << ": error: unable to open in write mode" << endl; - throw Failed (); + fwd.open (fwd_path.string ().c_str (), ios_base::out); + + if (!fwd.is_open ()) + { + wcerr << fwd_path << ": error: unable to open in write mode" << endl; + throw Failed (); + } + + unlinks.add (fwd_path); } - unlinks.add (fwd_path); file_list.push_back (fwd_path.string ()); } // HXX // - if (gen_cxx && header) + if (header) { - hxx.open (hxx_path.string ().c_str (), ios_base::out); - - if (!hxx.is_open ()) + if (gen_cxx) { - wcerr << hxx_path << ": error: unable to open in write mode" << endl; - throw Failed (); + hxx.open (hxx_path.string ().c_str (), ios_base::out); + + if (!hxx.is_open ()) + { + wcerr << hxx_path << ": error: unable to open in write mode" << endl; + throw Failed (); + } + + unlinks.add (hxx_path); } - unlinks.add (hxx_path); file_list.push_back (hxx_path.string ()); } // IXX // - if (gen_cxx && inline_) + if (inline_) { - ixx.open (ixx_path.string ().c_str (), ios_base::out); - - if (!ixx.is_open ()) + if (gen_cxx) { - wcerr << ixx_path << ": error: unable to open in write mode" << endl; - throw Failed (); + ixx.open (ixx_path.string ().c_str (), ios_base::out); + + if (!ixx.is_open ()) + { + wcerr << ixx_path << ": error: unable to open in write mode" << endl; + throw Failed (); + } + + unlinks.add (ixx_path); } - unlinks.add (ixx_path); file_list.push_back (ixx_path.string ()); } // CXX // - if (gen_cxx && source) + if (source) { for (Paths::iterator i (cxx_paths.begin ()); i != cxx_paths.end (); ++i) { - shared_ptr<WideOutputFileStream> s ( - new (shared) WideOutputFileStream ( - i->string ().c_str (), ios_base::out)); - - if (!s->is_open ()) + if (gen_cxx) { - wcerr << *i << ": error: unable to open in write mode" << endl; - throw Failed (); + shared_ptr<WideOutputFileStream> s ( + new (shared) WideOutputFileStream ( + i->string ().c_str (), ios_base::out)); + + if (!s->is_open ()) + { + wcerr << *i << ": error: unable to open in write mode" << endl; + throw Failed (); + } + + cxx.push_back (s); + unlinks.add (*i); } - unlinks.add (*i); file_list.push_back (i->string ()); - cxx.push_back (s); } } @@ -668,7 +697,8 @@ namespace CXX i != cxx_paths.end (); ++i) target += " \\\n" + i->string (); - target += " \\\n" + dep_path.string (); + if (!dep_path.empty ()) + target += " \\\n" + dep_path.string (); } dep << target.c_str () << ':'; @@ -769,7 +799,7 @@ namespace CXX // fwd << "#include <xsd/cxx/version.hxx>" << endl << endl - << "#if (XSD_INT_VERSION != " << XSD_INT_VERSION << "L)" << endl + << "#if (LIBXSD_VERSION != " << XSD_VERSION << "L)" << endl << "#error XSD runtime version mismatch" << endl << "#endif" << endl << endl; @@ -894,7 +924,7 @@ namespace CXX // hxx << "#include <xsd/cxx/config.hxx>" << endl << endl - << "#if (XSD_INT_VERSION != " << XSD_INT_VERSION << "L)" << endl + << "#if (LIBXSD_VERSION != " << XSD_VERSION << "L)" << endl << "#error XSD runtime version mismatch" << endl << "#endif" << endl << endl; @@ -928,19 +958,16 @@ namespace CXX } } - if (inline_) - { - hxx << "#ifndef XSD_DONT_INCLUDE_INLINE" << endl - << "#include " << ctx.process_include_path (ixx_name) << endl - << "#endif // XSD_DONT_INCLUDE_INLINE" << endl - << endl; - } - hxx << "#include <xsd/cxx/post.hxx>" << endl << endl; // Copy epilogue. // + // Note that it goes before the inline file in case it defines + // something (such as a custom type) which is needed by this file. + // And if something in the epilogue needs something from the inline + // file, then it should be the inline rather than header epilogue. + // hxx << "// Begin epilogue." << endl << "//" << endl; @@ -951,6 +978,14 @@ namespace CXX << "// End epilogue." << endl << endl; + if (inline_) + { + hxx << "#ifndef XSD_DONT_INCLUDE_INLINE" << endl + << "#include " << ctx.process_include_path (ixx_name) << endl + << "#endif // XSD_DONT_INCLUDE_INLINE" << endl + << endl; + } + hxx << "#endif // " << guard << endl; if (show_sloc) @@ -999,6 +1034,9 @@ namespace CXX << "// End prologue." << endl << endl; + ixx << "#include <xsd/cxx/pre.hxx>" << endl + << endl; + // Generate. // { @@ -1006,6 +1044,9 @@ namespace CXX generate_tree_inline (ctx, 1, 0); } + ixx << "#include <xsd/cxx/post.hxx>" << endl + << endl; + // Copy epilogue. // ixx << "// Begin epilogue." << endl diff --git a/xsd/cxx/tree/generator.hxx b/xsd/xsd/cxx/tree/generator.hxx index e3da0c3..a9b96fe 100644 --- a/xsd/cxx/tree/generator.hxx +++ b/xsd/xsd/cxx/tree/generator.hxx @@ -1,17 +1,17 @@ // file : xsd/cxx/tree/generator.hxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#ifndef CXX_TREE_GENERATOR_HXX -#define CXX_TREE_GENERATOR_HXX +#ifndef XSD_CXX_TREE_GENERATOR_HXX +#define XSD_CXX_TREE_GENERATOR_HXX -#include <xsd-frontend/semantic-graph/elements.hxx> // Path -#include <xsd-frontend/semantic-graph/schema.hxx> +#include <libxsd-frontend/semantic-graph/elements.hxx> // Path +#include <libxsd-frontend/semantic-graph/schema.hxx> -#include <xsd.hxx> -#include <types.hxx> +#include <xsd/xsd.hxx> +#include <xsd/types.hxx> -#include <cxx/literal-map.hxx> -#include <cxx/tree/options.hxx> +#include <xsd/cxx/literal-map.hxx> +#include <xsd/cxx/tree/options.hxx> namespace CXX { @@ -41,4 +41,4 @@ namespace CXX } } -#endif // CXX_TREE_GENERATOR_HXX +#endif // XSD_CXX_TREE_GENERATOR_HXX diff --git a/xsd/cxx/tree/name-processor.cxx b/xsd/xsd/cxx/tree/name-processor.cxx index 51f058c..325870a 100644 --- a/xsd/cxx/tree/name-processor.cxx +++ b/xsd/xsd/cxx/tree/name-processor.cxx @@ -7,10 +7,10 @@ #include <sstream> #include <iostream> -#include <cutl/re.hxx> +#include <libcutl/re.hxx> -#include <cxx/tree/default-value.hxx> -#include <cxx/tree/name-processor.hxx> +#include <xsd/cxx/tree/default-value.hxx> +#include <xsd/cxx/tree/name-processor.hxx> using namespace std; @@ -129,6 +129,12 @@ namespace CXX accessor_regex.push_back ("/([^,]+),([^,]+),([^,]+)/\\l$1\\u$2\\u$3/"); accessor_regex.push_back ("/([^,]+)/\\l$1/"); } + else if (fn == "ucc") + { + accessor_regex.push_back ("/([^,]+),([^,]+)/\\u$1\\u$2/"); + accessor_regex.push_back ("/([^,]+),([^,]+),([^,]+)/\\u$1\\u$2\\u$3/"); + accessor_regex.push_back ("/([^,]+)/\\u$1/"); + } else { // Java: add get. @@ -169,6 +175,11 @@ namespace CXX modifier_regex.push_back ("/([^,]+),([^,]+)/\\l$1\\u$2/"); modifier_regex.push_back ("/([^,]+)/\\l$1/"); } + else if (fn == "ucc") + { + modifier_regex.push_back ("/([^,]+),([^,]+)/\\u$1\\u$2/"); + modifier_regex.push_back ("/([^,]+)/\\u$1/"); + } else { // Java: add set. @@ -202,6 +213,10 @@ namespace CXX { parser_regex.push_back ("/(.+)/\\l$1/"); } + else if (fn == "ucc") + { + parser_regex.push_back ("/(.+)/\\u$1/"); + } else if (fn == "java") { // Java: add parse. @@ -219,6 +234,10 @@ namespace CXX { serializer_regex.push_back ("/(.+)/\\l$1/"); } + else if (fn == "ucc") + { + serializer_regex.push_back ("/(.+)/\\u$1/"); + } else if (fn == "java") { // Java: add serialize. @@ -244,6 +263,11 @@ namespace CXX const_regex.push_back ("/([^,]+),([^,]+),([^,]+)/\\l$1_\\u$2_\\u$3/"); const_regex.push_back ("/([^,]+),([^,]+)/\\l$1\\u$2/"); } + else if (fn == "ucc") + { + const_regex.push_back ("/([^,]+),([^,]+),([^,]+)/\\u$1_\\u$2_\\u$3/"); + const_regex.push_back ("/([^,]+),([^,]+)/\\u$1\\u$2/"); + } else { // Java: all uppercase. @@ -1808,6 +1832,8 @@ namespace CXX Context { + using Namespace::traverse; + FundamentalNamespace (Context& c) : Context (c) { @@ -2171,6 +2197,8 @@ namespace CXX if (fn == "knr") n.context ().set ("tree-node-key", String ("tree_node_key")); + else if (fn == "ucc") + n.context ().set ("tree-node-key", String ("TreeNodeKey")); else n.context ().set ("tree-node-key", String ("treeNodeKey")); diff --git a/xsd/cxx/tree/name-processor.hxx b/xsd/xsd/cxx/tree/name-processor.hxx index 62b3af4..632b05e 100644 --- a/xsd/cxx/tree/name-processor.hxx +++ b/xsd/xsd/cxx/tree/name-processor.hxx @@ -1,13 +1,13 @@ // file : xsd/cxx/tree/name-processor.hxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#ifndef CXX_TREE_NAME_PROCESSOR_HXX -#define CXX_TREE_NAME_PROCESSOR_HXX +#ifndef XSD_CXX_TREE_NAME_PROCESSOR_HXX +#define XSD_CXX_TREE_NAME_PROCESSOR_HXX -#include <types.hxx> +#include <xsd/types.hxx> -#include <cxx/tree/elements.hxx> -#include <cxx/tree/options.hxx> +#include <xsd/cxx/tree/elements.hxx> +#include <xsd/cxx/tree/options.hxx> namespace CXX { @@ -25,4 +25,4 @@ namespace CXX } } -#endif // CXX_TREE_NAME_PROCESSOR_HXX +#endif // XSD_CXX_TREE_NAME_PROCESSOR_HXX diff --git a/xsd/cxx/tree/options.cli b/xsd/xsd/cxx/tree/options.cli index 08c9be3..0230429 100644 --- a/xsd/cxx/tree/options.cli +++ b/xsd/xsd/cxx/tree/options.cli @@ -3,9 +3,9 @@ include <cstddef>; // std::size_t -include <types.hxx>; // NarrowString, NarrowStrings +include <xsd/types.hxx>; // NarrowString, NarrowStrings -include <cxx/options.cli>; +include <xsd/cxx/options.cli>; namespace CXX { @@ -257,9 +257,9 @@ namespace CXX { "<style>", "Specify the function naming convention that should be used in the - generated code. Valid styles are \cb{knr} (default), \cb{lcc}, and - \cb{java}. See the NAMING CONVENTION section below for more - information." + generated code. Valid styles are \cb{knr} (default), \cb{lcc}, + \cb{ucc}, and \cb{java}. See the NAMING CONVENTION section below + for more information." }; NarrowStrings --type-regex diff --git a/xsd/cxx/tree/order-processor.cxx b/xsd/xsd/cxx/tree/order-processor.cxx index 234f427..ccc3dc5 100644 --- a/xsd/cxx/tree/order-processor.cxx +++ b/xsd/xsd/cxx/tree/order-processor.cxx @@ -3,11 +3,11 @@ #include <iostream> -#include <cxx/tree/elements.hxx> -#include <cxx/tree/order-processor.hxx> +#include <xsd/cxx/tree/elements.hxx> +#include <xsd/cxx/tree/order-processor.hxx> -#include <xsd-frontend/semantic-graph.hxx> -#include <xsd-frontend/traversal.hxx> +#include <libxsd-frontend/semantic-graph.hxx> +#include <libxsd-frontend/traversal.hxx> using namespace std; diff --git a/xsd/cxx/tree/order-processor.hxx b/xsd/xsd/cxx/tree/order-processor.hxx index bde6c32..868547d 100644 --- a/xsd/cxx/tree/order-processor.hxx +++ b/xsd/xsd/cxx/tree/order-processor.hxx @@ -1,15 +1,15 @@ // file : xsde/cxx/tree/order-processor.hxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#ifndef CXX_TREE_ORDER_PROCESSOR_HXX -#define CXX_TREE_ORDER_PROCESSOR_HXX +#ifndef XSD_CXX_TREE_ORDER_PROCESSOR_HXX +#define XSD_CXX_TREE_ORDER_PROCESSOR_HXX -#include <xsd-frontend/semantic-graph.hxx> +#include <libxsd-frontend/semantic-graph.hxx> -#include <xsd.hxx> -#include <types.hxx> +#include <xsd/xsd.hxx> +#include <xsd/types.hxx> -#include <cxx/tree/options.hxx> +#include <xsd/cxx/tree/options.hxx> namespace CXX { @@ -26,4 +26,4 @@ namespace CXX } } -#endif // CXX_TREE_ORDER_PROCESSOR_HXX +#endif // XSD_CXX_TREE_ORDER_PROCESSOR_HXX diff --git a/xsd/cxx/tree/parser-header.cxx b/xsd/xsd/cxx/tree/parser-header.cxx index 4d76f2c..9ef9e89 100644 --- a/xsd/cxx/tree/parser-header.cxx +++ b/xsd/xsd/cxx/tree/parser-header.cxx @@ -1,10 +1,10 @@ // file : xsd/cxx/tree/parser-header.cxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#include <cxx/tree/parser-header.hxx> +#include <xsd/cxx/tree/parser-header.hxx> -#include <xsd-frontend/semantic-graph.hxx> -#include <xsd-frontend/traversal.hxx> +#include <libxsd-frontend/semantic-graph.hxx> +#include <libxsd-frontend/traversal.hxx> namespace CXX { diff --git a/xsd/cxx/tree/parser-header.hxx b/xsd/xsd/cxx/tree/parser-header.hxx index 6942190..b7860c4 100644 --- a/xsd/cxx/tree/parser-header.hxx +++ b/xsd/xsd/cxx/tree/parser-header.hxx @@ -1,10 +1,10 @@ // file : xsd/cxx/tree/parser-header.hxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#ifndef CXX_TREE_PARSER_HEADER_HXX -#define CXX_TREE_PARSER_HEADER_HXX +#ifndef XSD_CXX_TREE_PARSER_HEADER_HXX +#define XSD_CXX_TREE_PARSER_HEADER_HXX -#include <cxx/tree/elements.hxx> +#include <xsd/cxx/tree/elements.hxx> namespace CXX @@ -16,4 +16,4 @@ namespace CXX } } -#endif // CXX_TREE_PARSER_HEADER_HXX +#endif // XSD_CXX_TREE_PARSER_HEADER_HXX diff --git a/xsd/cxx/tree/parser-source.cxx b/xsd/xsd/cxx/tree/parser-source.cxx index e00997b..cee5ea6 100644 --- a/xsd/cxx/tree/parser-source.cxx +++ b/xsd/xsd/cxx/tree/parser-source.cxx @@ -1,10 +1,10 @@ // file : xsd/cxx/tree/parser-source.cxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#include <cxx/tree/parser-source.hxx> +#include <xsd/cxx/tree/parser-source.hxx> -#include <xsd-frontend/semantic-graph.hxx> -#include <xsd-frontend/traversal.hxx> +#include <libxsd-frontend/semantic-graph.hxx> +#include <libxsd-frontend/traversal.hxx> namespace CXX { diff --git a/xsd/cxx/tree/parser-source.hxx b/xsd/xsd/cxx/tree/parser-source.hxx index 8a52cd2..1bb70d9 100644 --- a/xsd/cxx/tree/parser-source.hxx +++ b/xsd/xsd/cxx/tree/parser-source.hxx @@ -1,10 +1,10 @@ // file : xsd/cxx/tree/parser-source.hxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#ifndef CXX_TREE_PARSER_SOURCE_HXX -#define CXX_TREE_PARSER_SOURCE_HXX +#ifndef XSD_CXX_TREE_PARSER_SOURCE_HXX +#define XSD_CXX_TREE_PARSER_SOURCE_HXX -#include <cxx/tree/elements.hxx> +#include <xsd/cxx/tree/elements.hxx> namespace CXX { @@ -15,4 +15,4 @@ namespace CXX } } -#endif // CXX_TREE_PARSER_SOURCE_HXX +#endif // XSD_CXX_TREE_PARSER_SOURCE_HXX diff --git a/xsd/cxx/tree/polymorphism-processor.cxx b/xsd/xsd/cxx/tree/polymorphism-processor.cxx index 2788a73..4d07c69 100644 --- a/xsd/cxx/tree/polymorphism-processor.cxx +++ b/xsd/xsd/cxx/tree/polymorphism-processor.cxx @@ -3,11 +3,11 @@ #include <iostream> -#include <cxx/tree/elements.hxx> -#include <cxx/tree/polymorphism-processor.hxx> +#include <xsd/cxx/tree/elements.hxx> +#include <xsd/cxx/tree/polymorphism-processor.hxx> -#include <xsd-frontend/semantic-graph.hxx> -#include <xsd-frontend/traversal.hxx> +#include <libxsd-frontend/semantic-graph.hxx> +#include <libxsd-frontend/traversal.hxx> using namespace std; diff --git a/xsd/cxx/tree/polymorphism-processor.hxx b/xsd/xsd/cxx/tree/polymorphism-processor.hxx index 08c2502..88019a8 100644 --- a/xsd/cxx/tree/polymorphism-processor.hxx +++ b/xsd/xsd/cxx/tree/polymorphism-processor.hxx @@ -1,15 +1,15 @@ // file : xsde/cxx/tree/polymorphism-processor.hxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#ifndef CXX_TREE_POLYMORPHISM_PROCESSOR_HXX -#define CXX_TREE_POLYMORPHISM_PROCESSOR_HXX +#ifndef XSD_CXX_TREE_POLYMORPHISM_PROCESSOR_HXX +#define XSD_CXX_TREE_POLYMORPHISM_PROCESSOR_HXX -#include <xsd-frontend/semantic-graph.hxx> +#include <libxsd-frontend/semantic-graph.hxx> -#include <xsd.hxx> -#include <types.hxx> +#include <xsd/xsd.hxx> +#include <xsd/types.hxx> -#include <cxx/tree/options.hxx> +#include <xsd/cxx/tree/options.hxx> namespace CXX { @@ -27,4 +27,4 @@ namespace CXX } } -#endif // CXX_TREE_POLYMORPHISM_PROCESSOR_HXX +#endif // XSD_CXX_TREE_POLYMORPHISM_PROCESSOR_HXX diff --git a/xsd/cxx/tree/serialization-header.cxx b/xsd/xsd/cxx/tree/serialization-header.cxx index 729d2b3..5434441 100644 --- a/xsd/cxx/tree/serialization-header.cxx +++ b/xsd/xsd/cxx/tree/serialization-header.cxx @@ -1,10 +1,10 @@ // file : xsd/cxx/tree/serialization-header.cxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#include <cxx/tree/serialization-header.hxx> +#include <xsd/cxx/tree/serialization-header.hxx> -#include <xsd-frontend/semantic-graph.hxx> -#include <xsd-frontend/traversal.hxx> +#include <libxsd-frontend/semantic-graph.hxx> +#include <libxsd-frontend/traversal.hxx> namespace CXX { diff --git a/xsd/cxx/tree/serialization-header.hxx b/xsd/xsd/cxx/tree/serialization-header.hxx index beef6c8..08c58ab 100644 --- a/xsd/cxx/tree/serialization-header.hxx +++ b/xsd/xsd/cxx/tree/serialization-header.hxx @@ -1,10 +1,10 @@ // file : xsd/cxx/tree/serialization-header.hxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#ifndef CXX_TREE_SERIALIZATION_HEADER_HXX -#define CXX_TREE_SERIALIZATION_HEADER_HXX +#ifndef XSD_CXX_TREE_SERIALIZATION_HEADER_HXX +#define XSD_CXX_TREE_SERIALIZATION_HEADER_HXX -#include <cxx/tree/elements.hxx> +#include <xsd/cxx/tree/elements.hxx> namespace CXX { @@ -15,4 +15,4 @@ namespace CXX } } -#endif // CXX_TREE_SERIALIZATION_HEADER_HXX +#endif // XSD_CXX_TREE_SERIALIZATION_HEADER_HXX diff --git a/xsd/cxx/tree/serialization-source.cxx b/xsd/xsd/cxx/tree/serialization-source.cxx index aa6f1ef..08b81d6 100644 --- a/xsd/cxx/tree/serialization-source.cxx +++ b/xsd/xsd/cxx/tree/serialization-source.cxx @@ -1,10 +1,10 @@ // file : xsd/cxx/tree/serialization-source.cxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#include <cxx/tree/serialization-source.hxx> +#include <xsd/cxx/tree/serialization-source.hxx> -#include <xsd-frontend/semantic-graph.hxx> -#include <xsd-frontend/traversal.hxx> +#include <libxsd-frontend/semantic-graph.hxx> +#include <libxsd-frontend/traversal.hxx> namespace CXX { @@ -334,6 +334,10 @@ namespace CXX { // sequence // + // Always pass the sequence element reference to typeid() to + // suppress the Clang's 'expression with side effects will be + // evaluated despite being used as an operand to typeid' warning. + // if (ordered) os << "const " << type << "& x (i." << aname << " ()[b->index]);" @@ -343,13 +347,12 @@ namespace CXX << "b (i." << aname << " ().begin ()), " << "n (i." << aname << " ().end ());" << endl << "b != n; ++b)" - << "{"; - - char const* x (ordered ? "x" : "*b"); + << "{" + << "const " << type << "& x (*b);" << endl; if (poly) { - os << "if (typeid (" << type << ") == typeid (" << x << "))" + os << "if (typeid (" << type << ") == typeid (x))" << "{" << xerces_ns << "::DOMElement& s (" << endl << "::xsd::cxx::xml::dom::create_element (" << endl @@ -357,14 +360,14 @@ namespace CXX << (ns ? strlit (ns) + L",\n" : L"") << "e));" << endl - << "s << " << x << ";" + << "s << x;" << "}" << "else" << endl << "tsm.serialize (" << endl << strlit (e.name ()) << "," << endl << strlit (ns) << "," << endl << (e.global_p () ? "true" : "false") << ", " << - (e.qualified_p () ? "true" : "false") << ", e, " << x << ");"; + (e.qualified_p () ? "true" : "false") << ", e, x);"; } else { @@ -379,17 +382,17 @@ namespace CXX { case st_other: { - os << "s << " << x << ";"; + os << "s << x;"; break; } case st_double: { - os << "s << " << as_double_type << " (" << x << ");"; + os << "s << " << as_double_type << " (x);"; break; } case st_decimal: { - os << "s << " << as_decimal_type << " (" << x << ");"; + os << "s << " << as_decimal_type << " (x);"; break; } } @@ -800,7 +803,7 @@ namespace CXX { bool o (ordered_p (c)); - size_t start, count; + size_t start (0), count (0); if (o) { @@ -996,8 +999,25 @@ namespace CXX virtual void traverse (Type& e) { + // Similar to parsing, we cannot just omit this element if it's + // abstract because it may serve as a "link" between the root of the + // substitution group and a non-abstract element that uses this + // element as its root (see + // element_serializer_map::find_substitution() for details). + // if (polymorphic && e.substitutes_p ()) { + SemanticGraph::Type& t (e.type ()); + + // Check if this element is abstract. + // + bool abst; + { + SemanticGraph::Complex* tc; + abst = (tc = dynamic_cast<SemanticGraph::Complex*> (&t)) != 0 && + tc->abstract_p (); + } + Type& r (e.substitutes ().root ()); String const& name (ename (e)); @@ -1013,7 +1033,18 @@ namespace CXX << strlit (r.name ()) << "," << endl << strlit (r.namespace_ ().name ()) << "," << endl << strlit (e.name ()) << "," << endl - << strlit (e.namespace_ ().name ()) << ");" + << strlit (e.namespace_ ().name ()) << "," << endl; + + if (abst) + os << "0"; + else + { + os << "&::xsd::cxx::tree::serializer_impl< "; + belongs (e, belongs_); + os << " >"; + } + + os << ");" << endl << endl; } diff --git a/xsd/cxx/tree/serialization-source.hxx b/xsd/xsd/cxx/tree/serialization-source.hxx index 7580cf8..75e57f3 100644 --- a/xsd/cxx/tree/serialization-source.hxx +++ b/xsd/xsd/cxx/tree/serialization-source.hxx @@ -1,10 +1,10 @@ // file : xsd/cxx/tree/serialization-source.hxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#ifndef CXX_TREE_SERIALIZATION_SOURCE_HXX -#define CXX_TREE_SERIALIZATION_SOURCE_HXX +#ifndef XSD_CXX_TREE_SERIALIZATION_SOURCE_HXX +#define XSD_CXX_TREE_SERIALIZATION_SOURCE_HXX -#include <cxx/tree/elements.hxx> +#include <xsd/cxx/tree/elements.hxx> namespace CXX { @@ -15,4 +15,4 @@ namespace CXX } } -#endif // CXX_TREE_SERIALIZATION_SOURCE_HXX +#endif // XSD_CXX_TREE_SERIALIZATION_SOURCE_HXX diff --git a/xsd/cxx/tree/stream-extraction-source.cxx b/xsd/xsd/cxx/tree/stream-extraction-source.cxx index a5b195b..5a5ed66 100644 --- a/xsd/cxx/tree/stream-extraction-source.cxx +++ b/xsd/xsd/cxx/tree/stream-extraction-source.cxx @@ -1,10 +1,10 @@ // file : xsd/cxx/tree/stream-extraction-source.cxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#include <cxx/tree/stream-extraction-source.hxx> +#include <xsd/cxx/tree/stream-extraction-source.hxx> -#include <xsd-frontend/semantic-graph.hxx> -#include <xsd-frontend/traversal.hxx> +#include <libxsd-frontend/semantic-graph.hxx> +#include <libxsd-frontend/traversal.hxx> namespace CXX { diff --git a/xsd/cxx/tree/stream-extraction-source.hxx b/xsd/xsd/cxx/tree/stream-extraction-source.hxx index 29e33f8..8b58491 100644 --- a/xsd/cxx/tree/stream-extraction-source.hxx +++ b/xsd/xsd/cxx/tree/stream-extraction-source.hxx @@ -1,10 +1,10 @@ // file : xsd/cxx/tree/stream-extraction-source.hxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#ifndef CXX_TREE_EXTRACTION_SOURCE_HXX -#define CXX_TREE_EXTRACTION_SOURCE_HXX +#ifndef XSD_CXX_TREE_EXTRACTION_SOURCE_HXX +#define XSD_CXX_TREE_EXTRACTION_SOURCE_HXX -#include <cxx/tree/elements.hxx> +#include <xsd/cxx/tree/elements.hxx> namespace CXX { @@ -15,4 +15,4 @@ namespace CXX } } -#endif // CXX_TREE_EXTRACTION_SOURCE_HXX +#endif // XSD_CXX_TREE_EXTRACTION_SOURCE_HXX diff --git a/xsd/cxx/tree/stream-header.cxx b/xsd/xsd/cxx/tree/stream-header.cxx index fcb18d1..c8243c9 100644 --- a/xsd/cxx/tree/stream-header.cxx +++ b/xsd/xsd/cxx/tree/stream-header.cxx @@ -1,10 +1,10 @@ // file : xsd/cxx/tree/stream-header.cxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#include <cxx/tree/stream-header.hxx> +#include <xsd/cxx/tree/stream-header.hxx> -#include <xsd-frontend/semantic-graph.hxx> -#include <xsd-frontend/traversal.hxx> +#include <libxsd-frontend/semantic-graph.hxx> +#include <libxsd-frontend/traversal.hxx> namespace CXX { diff --git a/xsd/cxx/tree/stream-header.hxx b/xsd/xsd/cxx/tree/stream-header.hxx index 18d2eef..58481c2 100644 --- a/xsd/cxx/tree/stream-header.hxx +++ b/xsd/xsd/cxx/tree/stream-header.hxx @@ -1,10 +1,10 @@ // file : xsd/cxx/tree/stream-header.hxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#ifndef CXX_TREE_STREAM_HEADER_HXX -#define CXX_TREE_STREAM_HEADER_HXX +#ifndef XSD_CXX_TREE_STREAM_HEADER_HXX +#define XSD_CXX_TREE_STREAM_HEADER_HXX -#include <cxx/tree/elements.hxx> +#include <xsd/cxx/tree/elements.hxx> namespace CXX { @@ -15,4 +15,4 @@ namespace CXX } } -#endif // CXX_TREE_STREAM_HEADER_HXX +#endif // XSD_CXX_TREE_STREAM_HEADER_HXX diff --git a/xsd/cxx/tree/stream-insertion-header.cxx b/xsd/xsd/cxx/tree/stream-insertion-header.cxx index 4c1d88e..9eb4bc4 100644 --- a/xsd/cxx/tree/stream-insertion-header.cxx +++ b/xsd/xsd/cxx/tree/stream-insertion-header.cxx @@ -1,10 +1,10 @@ // file : xsd/cxx/tree/stream-insertion-header.cxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#include <cxx/tree/stream-insertion-header.hxx> +#include <xsd/cxx/tree/stream-insertion-header.hxx> -#include <xsd-frontend/semantic-graph.hxx> -#include <xsd-frontend/traversal.hxx> +#include <libxsd-frontend/semantic-graph.hxx> +#include <libxsd-frontend/traversal.hxx> namespace CXX { diff --git a/xsd/cxx/tree/stream-insertion-header.hxx b/xsd/xsd/cxx/tree/stream-insertion-header.hxx index 5bf8f26..597bea0 100644 --- a/xsd/cxx/tree/stream-insertion-header.hxx +++ b/xsd/xsd/cxx/tree/stream-insertion-header.hxx @@ -1,10 +1,10 @@ // file : xsd/cxx/tree/stream-insertion-header.hxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#ifndef CXX_TREE_STREAM_INSERTION_HEADER_HXX -#define CXX_TREE_STREAM_INSERTION_HEADER_HXX +#ifndef XSD_CXX_TREE_STREAM_INSERTION_HEADER_HXX +#define XSD_CXX_TREE_STREAM_INSERTION_HEADER_HXX -#include <cxx/tree/elements.hxx> +#include <xsd/cxx/tree/elements.hxx> namespace CXX { @@ -15,4 +15,4 @@ namespace CXX } } -#endif // CXX_TREE_STREAM_INSERTION_HEADER_HXX +#endif // XSD_CXX_TREE_STREAM_INSERTION_HEADER_HXX diff --git a/xsd/cxx/tree/stream-insertion-source.cxx b/xsd/xsd/cxx/tree/stream-insertion-source.cxx index 7f00c76..08391ef 100644 --- a/xsd/cxx/tree/stream-insertion-source.cxx +++ b/xsd/xsd/cxx/tree/stream-insertion-source.cxx @@ -1,10 +1,10 @@ // file : xsd/cxx/tree/stream-insertion-source.cxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#include <cxx/tree/stream-insertion-source.hxx> +#include <xsd/cxx/tree/stream-insertion-source.hxx> -#include <xsd-frontend/semantic-graph.hxx> -#include <xsd-frontend/traversal.hxx> +#include <libxsd-frontend/semantic-graph.hxx> +#include <libxsd-frontend/traversal.hxx> namespace CXX { diff --git a/xsd/cxx/tree/stream-insertion-source.hxx b/xsd/xsd/cxx/tree/stream-insertion-source.hxx index ef832db..ace8bf6 100644 --- a/xsd/cxx/tree/stream-insertion-source.hxx +++ b/xsd/xsd/cxx/tree/stream-insertion-source.hxx @@ -1,10 +1,10 @@ // file : xsd/cxx/tree/stream-insertion-source.hxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#ifndef CXX_TREE_INSERTION_SOURCE_HXX -#define CXX_TREE_INSERTION_SOURCE_HXX +#ifndef XSD_CXX_TREE_INSERTION_SOURCE_HXX +#define XSD_CXX_TREE_INSERTION_SOURCE_HXX -#include <cxx/tree/elements.hxx> +#include <xsd/cxx/tree/elements.hxx> namespace CXX { @@ -15,4 +15,4 @@ namespace CXX } } -#endif // CXX_TREE_INSERTION_SOURCE_HXX +#endif // XSD_CXX_TREE_INSERTION_SOURCE_HXX diff --git a/xsd/cxx/tree/stream-source.cxx b/xsd/xsd/cxx/tree/stream-source.cxx index a3572ef..eeb3ca3 100644 --- a/xsd/cxx/tree/stream-source.cxx +++ b/xsd/xsd/cxx/tree/stream-source.cxx @@ -1,10 +1,10 @@ // file : xsd/cxx/tree/stream-source.cxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#include <cxx/tree/stream-source.hxx> +#include <xsd/cxx/tree/stream-source.hxx> -#include <xsd-frontend/semantic-graph.hxx> -#include <xsd-frontend/traversal.hxx> +#include <libxsd-frontend/semantic-graph.hxx> +#include <libxsd-frontend/traversal.hxx> namespace CXX { diff --git a/xsd/cxx/tree/stream-source.hxx b/xsd/xsd/cxx/tree/stream-source.hxx index f095d9e..b2b4d5d 100644 --- a/xsd/cxx/tree/stream-source.hxx +++ b/xsd/xsd/cxx/tree/stream-source.hxx @@ -1,10 +1,10 @@ // file : xsd/cxx/tree/stream-source.hxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#ifndef CXX_TREE_STREAM_SOURCE_HXX -#define CXX_TREE_STREAM_SOURCE_HXX +#ifndef XSD_CXX_TREE_STREAM_SOURCE_HXX +#define XSD_CXX_TREE_STREAM_SOURCE_HXX -#include <cxx/tree/elements.hxx> +#include <xsd/cxx/tree/elements.hxx> namespace CXX { @@ -15,4 +15,4 @@ namespace CXX } } -#endif // CXX_TREE_STREAM_SOURCE_HXX +#endif // XSD_CXX_TREE_STREAM_SOURCE_HXX diff --git a/xsd/cxx/tree/tree-forward.cxx b/xsd/xsd/cxx/tree/tree-forward.cxx index 1bea79d..b715abe 100644 --- a/xsd/cxx/tree/tree-forward.cxx +++ b/xsd/xsd/cxx/tree/tree-forward.cxx @@ -1,11 +1,11 @@ // file : xsd/cxx/tree/tree-forward.cxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#include <cxx/tree/tree-forward.hxx> -#include <cxx/tree/fundamental-header.hxx> +#include <xsd/cxx/tree/tree-forward.hxx> +#include <xsd/cxx/tree/fundamental-header.hxx> -#include <xsd-frontend/semantic-graph.hxx> -#include <xsd-frontend/traversal.hxx> +#include <libxsd-frontend/semantic-graph.hxx> +#include <libxsd-frontend/traversal.hxx> namespace CXX { diff --git a/xsd/cxx/tree/tree-forward.hxx b/xsd/xsd/cxx/tree/tree-forward.hxx index bd3c4f0..0610999 100644 --- a/xsd/cxx/tree/tree-forward.hxx +++ b/xsd/xsd/cxx/tree/tree-forward.hxx @@ -1,10 +1,10 @@ // file : xsd/cxx/tree/tree-forward.hxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#ifndef CXX_TREE_TREE_FORWARD_HXX -#define CXX_TREE_TREE_FORWARD_HXX +#ifndef XSD_CXX_TREE_TREE_FORWARD_HXX +#define XSD_CXX_TREE_TREE_FORWARD_HXX -#include <cxx/tree/elements.hxx> +#include <xsd/cxx/tree/elements.hxx> namespace CXX { @@ -15,4 +15,4 @@ namespace CXX } } -#endif // CXX_TREE_TREE_FORWARD_HXX +#endif // XSD_CXX_TREE_TREE_FORWARD_HXX diff --git a/xsd/cxx/tree/tree-header.cxx b/xsd/xsd/cxx/tree/tree-header.cxx index 8a695d4..99a9b17 100644 --- a/xsd/cxx/tree/tree-header.cxx +++ b/xsd/xsd/cxx/tree/tree-header.cxx @@ -1,12 +1,12 @@ // file : xsd/cxx/tree/tree-header.cxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#include <xsd-frontend/semantic-graph.hxx> -#include <xsd-frontend/traversal.hxx> +#include <libxsd-frontend/semantic-graph.hxx> +#include <libxsd-frontend/traversal.hxx> -#include <cxx/tree/tree-header.hxx> -#include <cxx/tree/default-value.hxx> -#include <cxx/tree/fundamental-header.hxx> +#include <xsd/cxx/tree/tree-header.hxx> +#include <xsd/cxx/tree/default-value.hxx> +#include <xsd/cxx/tree/fundamental-header.hxx> namespace CXX { @@ -252,6 +252,12 @@ namespace CXX << container << "* c = 0);" << endl; + os << "#ifdef XSD_CXX11" << endl + << name << "&" << endl + << "operator= (const " << name << "&) = default;" + << "#endif" << endl + << endl; + // clone // if (doxygen) @@ -527,6 +533,12 @@ namespace CXX << container << "* c = 0);" << endl; + os << "#ifdef XSD_CXX11" << endl + << name << "&" << endl + << "operator= (const " << name << "&) = default;" + << "#endif" << endl + << endl; + // clone // if (doxygen) @@ -942,6 +954,12 @@ namespace CXX << container << "* c = 0);" << endl; + os << "#ifdef XSD_CXX11" << endl + << name << "&" << endl + << "operator= (const " << name << "&) = default;" + << "#endif" << endl + << endl; + // clone // if (doxygen) @@ -3319,11 +3337,14 @@ namespace CXX // operator= // bool priv (false); + bool asop (true); if (!simple) { if (options.suppress_assignment ()) { + asop = false; + priv = true; os << "private:" << endl; @@ -3343,6 +3364,8 @@ namespace CXX } else if (has_members || (gen_wildcard && (hae || haa))) { + asop = false; + if (doxygen) { os << "/**" << endl @@ -3371,6 +3394,15 @@ namespace CXX if (priv) os << "public:" << endl; + if (asop) + { + os << "#ifdef XSD_CXX11" << endl + << name << "&" << endl + << "operator= (const " << name << "&) = default;" + << "#endif" << endl + << endl; + } + // d-tor // if (doxygen) @@ -3872,6 +3904,12 @@ namespace CXX flags_type << " f = 0);" << endl; + os << "#ifdef XSD_CXX11" << endl + << name << "&" << endl + << "operator= (const " << name << "&) = default;" + << "#endif" << endl + << endl; + // _clone // if (doxygen) diff --git a/xsd/cxx/tree/tree-header.hxx b/xsd/xsd/cxx/tree/tree-header.hxx index 153af5b..d0e9ea6 100644 --- a/xsd/cxx/tree/tree-header.hxx +++ b/xsd/xsd/cxx/tree/tree-header.hxx @@ -1,10 +1,10 @@ // file : xsd/cxx/tree/tree-header.hxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#ifndef CXX_TREE_TREE_HEADER_HXX -#define CXX_TREE_TREE_HEADER_HXX +#ifndef XSD_CXX_TREE_TREE_HEADER_HXX +#define XSD_CXX_TREE_TREE_HEADER_HXX -#include <cxx/tree/elements.hxx> +#include <xsd/cxx/tree/elements.hxx> namespace CXX { @@ -15,4 +15,4 @@ namespace CXX } } -#endif // CXX_TREE_TREE_HEADER_HXX +#endif // XSD_CXX_TREE_TREE_HEADER_HXX diff --git a/xsd/cxx/tree/tree-inline.cxx b/xsd/xsd/cxx/tree/tree-inline.cxx index 874586e..aa8b726 100644 --- a/xsd/cxx/tree/tree-inline.cxx +++ b/xsd/xsd/cxx/tree/tree-inline.cxx @@ -1,11 +1,11 @@ // file : xsd/cxx/tree/tree-inline.cxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#include <xsd-frontend/semantic-graph.hxx> -#include <xsd-frontend/traversal.hxx> +#include <libxsd-frontend/semantic-graph.hxx> +#include <libxsd-frontend/traversal.hxx> -#include <cxx/tree/tree-inline.hxx> -#include <cxx/tree/default-value.hxx> +#include <xsd/cxx/tree/tree-inline.hxx> +#include <xsd/cxx/tree/default-value.hxx> namespace CXX { @@ -291,7 +291,7 @@ namespace CXX } os << "// " << name << endl - << "// " << endl + << "//" << endl << endl; // default c-tor @@ -902,7 +902,7 @@ namespace CXX return; os << "// " << name << endl - << "// " << endl + << "//" << endl << endl; // Generate accessors and modifiers. @@ -1037,7 +1037,7 @@ namespace CXX String const& name (ename (e)); os << "// " << name << endl - << "// " << endl + << "//" << endl << endl; // Accessors/modifiers. diff --git a/xsd/cxx/tree/tree-inline.hxx b/xsd/xsd/cxx/tree/tree-inline.hxx index 7212dfd..dad4c24 100644 --- a/xsd/cxx/tree/tree-inline.hxx +++ b/xsd/xsd/cxx/tree/tree-inline.hxx @@ -1,10 +1,10 @@ // file : xsd/cxx/tree/tree-inline.hxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#ifndef CXX_TREE_TREE_INLINE_HXX -#define CXX_TREE_TREE_INLINE_HXX +#ifndef XSD_CXX_TREE_TREE_INLINE_HXX +#define XSD_CXX_TREE_TREE_INLINE_HXX -#include <cxx/tree/elements.hxx> +#include <xsd/cxx/tree/elements.hxx> namespace CXX { @@ -15,4 +15,4 @@ namespace CXX } } -#endif // CXX_TREE_TREE_INLINE_HXX +#endif // XSD_CXX_TREE_TREE_INLINE_HXX diff --git a/xsd/cxx/tree/tree-source.cxx b/xsd/xsd/cxx/tree/tree-source.cxx index e6b0aae..89419af 100644 --- a/xsd/cxx/tree/tree-source.cxx +++ b/xsd/xsd/cxx/tree/tree-source.cxx @@ -4,11 +4,11 @@ #include <map> #include <list> -#include <xsd-frontend/semantic-graph.hxx> -#include <xsd-frontend/traversal.hxx> +#include <libxsd-frontend/semantic-graph.hxx> +#include <libxsd-frontend/traversal.hxx> -#include <cxx/tree/tree-source.hxx> -#include <cxx/tree/default-value.hxx> +#include <xsd/cxx/tree/tree-source.hxx> +#include <xsd/cxx/tree/default-value.hxx> using namespace std; @@ -3562,7 +3562,7 @@ namespace CXX String const& member (emember (e)); os << "// " << name << endl - << "// " << endl + << "//" << endl << endl; // Virtual accessors. @@ -3727,24 +3727,36 @@ namespace CXX } } - if (!abst && polymorphic && e.substitutes_p () && - !options.suppress_parsing ()) + // Note that we cannot just omit this element if it's abstract + // because it may serve as a "link" between the root of the + // substitution group and a non-abstract element that uses this + // element as its root (see element_factory_map::find_substitution() + // for details). + // + if (polymorphic && e.substitutes_p () && !options.suppress_parsing ()) { String const& name (ename (e)); Type& r (e.substitutes ().root ()); os << "static" << endl << "const ::xsd::cxx::tree::element_factory_initializer< " << - poly_plate << ", " << char_type << ", "; - - belongs (e, belongs_); - - os << " >" << endl + poly_plate << ", " << char_type << " >" << endl << "_xsd_" << name << "_element_factory_init (" << endl << strlit (r.name ()) << "," << endl << strlit (r.namespace_ ().name ()) << "," << endl << strlit (e.name ()) << "," << endl - << strlit (e.namespace_ ().name ()) << ");" + << strlit (e.namespace_ ().name ()) << "," << endl; + + if (abst) + os << "0"; + else + { + os << "&::xsd::cxx::tree::factory_impl< "; + belongs (e, belongs_); + os << " >"; + } + + os << ");" << endl << endl; } diff --git a/xsd/cxx/tree/tree-source.hxx b/xsd/xsd/cxx/tree/tree-source.hxx index efd6927..66dcff7 100644 --- a/xsd/cxx/tree/tree-source.hxx +++ b/xsd/xsd/cxx/tree/tree-source.hxx @@ -1,10 +1,10 @@ // file : xsd/cxx/tree/tree-source.hxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#ifndef CXX_TREE_TREE_SOURCE_HXX -#define CXX_TREE_TREE_SOURCE_HXX +#ifndef XSD_CXX_TREE_TREE_SOURCE_HXX +#define XSD_CXX_TREE_TREE_SOURCE_HXX -#include <cxx/tree/elements.hxx> +#include <xsd/cxx/tree/elements.hxx> namespace CXX { @@ -15,4 +15,4 @@ namespace CXX } } -#endif // CXX_TREE_TREE_SOURCE_HXX +#endif // XSD_CXX_TREE_TREE_SOURCE_HXX diff --git a/xsd/cxx/tree/validator.cxx b/xsd/xsd/cxx/tree/validator.cxx index 68febb6..9785560 100644 --- a/xsd/cxx/tree/validator.cxx +++ b/xsd/xsd/cxx/tree/validator.cxx @@ -4,12 +4,12 @@ #include <set> #include <iostream> -#include <cxx/tree/validator.hxx> +#include <xsd/cxx/tree/validator.hxx> -#include <xsd-frontend/semantic-graph.hxx> -#include <xsd-frontend/traversal.hxx> +#include <libxsd-frontend/semantic-graph.hxx> +#include <libxsd-frontend/traversal.hxx> -#include <cxx/tree/elements.hxx> +#include <xsd/cxx/tree/elements.hxx> using namespace std; @@ -274,6 +274,8 @@ namespace CXX Traversal::Element, ValidationContext { + using Schema::traverse; + Traverser (ValidationContext& c) : ValidationContext (c), any_ (c) { @@ -420,6 +422,9 @@ namespace CXX Traversal::Attribute, ValidationContext { + using Schema::traverse; + using Complex::traverse; + AnonymousType (ValidationContext& c) : ValidationContext (c), anonymous_error_issued_ (false) @@ -582,7 +587,7 @@ namespace CXX NarrowString fn (ops.function_naming ()); - if (fn != "knr" && fn != "lcc" && fn != "java") + if (fn != "knr" && fn != "lcc" && fn != "ucc" && fn != "java") { wcerr << "error: unknown function naming style specified: '" << fn.c_str () << "'" << endl; diff --git a/xsd/cxx/tree/validator.hxx b/xsd/xsd/cxx/tree/validator.hxx index 25b36c6..23f3f04 100644 --- a/xsd/cxx/tree/validator.hxx +++ b/xsd/xsd/cxx/tree/validator.hxx @@ -1,13 +1,13 @@ // file : xsd/cxx/tree/validator.hxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#ifndef CXX_TREE_VALIDATOR_HXX -#define CXX_TREE_VALIDATOR_HXX +#ifndef XSD_CXX_TREE_VALIDATOR_HXX +#define XSD_CXX_TREE_VALIDATOR_HXX -#include <cxx/tree/elements.hxx> -#include <cxx/tree/options.hxx> +#include <xsd/cxx/tree/elements.hxx> +#include <xsd/cxx/tree/options.hxx> -#include <xsd.hxx> +#include <xsd/xsd.hxx> namespace CXX { @@ -26,4 +26,4 @@ namespace CXX } } -#endif // CXX_TREE_VALIDATOR_HXX +#endif // XSD_CXX_TREE_VALIDATOR_HXX diff --git a/xsd/elements.hxx b/xsd/xsd/elements.hxx index 4d63f6a..d3dd659 100644 --- a/xsd/elements.hxx +++ b/xsd/xsd/elements.hxx @@ -1,13 +1,13 @@ // file : xsd/elements.hxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#ifndef ELEMENTS_HXX -#define ELEMENTS_HXX +#ifndef XSD_ELEMENTS_HXX +#define XSD_ELEMENTS_HXX -#include <xsd-frontend/semantic-graph.hxx> -#include <xsd-frontend/traversal.hxx> +#include <libxsd-frontend/semantic-graph.hxx> +#include <libxsd-frontend/traversal.hxx> -#include <types.hxx> +#include <xsd/types.hxx> namespace SemanticGraph = XSDFrontend::SemanticGraph; namespace Traversal = XSDFrontend::Traversal; @@ -122,4 +122,4 @@ private: Traversal::Belongs belongs_; }; -#endif // ELEMENTS_HXX +#endif // XSD_ELEMENTS_HXX diff --git a/xsd/options-parser.hxx b/xsd/xsd/options-parser.hxx index 52125cb..afcdf80 100644 --- a/xsd/options-parser.hxx +++ b/xsd/xsd/options-parser.hxx @@ -1,11 +1,11 @@ // file : xsd/options-parser.hxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#ifndef OPTIONS_PARSER_HXX -#define OPTIONS_PARSER_HXX +#ifndef XSD_OPTIONS_PARSER_HXX +#define XSD_OPTIONS_PARSER_HXX -#include <types.hxx> -#include <options.hxx> +#include <xsd/types.hxx> +#include <xsd/options.hxx> namespace cli { @@ -26,4 +26,4 @@ namespace cli }; } -#endif // OPTIONS_PARSER_HXX +#endif // XSD_OPTIONS_PARSER_HXX diff --git a/xsd/options.cli b/xsd/xsd/options.cli index ac129cf..3153be9 100644 --- a/xsd/options.cli +++ b/xsd/xsd/options.cli @@ -2,11 +2,14 @@ // license : GNU GPL v2 + exceptions; see accompanying LICENSE file include <cstddef>; // std::size_t +include <cstdint>; // std::uint64_t -include <types.hxx>; // NarrowString, NarrowStrings +include <xsd/types.hxx>; // NarrowString, NarrowStrings class help_options { + std::uint64_t --build2-metadata; // Leave undocumented/hidden. + // These are all documented elsewhere. // bool --help; @@ -274,12 +277,19 @@ class options = 0 NarrowString --file-list { "<file>", - "Write a list of generated C++ files to <file>. This option is primarily - useful in the file-per-type compilation mode (\cb{--file-per-type}) to - create a list of generated C++ files, for example, as a makefile - fragment." + "Write a list of generated C++ files to <file> or to \cb{stdout} if + <file> is \cb{-}. This option is primarily useful in the file-per-type + compilation mode (\cb{--file-per-type}) to create a list of generated + C++ files, for example, as a makefile fragment." }; + bool --file-list-only + { + "Only write the list of C++ files that would be generated without + actually generating them. This option only makes sense together with + \cb{--file-list}." + } + NarrowString --file-list-prologue { "<text>", diff --git a/xsd/xsd/pregenerated/xsd/cxx/options.cxx b/xsd/xsd/pregenerated/xsd/cxx/options.cxx new file mode 100644 index 0000000..9eea3a9 --- /dev/null +++ b/xsd/xsd/pregenerated/xsd/cxx/options.cxx @@ -0,0 +1,739 @@ +// -*- C++ -*- +// +// This file was generated by CLI, a command line interface +// compiler for C++. +// + +// Begin prologue. +// +#include <xsd/options-parser.hxx> +// +// End prologue. + +#include <xsd/cxx/options.hxx> + +#include <map> +#include <set> +#include <string> +#include <vector> +#include <utility> +#include <ostream> +#include <sstream> +#include <cstring> + +namespace cli +{ + template <typename X> + struct parser + { + static void + parse (X& x, bool& xs, scanner& s) + { + using namespace std; + + const char* o (s.next ()); + if (s.more ()) + { + string v (s.next ()); + istringstream is (v); + if (!(is >> x && is.peek () == istringstream::traits_type::eof ())) + throw invalid_value (o, v); + } + else + throw missing_value (o); + + xs = true; + } + }; + + template <> + struct parser<bool> + { + static void + parse (bool& x, bool& xs, scanner& s) + { + const char* o (s.next ()); + + if (s.more ()) + { + const char* v (s.next ()); + + if (std::strcmp (v, "1") == 0 || + std::strcmp (v, "true") == 0 || + std::strcmp (v, "TRUE") == 0 || + std::strcmp (v, "True") == 0) + x = true; + else if (std::strcmp (v, "0") == 0 || + std::strcmp (v, "false") == 0 || + std::strcmp (v, "FALSE") == 0 || + std::strcmp (v, "False") == 0) + x = false; + else + throw invalid_value (o, v); + } + else + throw missing_value (o); + + xs = true; + } + }; + + template <> + struct parser<std::string> + { + static void + parse (std::string& x, bool& xs, scanner& s) + { + const char* o (s.next ()); + + if (s.more ()) + x = s.next (); + else + throw missing_value (o); + + xs = true; + } + }; + + template <typename X> + struct parser<std::pair<X, std::size_t> > + { + static void + parse (std::pair<X, std::size_t>& x, bool& xs, scanner& s) + { + x.second = s.position (); + parser<X>::parse (x.first, xs, s); + } + }; + + template <typename X> + struct parser<std::vector<X> > + { + static void + parse (std::vector<X>& c, bool& xs, scanner& s) + { + X x; + bool dummy; + parser<X>::parse (x, dummy, s); + c.push_back (x); + xs = true; + } + }; + + template <typename X, typename C> + struct parser<std::set<X, C> > + { + static void + parse (std::set<X, C>& c, bool& xs, scanner& s) + { + X x; + bool dummy; + parser<X>::parse (x, dummy, s); + c.insert (x); + xs = true; + } + }; + + template <typename K, typename V, typename C> + struct parser<std::map<K, V, C> > + { + static void + parse (std::map<K, V, C>& m, bool& xs, scanner& s) + { + const char* o (s.next ()); + + if (s.more ()) + { + std::size_t pos (s.position ()); + std::string ov (s.next ()); + std::string::size_type p = ov.find ('='); + + K k = K (); + V v = V (); + std::string kstr (ov, 0, p); + std::string vstr (ov, (p != std::string::npos ? p + 1 : ov.size ())); + + int ac (2); + char* av[] = + { + const_cast<char*> (o), + 0 + }; + + bool dummy; + if (!kstr.empty ()) + { + av[1] = const_cast<char*> (kstr.c_str ()); + argv_scanner s (0, ac, av, false, pos); + parser<K>::parse (k, dummy, s); + } + + if (!vstr.empty ()) + { + av[1] = const_cast<char*> (vstr.c_str ()); + argv_scanner s (0, ac, av, false, pos); + parser<V>::parse (v, dummy, s); + } + + m[k] = v; + } + else + throw missing_value (o); + + xs = true; + } + }; + + template <typename K, typename V, typename C> + struct parser<std::multimap<K, V, C> > + { + static void + parse (std::multimap<K, V, C>& m, bool& xs, scanner& s) + { + const char* o (s.next ()); + + if (s.more ()) + { + std::size_t pos (s.position ()); + std::string ov (s.next ()); + std::string::size_type p = ov.find ('='); + + K k = K (); + V v = V (); + std::string kstr (ov, 0, p); + std::string vstr (ov, (p != std::string::npos ? p + 1 : ov.size ())); + + int ac (2); + char* av[] = + { + const_cast<char*> (o), + 0 + }; + + bool dummy; + if (!kstr.empty ()) + { + av[1] = const_cast<char*> (kstr.c_str ()); + argv_scanner s (0, ac, av, false, pos); + parser<K>::parse (k, dummy, s); + } + + if (!vstr.empty ()) + { + av[1] = const_cast<char*> (vstr.c_str ()); + argv_scanner s (0, ac, av, false, pos); + parser<V>::parse (v, dummy, s); + } + + m.insert (typename std::multimap<K, V, C>::value_type (k, v)); + } + else + throw missing_value (o); + + xs = true; + } + }; + + template <typename X, typename T, T X::*M> + void + thunk (X& x, scanner& s) + { + parser<T>::parse (x.*M, s); + } + + template <typename X, bool X::*M> + void + thunk (X& x, scanner& s) + { + s.next (); + x.*M = true; + } + + template <typename X, typename T, T X::*M, bool X::*S> + void + thunk (X& x, scanner& s) + { + parser<T>::parse (x.*M, x.*S, s); + } +} + +#include <map> + +namespace CXX +{ + // options + // + + options:: + options () + : std_ (cxx_version::cxx11), + std_specified_ (false), + char_type_ ("char"), + char_type_specified_ (false), + char_encoding_ (), + char_encoding_specified_ (false), + output_dir_ (), + output_dir_specified_ (false), + generate_inline_ (), + generate_xml_schema_ (), + extern_xml_schema_ (), + extern_xml_schema_specified_ (false), + namespace_map_ (), + namespace_map_specified_ (false), + namespace_regex_ (), + namespace_regex_specified_ (false), + namespace_regex_trace_ (), + reserved_name_ (), + reserved_name_specified_ (false), + include_with_brackets_ (), + include_prefix_ (), + include_prefix_specified_ (false), + include_regex_ (), + include_regex_specified_ (false), + include_regex_trace_ (), + guard_prefix_ (), + guard_prefix_specified_ (false), + hxx_suffix_ (".hxx"), + hxx_suffix_specified_ (false), + ixx_suffix_ (".ixx"), + ixx_suffix_specified_ (false), + cxx_suffix_ (".cxx"), + cxx_suffix_specified_ (false), + fwd_suffix_ ("-fwd.hxx"), + fwd_suffix_specified_ (false), + hxx_regex_ (), + hxx_regex_specified_ (false), + ixx_regex_ (), + ixx_regex_specified_ (false), + cxx_regex_ (), + cxx_regex_specified_ (false), + fwd_regex_ (), + fwd_regex_specified_ (false), + hxx_prologue_ (), + hxx_prologue_specified_ (false), + ixx_prologue_ (), + ixx_prologue_specified_ (false), + cxx_prologue_ (), + cxx_prologue_specified_ (false), + fwd_prologue_ (), + fwd_prologue_specified_ (false), + prologue_ (), + prologue_specified_ (false), + hxx_epilogue_ (), + hxx_epilogue_specified_ (false), + ixx_epilogue_ (), + ixx_epilogue_specified_ (false), + cxx_epilogue_ (), + cxx_epilogue_specified_ (false), + fwd_epilogue_ (), + fwd_epilogue_specified_ (false), + epilogue_ (), + epilogue_specified_ (false), + hxx_prologue_file_ (), + hxx_prologue_file_specified_ (false), + ixx_prologue_file_ (), + ixx_prologue_file_specified_ (false), + cxx_prologue_file_ (), + cxx_prologue_file_specified_ (false), + fwd_prologue_file_ (), + fwd_prologue_file_specified_ (false), + prologue_file_ (), + prologue_file_specified_ (false), + hxx_epilogue_file_ (), + hxx_epilogue_file_specified_ (false), + ixx_epilogue_file_ (), + ixx_epilogue_file_specified_ (false), + cxx_epilogue_file_ (), + cxx_epilogue_file_specified_ (false), + fwd_epilogue_file_ (), + fwd_epilogue_file_specified_ (false), + epilogue_file_ (), + epilogue_file_specified_ (false), + export_symbol_ (), + export_symbol_specified_ (false), + export_xml_schema_ (), + export_maps_ (), + import_maps_ (), + generate_dep_ (), + generate_dep_only_ (), + dep_phony_ (), + dep_target_ (), + dep_target_specified_ (false), + dep_suffix_ (".d"), + dep_suffix_specified_ (false), + dep_file_ (), + dep_file_specified_ (false), + dep_regex_ (), + dep_regex_specified_ (false) + { + } + + ::cli::usage_para options:: + print_usage (::std::wostream& os, ::cli::usage_para p) + { + CLI_POTENTIALLY_UNUSED (os); + + if (p == ::cli::usage_para::text) + os << ::std::endl; + + os << "--std <version> Specify the C++ standard that the generated code" << ::std::endl + << " should conform to." << ::std::endl; + + os << "--char-type <type> Generate code using the provided character <type>" << ::std::endl + << " instead of the default char." << ::std::endl; + + os << "--char-encoding <enc> Specify the character encoding that should be used" << ::std::endl + << " in the generated code." << ::std::endl; + + os << "--output-dir <dir> Write generated files to <dir> instead of the" << ::std::endl + << " current directory." << ::std::endl; + + os << "--generate-inline Generate simple functions inline." << ::std::endl; + + os << "--generate-xml-schema Generate a C++ header file as if the schema being" << ::std::endl + << " compiled defines the XML Schema namespace." << ::std::endl; + + os << "--extern-xml-schema <file> Include a header file derived from <file> instead" << ::std::endl + << " of generating the XML Schema namespace mapping" << ::std::endl + << " inline." << ::std::endl; + + os << "--namespace-map <xns>=<cns> Map XML Schema namespace <xns> to C++ namespace" << ::std::endl + << " <cns>." << ::std::endl; + + os << "--namespace-regex <regex> Add <regex> to the list of regular expressions" << ::std::endl + << " used to translate XML Schema namespace names to" << ::std::endl + << " C++ namespace names." << ::std::endl; + + os << "--namespace-regex-trace Trace the process of applying regular expressions" << ::std::endl + << " specified with the --namespace-regex option." << ::std::endl; + + os << "--reserved-name <n>[=<r>] Add name <n> to the list of names that should not" << ::std::endl + << " be used as identifiers." << ::std::endl; + + os << "--include-with-brackets Use angle brackets (<>) instead of quotes (\"\") in" << ::std::endl + << " generated #include directives." << ::std::endl; + + os << "--include-prefix <prefix> Add <prefix> to generated #include directive" << ::std::endl + << " paths." << ::std::endl; + + os << "--include-regex <regex> Add <regex> to the list of regular expressions" << ::std::endl + << " used to transform #include directive paths." << ::std::endl; + + os << "--include-regex-trace Trace the process of applying regular expressions" << ::std::endl + << " specified with the --include-regex option." << ::std::endl; + + os << "--guard-prefix <prefix> Add <prefix> to generated header inclusion guards." << ::std::endl; + + os << "--hxx-suffix <suffix> Use the provided <suffix> instead of the default" << ::std::endl + << " .hxx to construct the name of the header file." << ::std::endl; + + os << "--ixx-suffix <suffix> Use the provided <suffix> instead of the default" << ::std::endl + << " .ixx to construct the name of the inline file." << ::std::endl; + + os << "--cxx-suffix <suffix> Use the provided <suffix> instead of the default" << ::std::endl + << " .cxx to construct the name of the source file." << ::std::endl; + + os << "--fwd-suffix <suffix> Use the provided <suffix> instead of the default" << ::std::endl + << " -fwd.hxx to construct the name of the forward" << ::std::endl + << " declaration file." << ::std::endl; + + os << "--hxx-regex <regex> Use the provided expression to construct the name" << ::std::endl + << " of the header file." << ::std::endl; + + os << "--ixx-regex <regex> Use the provided expression to construct the name" << ::std::endl + << " of the inline file." << ::std::endl; + + os << "--cxx-regex <regex> Use the provided expression to construct the name" << ::std::endl + << " of the source file." << ::std::endl; + + os << "--fwd-regex <regex> Use the provided expression to construct the name" << ::std::endl + << " of the forward declaration file." << ::std::endl; + + os << "--hxx-prologue <text> Insert <text> at the beginning of the header file." << ::std::endl; + + os << "--ixx-prologue <text> Insert <text> at the beginning of the inline file." << ::std::endl; + + os << "--cxx-prologue <text> Insert <text> at the beginning of the source file." << ::std::endl; + + os << "--fwd-prologue <text> Insert <text> at the beginning of the forward" << ::std::endl + << " declaration file." << ::std::endl; + + os << "--prologue <text> Insert <text> at the beginning of each generated" << ::std::endl + << " file for which there is no file-specific prologue." << ::std::endl; + + os << "--hxx-epilogue <text> Insert <text> at the end of the header file." << ::std::endl; + + os << "--ixx-epilogue <text> Insert <text> at the end of the inline file." << ::std::endl; + + os << "--cxx-epilogue <text> Insert <text> at the end of the source file." << ::std::endl; + + os << "--fwd-epilogue <text> Insert <text> at the end of the forward" << ::std::endl + << " declaration file." << ::std::endl; + + os << "--epilogue <text> Insert <text> at the end of each generated file" << ::std::endl + << " for which there is no file-specific epilogue." << ::std::endl; + + os << "--hxx-prologue-file <file> Insert the content of the <file> at the beginning" << ::std::endl + << " of the header file." << ::std::endl; + + os << "--ixx-prologue-file <file> Insert the content of the <file> at the beginning" << ::std::endl + << " of the inline file." << ::std::endl; + + os << "--cxx-prologue-file <file> Insert the content of the <file> at the beginning" << ::std::endl + << " of the source file." << ::std::endl; + + os << "--fwd-prologue-file <file> Insert the content of the <file> at the beginning" << ::std::endl + << " of the forward declaration file." << ::std::endl; + + os << "--prologue-file <file> Insert the content of the <file> at the beginning" << ::std::endl + << " of each generated file for which there is no" << ::std::endl + << " file-specific prologue file." << ::std::endl; + + os << "--hxx-epilogue-file <file> Insert the content of the <file> at the end of the" << ::std::endl + << " header file." << ::std::endl; + + os << "--ixx-epilogue-file <file> Insert the content of the <file> at the end of the" << ::std::endl + << " inline file." << ::std::endl; + + os << "--cxx-epilogue-file <file> Insert the content of the <file> at the end of the" << ::std::endl + << " source file." << ::std::endl; + + os << "--fwd-epilogue-file <file> Insert the content of the <file> at the end of the" << ::std::endl + << " forward declaration file." << ::std::endl; + + os << "--epilogue-file <file> Insert the content of the <file> at the end of" << ::std::endl + << " each generated file for which there is no" << ::std::endl + << " file-specific epilogue file." << ::std::endl; + + os << "--export-symbol <symbol> Insert <symbol> in places where DLL export/import" << ::std::endl + << " control statements" << ::std::endl + << " (__declspec(dllexport/dllimport)) are necessary." << ::std::endl; + + os << "--export-xml-schema Export/import types in the XML Schema namespace" << ::std::endl + << " using the export symbol provided with the" << ::std::endl + << " --export-symbol option." << ::std::endl; + + os << "--export-maps Export polymorphism support maps from a Win32 DLL" << ::std::endl + << " into which this generated code is placed." << ::std::endl; + + os << "--import-maps Import polymorphism support maps to a Win32 DLL or" << ::std::endl + << " executable into which this generated code is" << ::std::endl + << " linked." << ::std::endl; + + os << "--generate-dep Generate make dependency information." << ::std::endl; + + os << "--generate-dep-only Generate make dependency information only." << ::std::endl; + + os << "--dep-phony Generate phony targets for included/imported" << ::std::endl + << " schema files, causing each to depend on nothing." << ::std::endl; + + os << "--dep-target <target> Change the target of the dependency rule." << ::std::endl; + + os << "--dep-suffix <suffix> Use <suffix> instead of the default .d to" << ::std::endl + << " construct the name of the dependency file." << ::std::endl; + + os << "--dep-file <path> Use <path> as the generated dependency file path" << ::std::endl + << " instead of deriving it from the input file name." << ::std::endl; + + os << "--dep-regex <regex> Use the provided expression to construct the name" << ::std::endl + << " of the dependency file." << ::std::endl; + + p = ::cli::usage_para::option; + + return p; + } + + typedef + std::map<std::string, void (*) (options&, ::cli::scanner&)> + _cli_options_map; + + static _cli_options_map _cli_options_map_; + + struct _cli_options_map_init + { + _cli_options_map_init () + { + _cli_options_map_["--std"] = + &::cli::thunk< options, cxx_version, &options::std_, + &options::std_specified_ >; + _cli_options_map_["--char-type"] = + &::cli::thunk< options, NarrowString, &options::char_type_, + &options::char_type_specified_ >; + _cli_options_map_["--char-encoding"] = + &::cli::thunk< options, NarrowString, &options::char_encoding_, + &options::char_encoding_specified_ >; + _cli_options_map_["--output-dir"] = + &::cli::thunk< options, NarrowString, &options::output_dir_, + &options::output_dir_specified_ >; + _cli_options_map_["--generate-inline"] = + &::cli::thunk< options, &options::generate_inline_ >; + _cli_options_map_["--generate-xml-schema"] = + &::cli::thunk< options, &options::generate_xml_schema_ >; + _cli_options_map_["--extern-xml-schema"] = + &::cli::thunk< options, NarrowString, &options::extern_xml_schema_, + &options::extern_xml_schema_specified_ >; + _cli_options_map_["--namespace-map"] = + &::cli::thunk< options, NarrowStrings, &options::namespace_map_, + &options::namespace_map_specified_ >; + _cli_options_map_["--namespace-regex"] = + &::cli::thunk< options, NarrowStrings, &options::namespace_regex_, + &options::namespace_regex_specified_ >; + _cli_options_map_["--namespace-regex-trace"] = + &::cli::thunk< options, &options::namespace_regex_trace_ >; + _cli_options_map_["--reserved-name"] = + &::cli::thunk< options, NarrowStrings, &options::reserved_name_, + &options::reserved_name_specified_ >; + _cli_options_map_["--include-with-brackets"] = + &::cli::thunk< options, &options::include_with_brackets_ >; + _cli_options_map_["--include-prefix"] = + &::cli::thunk< options, NarrowString, &options::include_prefix_, + &options::include_prefix_specified_ >; + _cli_options_map_["--include-regex"] = + &::cli::thunk< options, NarrowStrings, &options::include_regex_, + &options::include_regex_specified_ >; + _cli_options_map_["--include-regex-trace"] = + &::cli::thunk< options, &options::include_regex_trace_ >; + _cli_options_map_["--guard-prefix"] = + &::cli::thunk< options, NarrowString, &options::guard_prefix_, + &options::guard_prefix_specified_ >; + _cli_options_map_["--hxx-suffix"] = + &::cli::thunk< options, NarrowString, &options::hxx_suffix_, + &options::hxx_suffix_specified_ >; + _cli_options_map_["--ixx-suffix"] = + &::cli::thunk< options, NarrowString, &options::ixx_suffix_, + &options::ixx_suffix_specified_ >; + _cli_options_map_["--cxx-suffix"] = + &::cli::thunk< options, NarrowString, &options::cxx_suffix_, + &options::cxx_suffix_specified_ >; + _cli_options_map_["--fwd-suffix"] = + &::cli::thunk< options, NarrowString, &options::fwd_suffix_, + &options::fwd_suffix_specified_ >; + _cli_options_map_["--hxx-regex"] = + &::cli::thunk< options, NarrowString, &options::hxx_regex_, + &options::hxx_regex_specified_ >; + _cli_options_map_["--ixx-regex"] = + &::cli::thunk< options, NarrowString, &options::ixx_regex_, + &options::ixx_regex_specified_ >; + _cli_options_map_["--cxx-regex"] = + &::cli::thunk< options, NarrowString, &options::cxx_regex_, + &options::cxx_regex_specified_ >; + _cli_options_map_["--fwd-regex"] = + &::cli::thunk< options, NarrowString, &options::fwd_regex_, + &options::fwd_regex_specified_ >; + _cli_options_map_["--hxx-prologue"] = + &::cli::thunk< options, NarrowStrings, &options::hxx_prologue_, + &options::hxx_prologue_specified_ >; + _cli_options_map_["--ixx-prologue"] = + &::cli::thunk< options, NarrowStrings, &options::ixx_prologue_, + &options::ixx_prologue_specified_ >; + _cli_options_map_["--cxx-prologue"] = + &::cli::thunk< options, NarrowStrings, &options::cxx_prologue_, + &options::cxx_prologue_specified_ >; + _cli_options_map_["--fwd-prologue"] = + &::cli::thunk< options, NarrowStrings, &options::fwd_prologue_, + &options::fwd_prologue_specified_ >; + _cli_options_map_["--prologue"] = + &::cli::thunk< options, NarrowStrings, &options::prologue_, + &options::prologue_specified_ >; + _cli_options_map_["--hxx-epilogue"] = + &::cli::thunk< options, NarrowStrings, &options::hxx_epilogue_, + &options::hxx_epilogue_specified_ >; + _cli_options_map_["--ixx-epilogue"] = + &::cli::thunk< options, NarrowStrings, &options::ixx_epilogue_, + &options::ixx_epilogue_specified_ >; + _cli_options_map_["--cxx-epilogue"] = + &::cli::thunk< options, NarrowStrings, &options::cxx_epilogue_, + &options::cxx_epilogue_specified_ >; + _cli_options_map_["--fwd-epilogue"] = + &::cli::thunk< options, NarrowStrings, &options::fwd_epilogue_, + &options::fwd_epilogue_specified_ >; + _cli_options_map_["--epilogue"] = + &::cli::thunk< options, NarrowStrings, &options::epilogue_, + &options::epilogue_specified_ >; + _cli_options_map_["--hxx-prologue-file"] = + &::cli::thunk< options, NarrowString, &options::hxx_prologue_file_, + &options::hxx_prologue_file_specified_ >; + _cli_options_map_["--ixx-prologue-file"] = + &::cli::thunk< options, NarrowString, &options::ixx_prologue_file_, + &options::ixx_prologue_file_specified_ >; + _cli_options_map_["--cxx-prologue-file"] = + &::cli::thunk< options, NarrowString, &options::cxx_prologue_file_, + &options::cxx_prologue_file_specified_ >; + _cli_options_map_["--fwd-prologue-file"] = + &::cli::thunk< options, NarrowString, &options::fwd_prologue_file_, + &options::fwd_prologue_file_specified_ >; + _cli_options_map_["--prologue-file"] = + &::cli::thunk< options, NarrowString, &options::prologue_file_, + &options::prologue_file_specified_ >; + _cli_options_map_["--hxx-epilogue-file"] = + &::cli::thunk< options, NarrowString, &options::hxx_epilogue_file_, + &options::hxx_epilogue_file_specified_ >; + _cli_options_map_["--ixx-epilogue-file"] = + &::cli::thunk< options, NarrowString, &options::ixx_epilogue_file_, + &options::ixx_epilogue_file_specified_ >; + _cli_options_map_["--cxx-epilogue-file"] = + &::cli::thunk< options, NarrowString, &options::cxx_epilogue_file_, + &options::cxx_epilogue_file_specified_ >; + _cli_options_map_["--fwd-epilogue-file"] = + &::cli::thunk< options, NarrowString, &options::fwd_epilogue_file_, + &options::fwd_epilogue_file_specified_ >; + _cli_options_map_["--epilogue-file"] = + &::cli::thunk< options, NarrowString, &options::epilogue_file_, + &options::epilogue_file_specified_ >; + _cli_options_map_["--export-symbol"] = + &::cli::thunk< options, NarrowString, &options::export_symbol_, + &options::export_symbol_specified_ >; + _cli_options_map_["--export-xml-schema"] = + &::cli::thunk< options, &options::export_xml_schema_ >; + _cli_options_map_["--export-maps"] = + &::cli::thunk< options, &options::export_maps_ >; + _cli_options_map_["--import-maps"] = + &::cli::thunk< options, &options::import_maps_ >; + _cli_options_map_["--generate-dep"] = + &::cli::thunk< options, &options::generate_dep_ >; + _cli_options_map_["--generate-dep-only"] = + &::cli::thunk< options, &options::generate_dep_only_ >; + _cli_options_map_["--dep-phony"] = + &::cli::thunk< options, &options::dep_phony_ >; + _cli_options_map_["--dep-target"] = + &::cli::thunk< options, NarrowStrings, &options::dep_target_, + &options::dep_target_specified_ >; + _cli_options_map_["--dep-suffix"] = + &::cli::thunk< options, NarrowString, &options::dep_suffix_, + &options::dep_suffix_specified_ >; + _cli_options_map_["--dep-file"] = + &::cli::thunk< options, NarrowString, &options::dep_file_, + &options::dep_file_specified_ >; + _cli_options_map_["--dep-regex"] = + &::cli::thunk< options, NarrowString, &options::dep_regex_, + &options::dep_regex_specified_ >; + } + }; + + static _cli_options_map_init _cli_options_map_init_; + + bool options:: + _parse (const char* o, ::cli::scanner& s) + { + _cli_options_map::const_iterator i (_cli_options_map_.find (o)); + + if (i != _cli_options_map_.end ()) + { + (*(i->second)) (*this, s); + return true; + } + + // options base + // + if (::options::_parse (o, s)) + return true; + + return false; + } +} + +// Begin epilogue. +// +// +// End epilogue. + diff --git a/xsd/xsd/pregenerated/xsd/cxx/options.hxx b/xsd/xsd/pregenerated/xsd/cxx/options.hxx new file mode 100644 index 0000000..085aa4c --- /dev/null +++ b/xsd/xsd/pregenerated/xsd/cxx/options.hxx @@ -0,0 +1,451 @@ +// -*- C++ -*- +// +// This file was generated by CLI, a command line interface +// compiler for C++. +// + +#ifndef XSD_CXX_OPTIONS_HXX +#define XSD_CXX_OPTIONS_HXX + +// Begin prologue. +// +// +// End prologue. + +#include <cstddef> + +#include <xsd/types.hxx> + +#include <xsd/cxx/option-types.hxx> + +#include <xsd/options.hxx> + +namespace CXX +{ + class options: public ::options + { + public: + // Option accessors. + // + const cxx_version& + std () const; + + bool + std_specified () const; + + const NarrowString& + char_type () const; + + bool + char_type_specified () const; + + const NarrowString& + char_encoding () const; + + bool + char_encoding_specified () const; + + const NarrowString& + output_dir () const; + + bool + output_dir_specified () const; + + const bool& + generate_inline () const; + + const bool& + generate_xml_schema () const; + + const NarrowString& + extern_xml_schema () const; + + bool + extern_xml_schema_specified () const; + + const NarrowStrings& + namespace_map () const; + + bool + namespace_map_specified () const; + + const NarrowStrings& + namespace_regex () const; + + bool + namespace_regex_specified () const; + + const bool& + namespace_regex_trace () const; + + const NarrowStrings& + reserved_name () const; + + bool + reserved_name_specified () const; + + const bool& + include_with_brackets () const; + + const NarrowString& + include_prefix () const; + + bool + include_prefix_specified () const; + + const NarrowStrings& + include_regex () const; + + bool + include_regex_specified () const; + + const bool& + include_regex_trace () const; + + const NarrowString& + guard_prefix () const; + + bool + guard_prefix_specified () const; + + const NarrowString& + hxx_suffix () const; + + bool + hxx_suffix_specified () const; + + const NarrowString& + ixx_suffix () const; + + bool + ixx_suffix_specified () const; + + const NarrowString& + cxx_suffix () const; + + bool + cxx_suffix_specified () const; + + const NarrowString& + fwd_suffix () const; + + bool + fwd_suffix_specified () const; + + const NarrowString& + hxx_regex () const; + + bool + hxx_regex_specified () const; + + const NarrowString& + ixx_regex () const; + + bool + ixx_regex_specified () const; + + const NarrowString& + cxx_regex () const; + + bool + cxx_regex_specified () const; + + const NarrowString& + fwd_regex () const; + + bool + fwd_regex_specified () const; + + const NarrowStrings& + hxx_prologue () const; + + bool + hxx_prologue_specified () const; + + const NarrowStrings& + ixx_prologue () const; + + bool + ixx_prologue_specified () const; + + const NarrowStrings& + cxx_prologue () const; + + bool + cxx_prologue_specified () const; + + const NarrowStrings& + fwd_prologue () const; + + bool + fwd_prologue_specified () const; + + const NarrowStrings& + prologue () const; + + bool + prologue_specified () const; + + const NarrowStrings& + hxx_epilogue () const; + + bool + hxx_epilogue_specified () const; + + const NarrowStrings& + ixx_epilogue () const; + + bool + ixx_epilogue_specified () const; + + const NarrowStrings& + cxx_epilogue () const; + + bool + cxx_epilogue_specified () const; + + const NarrowStrings& + fwd_epilogue () const; + + bool + fwd_epilogue_specified () const; + + const NarrowStrings& + epilogue () const; + + bool + epilogue_specified () const; + + const NarrowString& + hxx_prologue_file () const; + + bool + hxx_prologue_file_specified () const; + + const NarrowString& + ixx_prologue_file () const; + + bool + ixx_prologue_file_specified () const; + + const NarrowString& + cxx_prologue_file () const; + + bool + cxx_prologue_file_specified () const; + + const NarrowString& + fwd_prologue_file () const; + + bool + fwd_prologue_file_specified () const; + + const NarrowString& + prologue_file () const; + + bool + prologue_file_specified () const; + + const NarrowString& + hxx_epilogue_file () const; + + bool + hxx_epilogue_file_specified () const; + + const NarrowString& + ixx_epilogue_file () const; + + bool + ixx_epilogue_file_specified () const; + + const NarrowString& + cxx_epilogue_file () const; + + bool + cxx_epilogue_file_specified () const; + + const NarrowString& + fwd_epilogue_file () const; + + bool + fwd_epilogue_file_specified () const; + + const NarrowString& + epilogue_file () const; + + bool + epilogue_file_specified () const; + + const NarrowString& + export_symbol () const; + + bool + export_symbol_specified () const; + + const bool& + export_xml_schema () const; + + const bool& + export_maps () const; + + const bool& + import_maps () const; + + const bool& + generate_dep () const; + + const bool& + generate_dep_only () const; + + const bool& + dep_phony () const; + + const NarrowStrings& + dep_target () const; + + bool + dep_target_specified () const; + + const NarrowString& + dep_suffix () const; + + bool + dep_suffix_specified () const; + + const NarrowString& + dep_file () const; + + bool + dep_file_specified () const; + + const NarrowString& + dep_regex () const; + + bool + dep_regex_specified () const; + + // Print usage information. + // + static ::cli::usage_para + print_usage (::std::wostream&, + ::cli::usage_para = ::cli::usage_para::none); + + // Implementation details. + // + protected: + options (); + + bool + _parse (const char*, ::cli::scanner&); + + public: + cxx_version std_; + bool std_specified_; + NarrowString char_type_; + bool char_type_specified_; + NarrowString char_encoding_; + bool char_encoding_specified_; + NarrowString output_dir_; + bool output_dir_specified_; + bool generate_inline_; + bool generate_xml_schema_; + NarrowString extern_xml_schema_; + bool extern_xml_schema_specified_; + NarrowStrings namespace_map_; + bool namespace_map_specified_; + NarrowStrings namespace_regex_; + bool namespace_regex_specified_; + bool namespace_regex_trace_; + NarrowStrings reserved_name_; + bool reserved_name_specified_; + bool include_with_brackets_; + NarrowString include_prefix_; + bool include_prefix_specified_; + NarrowStrings include_regex_; + bool include_regex_specified_; + bool include_regex_trace_; + NarrowString guard_prefix_; + bool guard_prefix_specified_; + NarrowString hxx_suffix_; + bool hxx_suffix_specified_; + NarrowString ixx_suffix_; + bool ixx_suffix_specified_; + NarrowString cxx_suffix_; + bool cxx_suffix_specified_; + NarrowString fwd_suffix_; + bool fwd_suffix_specified_; + NarrowString hxx_regex_; + bool hxx_regex_specified_; + NarrowString ixx_regex_; + bool ixx_regex_specified_; + NarrowString cxx_regex_; + bool cxx_regex_specified_; + NarrowString fwd_regex_; + bool fwd_regex_specified_; + NarrowStrings hxx_prologue_; + bool hxx_prologue_specified_; + NarrowStrings ixx_prologue_; + bool ixx_prologue_specified_; + NarrowStrings cxx_prologue_; + bool cxx_prologue_specified_; + NarrowStrings fwd_prologue_; + bool fwd_prologue_specified_; + NarrowStrings prologue_; + bool prologue_specified_; + NarrowStrings hxx_epilogue_; + bool hxx_epilogue_specified_; + NarrowStrings ixx_epilogue_; + bool ixx_epilogue_specified_; + NarrowStrings cxx_epilogue_; + bool cxx_epilogue_specified_; + NarrowStrings fwd_epilogue_; + bool fwd_epilogue_specified_; + NarrowStrings epilogue_; + bool epilogue_specified_; + NarrowString hxx_prologue_file_; + bool hxx_prologue_file_specified_; + NarrowString ixx_prologue_file_; + bool ixx_prologue_file_specified_; + NarrowString cxx_prologue_file_; + bool cxx_prologue_file_specified_; + NarrowString fwd_prologue_file_; + bool fwd_prologue_file_specified_; + NarrowString prologue_file_; + bool prologue_file_specified_; + NarrowString hxx_epilogue_file_; + bool hxx_epilogue_file_specified_; + NarrowString ixx_epilogue_file_; + bool ixx_epilogue_file_specified_; + NarrowString cxx_epilogue_file_; + bool cxx_epilogue_file_specified_; + NarrowString fwd_epilogue_file_; + bool fwd_epilogue_file_specified_; + NarrowString epilogue_file_; + bool epilogue_file_specified_; + NarrowString export_symbol_; + bool export_symbol_specified_; + bool export_xml_schema_; + bool export_maps_; + bool import_maps_; + bool generate_dep_; + bool generate_dep_only_; + bool dep_phony_; + NarrowStrings dep_target_; + bool dep_target_specified_; + NarrowString dep_suffix_; + bool dep_suffix_specified_; + NarrowString dep_file_; + bool dep_file_specified_; + NarrowString dep_regex_; + bool dep_regex_specified_; + }; +} + +#include <xsd/cxx/options.ixx> + +// Begin epilogue. +// +// +// End epilogue. + +#endif // XSD_CXX_OPTIONS_HXX diff --git a/xsd/xsd/pregenerated/xsd/cxx/options.ixx b/xsd/xsd/pregenerated/xsd/cxx/options.ixx new file mode 100644 index 0000000..8266e31 --- /dev/null +++ b/xsd/xsd/pregenerated/xsd/cxx/options.ixx @@ -0,0 +1,615 @@ +// -*- C++ -*- +// +// This file was generated by CLI, a command line interface +// compiler for C++. +// + +// Begin prologue. +// +// +// End prologue. + +namespace CXX +{ + // options + // + + inline const cxx_version& options:: + std () const + { + return this->std_; + } + + inline bool options:: + std_specified () const + { + return this->std_specified_; + } + + inline const NarrowString& options:: + char_type () const + { + return this->char_type_; + } + + inline bool options:: + char_type_specified () const + { + return this->char_type_specified_; + } + + inline const NarrowString& options:: + char_encoding () const + { + return this->char_encoding_; + } + + inline bool options:: + char_encoding_specified () const + { + return this->char_encoding_specified_; + } + + inline const NarrowString& options:: + output_dir () const + { + return this->output_dir_; + } + + inline bool options:: + output_dir_specified () const + { + return this->output_dir_specified_; + } + + inline const bool& options:: + generate_inline () const + { + return this->generate_inline_; + } + + inline const bool& options:: + generate_xml_schema () const + { + return this->generate_xml_schema_; + } + + inline const NarrowString& options:: + extern_xml_schema () const + { + return this->extern_xml_schema_; + } + + inline bool options:: + extern_xml_schema_specified () const + { + return this->extern_xml_schema_specified_; + } + + inline const NarrowStrings& options:: + namespace_map () const + { + return this->namespace_map_; + } + + inline bool options:: + namespace_map_specified () const + { + return this->namespace_map_specified_; + } + + inline const NarrowStrings& options:: + namespace_regex () const + { + return this->namespace_regex_; + } + + inline bool options:: + namespace_regex_specified () const + { + return this->namespace_regex_specified_; + } + + inline const bool& options:: + namespace_regex_trace () const + { + return this->namespace_regex_trace_; + } + + inline const NarrowStrings& options:: + reserved_name () const + { + return this->reserved_name_; + } + + inline bool options:: + reserved_name_specified () const + { + return this->reserved_name_specified_; + } + + inline const bool& options:: + include_with_brackets () const + { + return this->include_with_brackets_; + } + + inline const NarrowString& options:: + include_prefix () const + { + return this->include_prefix_; + } + + inline bool options:: + include_prefix_specified () const + { + return this->include_prefix_specified_; + } + + inline const NarrowStrings& options:: + include_regex () const + { + return this->include_regex_; + } + + inline bool options:: + include_regex_specified () const + { + return this->include_regex_specified_; + } + + inline const bool& options:: + include_regex_trace () const + { + return this->include_regex_trace_; + } + + inline const NarrowString& options:: + guard_prefix () const + { + return this->guard_prefix_; + } + + inline bool options:: + guard_prefix_specified () const + { + return this->guard_prefix_specified_; + } + + inline const NarrowString& options:: + hxx_suffix () const + { + return this->hxx_suffix_; + } + + inline bool options:: + hxx_suffix_specified () const + { + return this->hxx_suffix_specified_; + } + + inline const NarrowString& options:: + ixx_suffix () const + { + return this->ixx_suffix_; + } + + inline bool options:: + ixx_suffix_specified () const + { + return this->ixx_suffix_specified_; + } + + inline const NarrowString& options:: + cxx_suffix () const + { + return this->cxx_suffix_; + } + + inline bool options:: + cxx_suffix_specified () const + { + return this->cxx_suffix_specified_; + } + + inline const NarrowString& options:: + fwd_suffix () const + { + return this->fwd_suffix_; + } + + inline bool options:: + fwd_suffix_specified () const + { + return this->fwd_suffix_specified_; + } + + inline const NarrowString& options:: + hxx_regex () const + { + return this->hxx_regex_; + } + + inline bool options:: + hxx_regex_specified () const + { + return this->hxx_regex_specified_; + } + + inline const NarrowString& options:: + ixx_regex () const + { + return this->ixx_regex_; + } + + inline bool options:: + ixx_regex_specified () const + { + return this->ixx_regex_specified_; + } + + inline const NarrowString& options:: + cxx_regex () const + { + return this->cxx_regex_; + } + + inline bool options:: + cxx_regex_specified () const + { + return this->cxx_regex_specified_; + } + + inline const NarrowString& options:: + fwd_regex () const + { + return this->fwd_regex_; + } + + inline bool options:: + fwd_regex_specified () const + { + return this->fwd_regex_specified_; + } + + inline const NarrowStrings& options:: + hxx_prologue () const + { + return this->hxx_prologue_; + } + + inline bool options:: + hxx_prologue_specified () const + { + return this->hxx_prologue_specified_; + } + + inline const NarrowStrings& options:: + ixx_prologue () const + { + return this->ixx_prologue_; + } + + inline bool options:: + ixx_prologue_specified () const + { + return this->ixx_prologue_specified_; + } + + inline const NarrowStrings& options:: + cxx_prologue () const + { + return this->cxx_prologue_; + } + + inline bool options:: + cxx_prologue_specified () const + { + return this->cxx_prologue_specified_; + } + + inline const NarrowStrings& options:: + fwd_prologue () const + { + return this->fwd_prologue_; + } + + inline bool options:: + fwd_prologue_specified () const + { + return this->fwd_prologue_specified_; + } + + inline const NarrowStrings& options:: + prologue () const + { + return this->prologue_; + } + + inline bool options:: + prologue_specified () const + { + return this->prologue_specified_; + } + + inline const NarrowStrings& options:: + hxx_epilogue () const + { + return this->hxx_epilogue_; + } + + inline bool options:: + hxx_epilogue_specified () const + { + return this->hxx_epilogue_specified_; + } + + inline const NarrowStrings& options:: + ixx_epilogue () const + { + return this->ixx_epilogue_; + } + + inline bool options:: + ixx_epilogue_specified () const + { + return this->ixx_epilogue_specified_; + } + + inline const NarrowStrings& options:: + cxx_epilogue () const + { + return this->cxx_epilogue_; + } + + inline bool options:: + cxx_epilogue_specified () const + { + return this->cxx_epilogue_specified_; + } + + inline const NarrowStrings& options:: + fwd_epilogue () const + { + return this->fwd_epilogue_; + } + + inline bool options:: + fwd_epilogue_specified () const + { + return this->fwd_epilogue_specified_; + } + + inline const NarrowStrings& options:: + epilogue () const + { + return this->epilogue_; + } + + inline bool options:: + epilogue_specified () const + { + return this->epilogue_specified_; + } + + inline const NarrowString& options:: + hxx_prologue_file () const + { + return this->hxx_prologue_file_; + } + + inline bool options:: + hxx_prologue_file_specified () const + { + return this->hxx_prologue_file_specified_; + } + + inline const NarrowString& options:: + ixx_prologue_file () const + { + return this->ixx_prologue_file_; + } + + inline bool options:: + ixx_prologue_file_specified () const + { + return this->ixx_prologue_file_specified_; + } + + inline const NarrowString& options:: + cxx_prologue_file () const + { + return this->cxx_prologue_file_; + } + + inline bool options:: + cxx_prologue_file_specified () const + { + return this->cxx_prologue_file_specified_; + } + + inline const NarrowString& options:: + fwd_prologue_file () const + { + return this->fwd_prologue_file_; + } + + inline bool options:: + fwd_prologue_file_specified () const + { + return this->fwd_prologue_file_specified_; + } + + inline const NarrowString& options:: + prologue_file () const + { + return this->prologue_file_; + } + + inline bool options:: + prologue_file_specified () const + { + return this->prologue_file_specified_; + } + + inline const NarrowString& options:: + hxx_epilogue_file () const + { + return this->hxx_epilogue_file_; + } + + inline bool options:: + hxx_epilogue_file_specified () const + { + return this->hxx_epilogue_file_specified_; + } + + inline const NarrowString& options:: + ixx_epilogue_file () const + { + return this->ixx_epilogue_file_; + } + + inline bool options:: + ixx_epilogue_file_specified () const + { + return this->ixx_epilogue_file_specified_; + } + + inline const NarrowString& options:: + cxx_epilogue_file () const + { + return this->cxx_epilogue_file_; + } + + inline bool options:: + cxx_epilogue_file_specified () const + { + return this->cxx_epilogue_file_specified_; + } + + inline const NarrowString& options:: + fwd_epilogue_file () const + { + return this->fwd_epilogue_file_; + } + + inline bool options:: + fwd_epilogue_file_specified () const + { + return this->fwd_epilogue_file_specified_; + } + + inline const NarrowString& options:: + epilogue_file () const + { + return this->epilogue_file_; + } + + inline bool options:: + epilogue_file_specified () const + { + return this->epilogue_file_specified_; + } + + inline const NarrowString& options:: + export_symbol () const + { + return this->export_symbol_; + } + + inline bool options:: + export_symbol_specified () const + { + return this->export_symbol_specified_; + } + + inline const bool& options:: + export_xml_schema () const + { + return this->export_xml_schema_; + } + + inline const bool& options:: + export_maps () const + { + return this->export_maps_; + } + + inline const bool& options:: + import_maps () const + { + return this->import_maps_; + } + + inline const bool& options:: + generate_dep () const + { + return this->generate_dep_; + } + + inline const bool& options:: + generate_dep_only () const + { + return this->generate_dep_only_; + } + + inline const bool& options:: + dep_phony () const + { + return this->dep_phony_; + } + + inline const NarrowStrings& options:: + dep_target () const + { + return this->dep_target_; + } + + inline bool options:: + dep_target_specified () const + { + return this->dep_target_specified_; + } + + inline const NarrowString& options:: + dep_suffix () const + { + return this->dep_suffix_; + } + + inline bool options:: + dep_suffix_specified () const + { + return this->dep_suffix_specified_; + } + + inline const NarrowString& options:: + dep_file () const + { + return this->dep_file_; + } + + inline bool options:: + dep_file_specified () const + { + return this->dep_file_specified_; + } + + inline const NarrowString& options:: + dep_regex () const + { + return this->dep_regex_; + } + + inline bool options:: + dep_regex_specified () const + { + return this->dep_regex_specified_; + } +} + +// Begin epilogue. +// +// +// End epilogue. diff --git a/xsd/xsd/pregenerated/xsd/cxx/parser/options.cxx b/xsd/xsd/pregenerated/xsd/cxx/parser/options.cxx new file mode 100644 index 0000000..60667ac --- /dev/null +++ b/xsd/xsd/pregenerated/xsd/cxx/parser/options.cxx @@ -0,0 +1,776 @@ +// -*- C++ -*- +// +// This file was generated by CLI, a command line interface +// compiler for C++. +// + +// Begin prologue. +// +#include <xsd/options-parser.hxx> +// +// End prologue. + +#include <xsd/cxx/parser/options.hxx> + +#include <map> +#include <set> +#include <string> +#include <vector> +#include <utility> +#include <ostream> +#include <sstream> +#include <cstring> + +namespace cli +{ + template <typename X> + struct parser + { + static void + parse (X& x, bool& xs, scanner& s) + { + using namespace std; + + const char* o (s.next ()); + if (s.more ()) + { + string v (s.next ()); + istringstream is (v); + if (!(is >> x && is.peek () == istringstream::traits_type::eof ())) + throw invalid_value (o, v); + } + else + throw missing_value (o); + + xs = true; + } + }; + + template <> + struct parser<bool> + { + static void + parse (bool& x, bool& xs, scanner& s) + { + const char* o (s.next ()); + + if (s.more ()) + { + const char* v (s.next ()); + + if (std::strcmp (v, "1") == 0 || + std::strcmp (v, "true") == 0 || + std::strcmp (v, "TRUE") == 0 || + std::strcmp (v, "True") == 0) + x = true; + else if (std::strcmp (v, "0") == 0 || + std::strcmp (v, "false") == 0 || + std::strcmp (v, "FALSE") == 0 || + std::strcmp (v, "False") == 0) + x = false; + else + throw invalid_value (o, v); + } + else + throw missing_value (o); + + xs = true; + } + }; + + template <> + struct parser<std::string> + { + static void + parse (std::string& x, bool& xs, scanner& s) + { + const char* o (s.next ()); + + if (s.more ()) + x = s.next (); + else + throw missing_value (o); + + xs = true; + } + }; + + template <typename X> + struct parser<std::pair<X, std::size_t> > + { + static void + parse (std::pair<X, std::size_t>& x, bool& xs, scanner& s) + { + x.second = s.position (); + parser<X>::parse (x.first, xs, s); + } + }; + + template <typename X> + struct parser<std::vector<X> > + { + static void + parse (std::vector<X>& c, bool& xs, scanner& s) + { + X x; + bool dummy; + parser<X>::parse (x, dummy, s); + c.push_back (x); + xs = true; + } + }; + + template <typename X, typename C> + struct parser<std::set<X, C> > + { + static void + parse (std::set<X, C>& c, bool& xs, scanner& s) + { + X x; + bool dummy; + parser<X>::parse (x, dummy, s); + c.insert (x); + xs = true; + } + }; + + template <typename K, typename V, typename C> + struct parser<std::map<K, V, C> > + { + static void + parse (std::map<K, V, C>& m, bool& xs, scanner& s) + { + const char* o (s.next ()); + + if (s.more ()) + { + std::size_t pos (s.position ()); + std::string ov (s.next ()); + std::string::size_type p = ov.find ('='); + + K k = K (); + V v = V (); + std::string kstr (ov, 0, p); + std::string vstr (ov, (p != std::string::npos ? p + 1 : ov.size ())); + + int ac (2); + char* av[] = + { + const_cast<char*> (o), + 0 + }; + + bool dummy; + if (!kstr.empty ()) + { + av[1] = const_cast<char*> (kstr.c_str ()); + argv_scanner s (0, ac, av, false, pos); + parser<K>::parse (k, dummy, s); + } + + if (!vstr.empty ()) + { + av[1] = const_cast<char*> (vstr.c_str ()); + argv_scanner s (0, ac, av, false, pos); + parser<V>::parse (v, dummy, s); + } + + m[k] = v; + } + else + throw missing_value (o); + + xs = true; + } + }; + + template <typename K, typename V, typename C> + struct parser<std::multimap<K, V, C> > + { + static void + parse (std::multimap<K, V, C>& m, bool& xs, scanner& s) + { + const char* o (s.next ()); + + if (s.more ()) + { + std::size_t pos (s.position ()); + std::string ov (s.next ()); + std::string::size_type p = ov.find ('='); + + K k = K (); + V v = V (); + std::string kstr (ov, 0, p); + std::string vstr (ov, (p != std::string::npos ? p + 1 : ov.size ())); + + int ac (2); + char* av[] = + { + const_cast<char*> (o), + 0 + }; + + bool dummy; + if (!kstr.empty ()) + { + av[1] = const_cast<char*> (kstr.c_str ()); + argv_scanner s (0, ac, av, false, pos); + parser<K>::parse (k, dummy, s); + } + + if (!vstr.empty ()) + { + av[1] = const_cast<char*> (vstr.c_str ()); + argv_scanner s (0, ac, av, false, pos); + parser<V>::parse (v, dummy, s); + } + + m.insert (typename std::multimap<K, V, C>::value_type (k, v)); + } + else + throw missing_value (o); + + xs = true; + } + }; + + template <typename X, typename T, T X::*M> + void + thunk (X& x, scanner& s) + { + parser<T>::parse (x.*M, s); + } + + template <typename X, bool X::*M> + void + thunk (X& x, scanner& s) + { + s.next (); + x.*M = true; + } + + template <typename X, typename T, T X::*M, bool X::*S> + void + thunk (X& x, scanner& s) + { + parser<T>::parse (x.*M, x.*S, s); + } +} + +#include <map> + +namespace CXX +{ + namespace Parser + { + // options + // + + options:: + options () + : type_map_ (), + type_map_specified_ (false), + xml_parser_ ("xerces"), + xml_parser_specified_ (false), + generate_validation_ (), + suppress_validation_ (), + generate_polymorphic_ (), + generate_noop_impl_ (), + generate_print_impl_ (), + generate_test_driver_ (), + force_overwrite_ (), + root_element_first_ (), + root_element_last_ (), + root_element_ (), + root_element_specified_ (false), + skel_type_suffix_ ("_pskel"), + skel_type_suffix_specified_ (false), + skel_file_suffix_ ("-pskel"), + skel_file_suffix_specified_ (false), + impl_type_suffix_ ("_pimpl"), + impl_type_suffix_specified_ (false), + impl_file_suffix_ ("-pimpl"), + impl_file_suffix_specified_ (false) + { + } + + options:: + options (int& argc, + char** argv, + bool erase, + ::cli::unknown_mode opt, + ::cli::unknown_mode arg) + : type_map_ (), + type_map_specified_ (false), + xml_parser_ ("xerces"), + xml_parser_specified_ (false), + generate_validation_ (), + suppress_validation_ (), + generate_polymorphic_ (), + generate_noop_impl_ (), + generate_print_impl_ (), + generate_test_driver_ (), + force_overwrite_ (), + root_element_first_ (), + root_element_last_ (), + root_element_ (), + root_element_specified_ (false), + skel_type_suffix_ ("_pskel"), + skel_type_suffix_specified_ (false), + skel_file_suffix_ ("-pskel"), + skel_file_suffix_specified_ (false), + impl_type_suffix_ ("_pimpl"), + impl_type_suffix_specified_ (false), + impl_file_suffix_ ("-pimpl"), + impl_file_suffix_specified_ (false) + { + ::cli::argv_scanner s (argc, argv, erase); + _parse (s, opt, arg); + } + + options:: + options (int start, + int& argc, + char** argv, + bool erase, + ::cli::unknown_mode opt, + ::cli::unknown_mode arg) + : type_map_ (), + type_map_specified_ (false), + xml_parser_ ("xerces"), + xml_parser_specified_ (false), + generate_validation_ (), + suppress_validation_ (), + generate_polymorphic_ (), + generate_noop_impl_ (), + generate_print_impl_ (), + generate_test_driver_ (), + force_overwrite_ (), + root_element_first_ (), + root_element_last_ (), + root_element_ (), + root_element_specified_ (false), + skel_type_suffix_ ("_pskel"), + skel_type_suffix_specified_ (false), + skel_file_suffix_ ("-pskel"), + skel_file_suffix_specified_ (false), + impl_type_suffix_ ("_pimpl"), + impl_type_suffix_specified_ (false), + impl_file_suffix_ ("-pimpl"), + impl_file_suffix_specified_ (false) + { + ::cli::argv_scanner s (start, argc, argv, erase); + _parse (s, opt, arg); + } + + options:: + options (int& argc, + char** argv, + int& end, + bool erase, + ::cli::unknown_mode opt, + ::cli::unknown_mode arg) + : type_map_ (), + type_map_specified_ (false), + xml_parser_ ("xerces"), + xml_parser_specified_ (false), + generate_validation_ (), + suppress_validation_ (), + generate_polymorphic_ (), + generate_noop_impl_ (), + generate_print_impl_ (), + generate_test_driver_ (), + force_overwrite_ (), + root_element_first_ (), + root_element_last_ (), + root_element_ (), + root_element_specified_ (false), + skel_type_suffix_ ("_pskel"), + skel_type_suffix_specified_ (false), + skel_file_suffix_ ("-pskel"), + skel_file_suffix_specified_ (false), + impl_type_suffix_ ("_pimpl"), + impl_type_suffix_specified_ (false), + impl_file_suffix_ ("-pimpl"), + impl_file_suffix_specified_ (false) + { + ::cli::argv_scanner s (argc, argv, erase); + _parse (s, opt, arg); + end = s.end (); + } + + options:: + options (int start, + int& argc, + char** argv, + int& end, + bool erase, + ::cli::unknown_mode opt, + ::cli::unknown_mode arg) + : type_map_ (), + type_map_specified_ (false), + xml_parser_ ("xerces"), + xml_parser_specified_ (false), + generate_validation_ (), + suppress_validation_ (), + generate_polymorphic_ (), + generate_noop_impl_ (), + generate_print_impl_ (), + generate_test_driver_ (), + force_overwrite_ (), + root_element_first_ (), + root_element_last_ (), + root_element_ (), + root_element_specified_ (false), + skel_type_suffix_ ("_pskel"), + skel_type_suffix_specified_ (false), + skel_file_suffix_ ("-pskel"), + skel_file_suffix_specified_ (false), + impl_type_suffix_ ("_pimpl"), + impl_type_suffix_specified_ (false), + impl_file_suffix_ ("-pimpl"), + impl_file_suffix_specified_ (false) + { + ::cli::argv_scanner s (start, argc, argv, erase); + _parse (s, opt, arg); + end = s.end (); + } + + options:: + options (::cli::scanner& s, + ::cli::unknown_mode opt, + ::cli::unknown_mode arg) + : type_map_ (), + type_map_specified_ (false), + xml_parser_ ("xerces"), + xml_parser_specified_ (false), + generate_validation_ (), + suppress_validation_ (), + generate_polymorphic_ (), + generate_noop_impl_ (), + generate_print_impl_ (), + generate_test_driver_ (), + force_overwrite_ (), + root_element_first_ (), + root_element_last_ (), + root_element_ (), + root_element_specified_ (false), + skel_type_suffix_ ("_pskel"), + skel_type_suffix_specified_ (false), + skel_file_suffix_ ("-pskel"), + skel_file_suffix_specified_ (false), + impl_type_suffix_ ("_pimpl"), + impl_type_suffix_specified_ (false), + impl_file_suffix_ ("-pimpl"), + impl_file_suffix_specified_ (false) + { + _parse (s, opt, arg); + } + + ::cli::usage_para options:: + print_usage (::std::wostream& os, ::cli::usage_para p) + { + CLI_POTENTIALLY_UNUSED (os); + + if (p == ::cli::usage_para::text) + os << ::std::endl; + + os << "--type-map <mapfile> Read XML Schema to C++ type mapping information" << ::std::endl + << " from <mapfile>." << ::std::endl; + + os << "--xml-parser <parser> Use <parser> as the underlying XML parser." << ::std::endl; + + os << "--generate-validation Generate validation code." << ::std::endl; + + os << "--suppress-validation Suppress the generation of validation code." << ::std::endl; + + os << "--generate-polymorphic Generate polymorphism-aware code." << ::std::endl; + + os << "--generate-noop-impl Generate a sample parser implementation that does" << ::std::endl + << " nothing (no operation)." << ::std::endl; + + os << "--generate-print-impl Generate a sample parser implementation that" << ::std::endl + << " prints the XML data to STDOUT." << ::std::endl; + + os << "--generate-test-driver Generate a test driver for the sample parser" << ::std::endl + << " implementation." << ::std::endl; + + os << "--force-overwrite Force overwriting of the existing implementation" << ::std::endl + << " and test driver files." << ::std::endl; + + os << "--root-element-first Indicate that the first global element is the" << ::std::endl + << " document root." << ::std::endl; + + os << "--root-element-last Indicate that the last global element is the" << ::std::endl + << " document root." << ::std::endl; + + os << "--root-element <element> Indicate that <element> is the document root." << ::std::endl; + + os << "--skel-type-suffix <suffix> Use the provided <suffix> instead of the default" << ::std::endl + << " _pskel to construct the names of the generated" << ::std::endl + << " parser skeletons." << ::std::endl; + + os << "--skel-file-suffix <suffix> Use the provided <suffix> instead of the default" << ::std::endl + << " -pskel to construct the names of the generated" << ::std::endl + << " parser skeleton files." << ::std::endl; + + os << "--impl-type-suffix <suffix> Use the provided <suffix> instead of the default" << ::std::endl + << " _pimpl to construct the names of the parser" << ::std::endl + << " implementations for the built-in XML Schema types" << ::std::endl + << " as well as sample parser implementations." << ::std::endl; + + os << "--impl-file-suffix <suffix> Use the provided <suffix> instead of the default" << ::std::endl + << " -pimpl to construct the names of the generated" << ::std::endl + << " sample parser implementation files." << ::std::endl; + + p = ::cli::usage_para::option; + + return p; + } + + typedef + std::map<std::string, void (*) (options&, ::cli::scanner&)> + _cli_options_map; + + static _cli_options_map _cli_options_map_; + + struct _cli_options_map_init + { + _cli_options_map_init () + { + _cli_options_map_["--type-map"] = + &::cli::thunk< options, NarrowStrings, &options::type_map_, + &options::type_map_specified_ >; + _cli_options_map_["--xml-parser"] = + &::cli::thunk< options, NarrowString, &options::xml_parser_, + &options::xml_parser_specified_ >; + _cli_options_map_["--generate-validation"] = + &::cli::thunk< options, &options::generate_validation_ >; + _cli_options_map_["--suppress-validation"] = + &::cli::thunk< options, &options::suppress_validation_ >; + _cli_options_map_["--generate-polymorphic"] = + &::cli::thunk< options, &options::generate_polymorphic_ >; + _cli_options_map_["--generate-noop-impl"] = + &::cli::thunk< options, &options::generate_noop_impl_ >; + _cli_options_map_["--generate-print-impl"] = + &::cli::thunk< options, &options::generate_print_impl_ >; + _cli_options_map_["--generate-test-driver"] = + &::cli::thunk< options, &options::generate_test_driver_ >; + _cli_options_map_["--force-overwrite"] = + &::cli::thunk< options, &options::force_overwrite_ >; + _cli_options_map_["--root-element-first"] = + &::cli::thunk< options, &options::root_element_first_ >; + _cli_options_map_["--root-element-last"] = + &::cli::thunk< options, &options::root_element_last_ >; + _cli_options_map_["--root-element"] = + &::cli::thunk< options, NarrowString, &options::root_element_, + &options::root_element_specified_ >; + _cli_options_map_["--skel-type-suffix"] = + &::cli::thunk< options, NarrowString, &options::skel_type_suffix_, + &options::skel_type_suffix_specified_ >; + _cli_options_map_["--skel-file-suffix"] = + &::cli::thunk< options, NarrowString, &options::skel_file_suffix_, + &options::skel_file_suffix_specified_ >; + _cli_options_map_["--impl-type-suffix"] = + &::cli::thunk< options, NarrowString, &options::impl_type_suffix_, + &options::impl_type_suffix_specified_ >; + _cli_options_map_["--impl-file-suffix"] = + &::cli::thunk< options, NarrowString, &options::impl_file_suffix_, + &options::impl_file_suffix_specified_ >; + } + }; + + static _cli_options_map_init _cli_options_map_init_; + + bool options:: + _parse (const char* o, ::cli::scanner& s) + { + _cli_options_map::const_iterator i (_cli_options_map_.find (o)); + + if (i != _cli_options_map_.end ()) + { + (*(i->second)) (*this, s); + return true; + } + + // options base + // + if (::CXX::options::_parse (o, s)) + return true; + + return false; + } + + bool options:: + _parse (::cli::scanner& s, + ::cli::unknown_mode opt_mode, + ::cli::unknown_mode arg_mode) + { + // Can't skip combined flags (--no-combined-flags). + // + assert (opt_mode != ::cli::unknown_mode::skip); + + bool r = false; + bool opt = true; + + while (s.more ()) + { + const char* o = s.peek (); + + if (std::strcmp (o, "--") == 0) + { + opt = false; + s.skip (); + r = true; + continue; + } + + if (opt) + { + if (_parse (o, s)) + { + r = true; + continue; + } + + if (std::strncmp (o, "-", 1) == 0 && o[1] != '\0') + { + // Handle combined option values. + // + std::string co; + if (const char* v = std::strchr (o, '=')) + { + co.assign (o, 0, v - o); + ++v; + + int ac (2); + char* av[] = + { + const_cast<char*> (co.c_str ()), + const_cast<char*> (v) + }; + + ::cli::argv_scanner ns (0, ac, av); + + if (_parse (co.c_str (), ns)) + { + // Parsed the option but not its value? + // + if (ns.end () != 2) + throw ::cli::invalid_value (co, v); + + s.next (); + r = true; + continue; + } + else + { + // Set the unknown option and fall through. + // + o = co.c_str (); + } + } + + // Handle combined flags. + // + char cf[3]; + { + const char* p = o + 1; + for (; *p != '\0'; ++p) + { + if (!((*p >= 'a' && *p <= 'z') || + (*p >= 'A' && *p <= 'Z') || + (*p >= '0' && *p <= '9'))) + break; + } + + if (*p == '\0') + { + for (p = o + 1; *p != '\0'; ++p) + { + std::strcpy (cf, "-"); + cf[1] = *p; + cf[2] = '\0'; + + int ac (1); + char* av[] = + { + cf + }; + + ::cli::argv_scanner ns (0, ac, av); + + if (!_parse (cf, ns)) + break; + } + + if (*p == '\0') + { + // All handled. + // + s.next (); + r = true; + continue; + } + else + { + // Set the unknown option and fall through. + // + o = cf; + } + } + } + + switch (opt_mode) + { + case ::cli::unknown_mode::skip: + { + s.skip (); + r = true; + continue; + } + case ::cli::unknown_mode::stop: + { + break; + } + case ::cli::unknown_mode::fail: + { + throw ::cli::unknown_option (o); + } + } + + break; + } + } + + switch (arg_mode) + { + case ::cli::unknown_mode::skip: + { + s.skip (); + r = true; + continue; + } + case ::cli::unknown_mode::stop: + { + break; + } + case ::cli::unknown_mode::fail: + { + throw ::cli::unknown_argument (o); + } + } + + break; + } + + return r; + } + } +} + +// Begin epilogue. +// +// +// End epilogue. + diff --git a/xsd/xsd/pregenerated/xsd/cxx/parser/options.hxx b/xsd/xsd/pregenerated/xsd/cxx/parser/options.hxx new file mode 100644 index 0000000..03b67fd --- /dev/null +++ b/xsd/xsd/pregenerated/xsd/cxx/parser/options.hxx @@ -0,0 +1,186 @@ +// -*- C++ -*- +// +// This file was generated by CLI, a command line interface +// compiler for C++. +// + +#ifndef XSD_CXX_PARSER_OPTIONS_HXX +#define XSD_CXX_PARSER_OPTIONS_HXX + +// Begin prologue. +// +// +// End prologue. + +#include <cstddef> + +#include <xsd/types.hxx> + +#include <xsd/cxx/options.hxx> + +namespace CXX +{ + namespace Parser + { + class options: public ::CXX::options + { + public: + options (); + + options (int& argc, + char** argv, + bool erase = false, + ::cli::unknown_mode option = ::cli::unknown_mode::fail, + ::cli::unknown_mode argument = ::cli::unknown_mode::stop); + + options (int start, + int& argc, + char** argv, + bool erase = false, + ::cli::unknown_mode option = ::cli::unknown_mode::fail, + ::cli::unknown_mode argument = ::cli::unknown_mode::stop); + + options (int& argc, + char** argv, + int& end, + bool erase = false, + ::cli::unknown_mode option = ::cli::unknown_mode::fail, + ::cli::unknown_mode argument = ::cli::unknown_mode::stop); + + options (int start, + int& argc, + char** argv, + int& end, + bool erase = false, + ::cli::unknown_mode option = ::cli::unknown_mode::fail, + ::cli::unknown_mode argument = ::cli::unknown_mode::stop); + + options (::cli::scanner&, + ::cli::unknown_mode option = ::cli::unknown_mode::fail, + ::cli::unknown_mode argument = ::cli::unknown_mode::stop); + + // Option accessors. + // + const NarrowStrings& + type_map () const; + + bool + type_map_specified () const; + + const NarrowString& + xml_parser () const; + + bool + xml_parser_specified () const; + + const bool& + generate_validation () const; + + const bool& + suppress_validation () const; + + const bool& + generate_polymorphic () const; + + const bool& + generate_noop_impl () const; + + const bool& + generate_print_impl () const; + + const bool& + generate_test_driver () const; + + const bool& + force_overwrite () const; + + const bool& + root_element_first () const; + + const bool& + root_element_last () const; + + const NarrowString& + root_element () const; + + bool + root_element_specified () const; + + const NarrowString& + skel_type_suffix () const; + + bool + skel_type_suffix_specified () const; + + const NarrowString& + skel_file_suffix () const; + + bool + skel_file_suffix_specified () const; + + const NarrowString& + impl_type_suffix () const; + + bool + impl_type_suffix_specified () const; + + const NarrowString& + impl_file_suffix () const; + + bool + impl_file_suffix_specified () const; + + // Print usage information. + // + static ::cli::usage_para + print_usage (::std::wostream&, + ::cli::usage_para = ::cli::usage_para::none); + + // Implementation details. + // + protected: + bool + _parse (const char*, ::cli::scanner&); + + private: + bool + _parse (::cli::scanner&, + ::cli::unknown_mode option, + ::cli::unknown_mode argument); + + public: + NarrowStrings type_map_; + bool type_map_specified_; + NarrowString xml_parser_; + bool xml_parser_specified_; + bool generate_validation_; + bool suppress_validation_; + bool generate_polymorphic_; + bool generate_noop_impl_; + bool generate_print_impl_; + bool generate_test_driver_; + bool force_overwrite_; + bool root_element_first_; + bool root_element_last_; + NarrowString root_element_; + bool root_element_specified_; + NarrowString skel_type_suffix_; + bool skel_type_suffix_specified_; + NarrowString skel_file_suffix_; + bool skel_file_suffix_specified_; + NarrowString impl_type_suffix_; + bool impl_type_suffix_specified_; + NarrowString impl_file_suffix_; + bool impl_file_suffix_specified_; + }; + } +} + +#include <xsd/cxx/parser/options.ixx> + +// Begin epilogue. +// +// +// End epilogue. + +#endif // XSD_CXX_PARSER_OPTIONS_HXX diff --git a/xsd/xsd/pregenerated/xsd/cxx/parser/options.ixx b/xsd/xsd/pregenerated/xsd/cxx/parser/options.ixx new file mode 100644 index 0000000..64c00c5 --- /dev/null +++ b/xsd/xsd/pregenerated/xsd/cxx/parser/options.ixx @@ -0,0 +1,162 @@ +// -*- C++ -*- +// +// This file was generated by CLI, a command line interface +// compiler for C++. +// + +// Begin prologue. +// +// +// End prologue. + +namespace CXX +{ + namespace Parser + { + // options + // + + inline const NarrowStrings& options:: + type_map () const + { + return this->type_map_; + } + + inline bool options:: + type_map_specified () const + { + return this->type_map_specified_; + } + + inline const NarrowString& options:: + xml_parser () const + { + return this->xml_parser_; + } + + inline bool options:: + xml_parser_specified () const + { + return this->xml_parser_specified_; + } + + inline const bool& options:: + generate_validation () const + { + return this->generate_validation_; + } + + inline const bool& options:: + suppress_validation () const + { + return this->suppress_validation_; + } + + inline const bool& options:: + generate_polymorphic () const + { + return this->generate_polymorphic_; + } + + inline const bool& options:: + generate_noop_impl () const + { + return this->generate_noop_impl_; + } + + inline const bool& options:: + generate_print_impl () const + { + return this->generate_print_impl_; + } + + inline const bool& options:: + generate_test_driver () const + { + return this->generate_test_driver_; + } + + inline const bool& options:: + force_overwrite () const + { + return this->force_overwrite_; + } + + inline const bool& options:: + root_element_first () const + { + return this->root_element_first_; + } + + inline const bool& options:: + root_element_last () const + { + return this->root_element_last_; + } + + inline const NarrowString& options:: + root_element () const + { + return this->root_element_; + } + + inline bool options:: + root_element_specified () const + { + return this->root_element_specified_; + } + + inline const NarrowString& options:: + skel_type_suffix () const + { + return this->skel_type_suffix_; + } + + inline bool options:: + skel_type_suffix_specified () const + { + return this->skel_type_suffix_specified_; + } + + inline const NarrowString& options:: + skel_file_suffix () const + { + return this->skel_file_suffix_; + } + + inline bool options:: + skel_file_suffix_specified () const + { + return this->skel_file_suffix_specified_; + } + + inline const NarrowString& options:: + impl_type_suffix () const + { + return this->impl_type_suffix_; + } + + inline bool options:: + impl_type_suffix_specified () const + { + return this->impl_type_suffix_specified_; + } + + inline const NarrowString& options:: + impl_file_suffix () const + { + return this->impl_file_suffix_; + } + + inline bool options:: + impl_file_suffix_specified () const + { + return this->impl_file_suffix_specified_; + } + } +} + +// Begin epilogue. +// +// +// End epilogue. diff --git a/xsd/xsd/pregenerated/xsd/cxx/tree/options.cxx b/xsd/xsd/pregenerated/xsd/cxx/tree/options.cxx new file mode 100644 index 0000000..17214c1 --- /dev/null +++ b/xsd/xsd/pregenerated/xsd/cxx/tree/options.cxx @@ -0,0 +1,1343 @@ +// -*- C++ -*- +// +// This file was generated by CLI, a command line interface +// compiler for C++. +// + +// Begin prologue. +// +#include <xsd/options-parser.hxx> +// +// End prologue. + +#include <xsd/cxx/tree/options.hxx> + +#include <map> +#include <set> +#include <string> +#include <vector> +#include <utility> +#include <ostream> +#include <sstream> +#include <cstring> + +namespace cli +{ + template <typename X> + struct parser + { + static void + parse (X& x, bool& xs, scanner& s) + { + using namespace std; + + const char* o (s.next ()); + if (s.more ()) + { + string v (s.next ()); + istringstream is (v); + if (!(is >> x && is.peek () == istringstream::traits_type::eof ())) + throw invalid_value (o, v); + } + else + throw missing_value (o); + + xs = true; + } + }; + + template <> + struct parser<bool> + { + static void + parse (bool& x, bool& xs, scanner& s) + { + const char* o (s.next ()); + + if (s.more ()) + { + const char* v (s.next ()); + + if (std::strcmp (v, "1") == 0 || + std::strcmp (v, "true") == 0 || + std::strcmp (v, "TRUE") == 0 || + std::strcmp (v, "True") == 0) + x = true; + else if (std::strcmp (v, "0") == 0 || + std::strcmp (v, "false") == 0 || + std::strcmp (v, "FALSE") == 0 || + std::strcmp (v, "False") == 0) + x = false; + else + throw invalid_value (o, v); + } + else + throw missing_value (o); + + xs = true; + } + }; + + template <> + struct parser<std::string> + { + static void + parse (std::string& x, bool& xs, scanner& s) + { + const char* o (s.next ()); + + if (s.more ()) + x = s.next (); + else + throw missing_value (o); + + xs = true; + } + }; + + template <typename X> + struct parser<std::pair<X, std::size_t> > + { + static void + parse (std::pair<X, std::size_t>& x, bool& xs, scanner& s) + { + x.second = s.position (); + parser<X>::parse (x.first, xs, s); + } + }; + + template <typename X> + struct parser<std::vector<X> > + { + static void + parse (std::vector<X>& c, bool& xs, scanner& s) + { + X x; + bool dummy; + parser<X>::parse (x, dummy, s); + c.push_back (x); + xs = true; + } + }; + + template <typename X, typename C> + struct parser<std::set<X, C> > + { + static void + parse (std::set<X, C>& c, bool& xs, scanner& s) + { + X x; + bool dummy; + parser<X>::parse (x, dummy, s); + c.insert (x); + xs = true; + } + }; + + template <typename K, typename V, typename C> + struct parser<std::map<K, V, C> > + { + static void + parse (std::map<K, V, C>& m, bool& xs, scanner& s) + { + const char* o (s.next ()); + + if (s.more ()) + { + std::size_t pos (s.position ()); + std::string ov (s.next ()); + std::string::size_type p = ov.find ('='); + + K k = K (); + V v = V (); + std::string kstr (ov, 0, p); + std::string vstr (ov, (p != std::string::npos ? p + 1 : ov.size ())); + + int ac (2); + char* av[] = + { + const_cast<char*> (o), + 0 + }; + + bool dummy; + if (!kstr.empty ()) + { + av[1] = const_cast<char*> (kstr.c_str ()); + argv_scanner s (0, ac, av, false, pos); + parser<K>::parse (k, dummy, s); + } + + if (!vstr.empty ()) + { + av[1] = const_cast<char*> (vstr.c_str ()); + argv_scanner s (0, ac, av, false, pos); + parser<V>::parse (v, dummy, s); + } + + m[k] = v; + } + else + throw missing_value (o); + + xs = true; + } + }; + + template <typename K, typename V, typename C> + struct parser<std::multimap<K, V, C> > + { + static void + parse (std::multimap<K, V, C>& m, bool& xs, scanner& s) + { + const char* o (s.next ()); + + if (s.more ()) + { + std::size_t pos (s.position ()); + std::string ov (s.next ()); + std::string::size_type p = ov.find ('='); + + K k = K (); + V v = V (); + std::string kstr (ov, 0, p); + std::string vstr (ov, (p != std::string::npos ? p + 1 : ov.size ())); + + int ac (2); + char* av[] = + { + const_cast<char*> (o), + 0 + }; + + bool dummy; + if (!kstr.empty ()) + { + av[1] = const_cast<char*> (kstr.c_str ()); + argv_scanner s (0, ac, av, false, pos); + parser<K>::parse (k, dummy, s); + } + + if (!vstr.empty ()) + { + av[1] = const_cast<char*> (vstr.c_str ()); + argv_scanner s (0, ac, av, false, pos); + parser<V>::parse (v, dummy, s); + } + + m.insert (typename std::multimap<K, V, C>::value_type (k, v)); + } + else + throw missing_value (o); + + xs = true; + } + }; + + template <typename X, typename T, T X::*M> + void + thunk (X& x, scanner& s) + { + parser<T>::parse (x.*M, s); + } + + template <typename X, bool X::*M> + void + thunk (X& x, scanner& s) + { + s.next (); + x.*M = true; + } + + template <typename X, typename T, T X::*M, bool X::*S> + void + thunk (X& x, scanner& s) + { + parser<T>::parse (x.*M, x.*S, s); + } +} + +#include <map> + +namespace CXX +{ + namespace Tree + { + // options + // + + options:: + options () + : generate_polymorphic_ (), + polymorphic_type_ (), + polymorphic_type_specified_ (false), + polymorphic_type_all_ (), + polymorphic_plate_ (0), + polymorphic_plate_specified_ (false), + ordered_type_ (), + ordered_type_specified_ (false), + ordered_type_derived_ (), + ordered_type_mixed_ (), + ordered_type_all_ (), + order_container_ (), + order_container_specified_ (false), + generate_serialization_ (), + generate_ostream_ (), + generate_doxygen_ (), + generate_comparison_ (), + generate_default_ctor_ (), + generate_from_base_ctor_ (), + suppress_assignment_ (), + generate_detach_ (), + generate_wildcard_ (), + generate_any_type_ (), + generate_insertion_ (), + generate_insertion_specified_ (false), + generate_extraction_ (), + generate_extraction_specified_ (false), + generate_forward_ (), + suppress_parsing_ (), + generate_element_type_ (), + generate_element_map_ (), + generate_intellisense_ (), + omit_default_attributes_ (), + type_naming_ ("knr"), + type_naming_specified_ (false), + function_naming_ ("knr"), + function_naming_specified_ (false), + type_regex_ (), + type_regex_specified_ (false), + accessor_regex_ (), + accessor_regex_specified_ (false), + one_accessor_regex_ (), + one_accessor_regex_specified_ (false), + opt_accessor_regex_ (), + opt_accessor_regex_specified_ (false), + seq_accessor_regex_ (), + seq_accessor_regex_specified_ (false), + modifier_regex_ (), + modifier_regex_specified_ (false), + one_modifier_regex_ (), + one_modifier_regex_specified_ (false), + opt_modifier_regex_ (), + opt_modifier_regex_specified_ (false), + seq_modifier_regex_ (), + seq_modifier_regex_specified_ (false), + parser_regex_ (), + parser_regex_specified_ (false), + serializer_regex_ (), + serializer_regex_specified_ (false), + const_regex_ (), + const_regex_specified_ (false), + enumerator_regex_ (), + enumerator_regex_specified_ (false), + element_type_regex_ (), + element_type_regex_specified_ (false), + name_regex_trace_ (), + root_element_first_ (), + root_element_last_ (), + root_element_all_ (), + root_element_none_ (), + root_element_ (), + root_element_specified_ (false), + custom_type_ (), + custom_type_specified_ (false), + custom_type_regex_ (), + custom_type_regex_specified_ (false), + parts_ (1), + parts_specified_ (false), + parts_suffix_ ("-"), + parts_suffix_specified_ (false) + { + } + + options:: + options (int& argc, + char** argv, + bool erase, + ::cli::unknown_mode opt, + ::cli::unknown_mode arg) + : generate_polymorphic_ (), + polymorphic_type_ (), + polymorphic_type_specified_ (false), + polymorphic_type_all_ (), + polymorphic_plate_ (0), + polymorphic_plate_specified_ (false), + ordered_type_ (), + ordered_type_specified_ (false), + ordered_type_derived_ (), + ordered_type_mixed_ (), + ordered_type_all_ (), + order_container_ (), + order_container_specified_ (false), + generate_serialization_ (), + generate_ostream_ (), + generate_doxygen_ (), + generate_comparison_ (), + generate_default_ctor_ (), + generate_from_base_ctor_ (), + suppress_assignment_ (), + generate_detach_ (), + generate_wildcard_ (), + generate_any_type_ (), + generate_insertion_ (), + generate_insertion_specified_ (false), + generate_extraction_ (), + generate_extraction_specified_ (false), + generate_forward_ (), + suppress_parsing_ (), + generate_element_type_ (), + generate_element_map_ (), + generate_intellisense_ (), + omit_default_attributes_ (), + type_naming_ ("knr"), + type_naming_specified_ (false), + function_naming_ ("knr"), + function_naming_specified_ (false), + type_regex_ (), + type_regex_specified_ (false), + accessor_regex_ (), + accessor_regex_specified_ (false), + one_accessor_regex_ (), + one_accessor_regex_specified_ (false), + opt_accessor_regex_ (), + opt_accessor_regex_specified_ (false), + seq_accessor_regex_ (), + seq_accessor_regex_specified_ (false), + modifier_regex_ (), + modifier_regex_specified_ (false), + one_modifier_regex_ (), + one_modifier_regex_specified_ (false), + opt_modifier_regex_ (), + opt_modifier_regex_specified_ (false), + seq_modifier_regex_ (), + seq_modifier_regex_specified_ (false), + parser_regex_ (), + parser_regex_specified_ (false), + serializer_regex_ (), + serializer_regex_specified_ (false), + const_regex_ (), + const_regex_specified_ (false), + enumerator_regex_ (), + enumerator_regex_specified_ (false), + element_type_regex_ (), + element_type_regex_specified_ (false), + name_regex_trace_ (), + root_element_first_ (), + root_element_last_ (), + root_element_all_ (), + root_element_none_ (), + root_element_ (), + root_element_specified_ (false), + custom_type_ (), + custom_type_specified_ (false), + custom_type_regex_ (), + custom_type_regex_specified_ (false), + parts_ (1), + parts_specified_ (false), + parts_suffix_ ("-"), + parts_suffix_specified_ (false) + { + ::cli::argv_scanner s (argc, argv, erase); + _parse (s, opt, arg); + } + + options:: + options (int start, + int& argc, + char** argv, + bool erase, + ::cli::unknown_mode opt, + ::cli::unknown_mode arg) + : generate_polymorphic_ (), + polymorphic_type_ (), + polymorphic_type_specified_ (false), + polymorphic_type_all_ (), + polymorphic_plate_ (0), + polymorphic_plate_specified_ (false), + ordered_type_ (), + ordered_type_specified_ (false), + ordered_type_derived_ (), + ordered_type_mixed_ (), + ordered_type_all_ (), + order_container_ (), + order_container_specified_ (false), + generate_serialization_ (), + generate_ostream_ (), + generate_doxygen_ (), + generate_comparison_ (), + generate_default_ctor_ (), + generate_from_base_ctor_ (), + suppress_assignment_ (), + generate_detach_ (), + generate_wildcard_ (), + generate_any_type_ (), + generate_insertion_ (), + generate_insertion_specified_ (false), + generate_extraction_ (), + generate_extraction_specified_ (false), + generate_forward_ (), + suppress_parsing_ (), + generate_element_type_ (), + generate_element_map_ (), + generate_intellisense_ (), + omit_default_attributes_ (), + type_naming_ ("knr"), + type_naming_specified_ (false), + function_naming_ ("knr"), + function_naming_specified_ (false), + type_regex_ (), + type_regex_specified_ (false), + accessor_regex_ (), + accessor_regex_specified_ (false), + one_accessor_regex_ (), + one_accessor_regex_specified_ (false), + opt_accessor_regex_ (), + opt_accessor_regex_specified_ (false), + seq_accessor_regex_ (), + seq_accessor_regex_specified_ (false), + modifier_regex_ (), + modifier_regex_specified_ (false), + one_modifier_regex_ (), + one_modifier_regex_specified_ (false), + opt_modifier_regex_ (), + opt_modifier_regex_specified_ (false), + seq_modifier_regex_ (), + seq_modifier_regex_specified_ (false), + parser_regex_ (), + parser_regex_specified_ (false), + serializer_regex_ (), + serializer_regex_specified_ (false), + const_regex_ (), + const_regex_specified_ (false), + enumerator_regex_ (), + enumerator_regex_specified_ (false), + element_type_regex_ (), + element_type_regex_specified_ (false), + name_regex_trace_ (), + root_element_first_ (), + root_element_last_ (), + root_element_all_ (), + root_element_none_ (), + root_element_ (), + root_element_specified_ (false), + custom_type_ (), + custom_type_specified_ (false), + custom_type_regex_ (), + custom_type_regex_specified_ (false), + parts_ (1), + parts_specified_ (false), + parts_suffix_ ("-"), + parts_suffix_specified_ (false) + { + ::cli::argv_scanner s (start, argc, argv, erase); + _parse (s, opt, arg); + } + + options:: + options (int& argc, + char** argv, + int& end, + bool erase, + ::cli::unknown_mode opt, + ::cli::unknown_mode arg) + : generate_polymorphic_ (), + polymorphic_type_ (), + polymorphic_type_specified_ (false), + polymorphic_type_all_ (), + polymorphic_plate_ (0), + polymorphic_plate_specified_ (false), + ordered_type_ (), + ordered_type_specified_ (false), + ordered_type_derived_ (), + ordered_type_mixed_ (), + ordered_type_all_ (), + order_container_ (), + order_container_specified_ (false), + generate_serialization_ (), + generate_ostream_ (), + generate_doxygen_ (), + generate_comparison_ (), + generate_default_ctor_ (), + generate_from_base_ctor_ (), + suppress_assignment_ (), + generate_detach_ (), + generate_wildcard_ (), + generate_any_type_ (), + generate_insertion_ (), + generate_insertion_specified_ (false), + generate_extraction_ (), + generate_extraction_specified_ (false), + generate_forward_ (), + suppress_parsing_ (), + generate_element_type_ (), + generate_element_map_ (), + generate_intellisense_ (), + omit_default_attributes_ (), + type_naming_ ("knr"), + type_naming_specified_ (false), + function_naming_ ("knr"), + function_naming_specified_ (false), + type_regex_ (), + type_regex_specified_ (false), + accessor_regex_ (), + accessor_regex_specified_ (false), + one_accessor_regex_ (), + one_accessor_regex_specified_ (false), + opt_accessor_regex_ (), + opt_accessor_regex_specified_ (false), + seq_accessor_regex_ (), + seq_accessor_regex_specified_ (false), + modifier_regex_ (), + modifier_regex_specified_ (false), + one_modifier_regex_ (), + one_modifier_regex_specified_ (false), + opt_modifier_regex_ (), + opt_modifier_regex_specified_ (false), + seq_modifier_regex_ (), + seq_modifier_regex_specified_ (false), + parser_regex_ (), + parser_regex_specified_ (false), + serializer_regex_ (), + serializer_regex_specified_ (false), + const_regex_ (), + const_regex_specified_ (false), + enumerator_regex_ (), + enumerator_regex_specified_ (false), + element_type_regex_ (), + element_type_regex_specified_ (false), + name_regex_trace_ (), + root_element_first_ (), + root_element_last_ (), + root_element_all_ (), + root_element_none_ (), + root_element_ (), + root_element_specified_ (false), + custom_type_ (), + custom_type_specified_ (false), + custom_type_regex_ (), + custom_type_regex_specified_ (false), + parts_ (1), + parts_specified_ (false), + parts_suffix_ ("-"), + parts_suffix_specified_ (false) + { + ::cli::argv_scanner s (argc, argv, erase); + _parse (s, opt, arg); + end = s.end (); + } + + options:: + options (int start, + int& argc, + char** argv, + int& end, + bool erase, + ::cli::unknown_mode opt, + ::cli::unknown_mode arg) + : generate_polymorphic_ (), + polymorphic_type_ (), + polymorphic_type_specified_ (false), + polymorphic_type_all_ (), + polymorphic_plate_ (0), + polymorphic_plate_specified_ (false), + ordered_type_ (), + ordered_type_specified_ (false), + ordered_type_derived_ (), + ordered_type_mixed_ (), + ordered_type_all_ (), + order_container_ (), + order_container_specified_ (false), + generate_serialization_ (), + generate_ostream_ (), + generate_doxygen_ (), + generate_comparison_ (), + generate_default_ctor_ (), + generate_from_base_ctor_ (), + suppress_assignment_ (), + generate_detach_ (), + generate_wildcard_ (), + generate_any_type_ (), + generate_insertion_ (), + generate_insertion_specified_ (false), + generate_extraction_ (), + generate_extraction_specified_ (false), + generate_forward_ (), + suppress_parsing_ (), + generate_element_type_ (), + generate_element_map_ (), + generate_intellisense_ (), + omit_default_attributes_ (), + type_naming_ ("knr"), + type_naming_specified_ (false), + function_naming_ ("knr"), + function_naming_specified_ (false), + type_regex_ (), + type_regex_specified_ (false), + accessor_regex_ (), + accessor_regex_specified_ (false), + one_accessor_regex_ (), + one_accessor_regex_specified_ (false), + opt_accessor_regex_ (), + opt_accessor_regex_specified_ (false), + seq_accessor_regex_ (), + seq_accessor_regex_specified_ (false), + modifier_regex_ (), + modifier_regex_specified_ (false), + one_modifier_regex_ (), + one_modifier_regex_specified_ (false), + opt_modifier_regex_ (), + opt_modifier_regex_specified_ (false), + seq_modifier_regex_ (), + seq_modifier_regex_specified_ (false), + parser_regex_ (), + parser_regex_specified_ (false), + serializer_regex_ (), + serializer_regex_specified_ (false), + const_regex_ (), + const_regex_specified_ (false), + enumerator_regex_ (), + enumerator_regex_specified_ (false), + element_type_regex_ (), + element_type_regex_specified_ (false), + name_regex_trace_ (), + root_element_first_ (), + root_element_last_ (), + root_element_all_ (), + root_element_none_ (), + root_element_ (), + root_element_specified_ (false), + custom_type_ (), + custom_type_specified_ (false), + custom_type_regex_ (), + custom_type_regex_specified_ (false), + parts_ (1), + parts_specified_ (false), + parts_suffix_ ("-"), + parts_suffix_specified_ (false) + { + ::cli::argv_scanner s (start, argc, argv, erase); + _parse (s, opt, arg); + end = s.end (); + } + + options:: + options (::cli::scanner& s, + ::cli::unknown_mode opt, + ::cli::unknown_mode arg) + : generate_polymorphic_ (), + polymorphic_type_ (), + polymorphic_type_specified_ (false), + polymorphic_type_all_ (), + polymorphic_plate_ (0), + polymorphic_plate_specified_ (false), + ordered_type_ (), + ordered_type_specified_ (false), + ordered_type_derived_ (), + ordered_type_mixed_ (), + ordered_type_all_ (), + order_container_ (), + order_container_specified_ (false), + generate_serialization_ (), + generate_ostream_ (), + generate_doxygen_ (), + generate_comparison_ (), + generate_default_ctor_ (), + generate_from_base_ctor_ (), + suppress_assignment_ (), + generate_detach_ (), + generate_wildcard_ (), + generate_any_type_ (), + generate_insertion_ (), + generate_insertion_specified_ (false), + generate_extraction_ (), + generate_extraction_specified_ (false), + generate_forward_ (), + suppress_parsing_ (), + generate_element_type_ (), + generate_element_map_ (), + generate_intellisense_ (), + omit_default_attributes_ (), + type_naming_ ("knr"), + type_naming_specified_ (false), + function_naming_ ("knr"), + function_naming_specified_ (false), + type_regex_ (), + type_regex_specified_ (false), + accessor_regex_ (), + accessor_regex_specified_ (false), + one_accessor_regex_ (), + one_accessor_regex_specified_ (false), + opt_accessor_regex_ (), + opt_accessor_regex_specified_ (false), + seq_accessor_regex_ (), + seq_accessor_regex_specified_ (false), + modifier_regex_ (), + modifier_regex_specified_ (false), + one_modifier_regex_ (), + one_modifier_regex_specified_ (false), + opt_modifier_regex_ (), + opt_modifier_regex_specified_ (false), + seq_modifier_regex_ (), + seq_modifier_regex_specified_ (false), + parser_regex_ (), + parser_regex_specified_ (false), + serializer_regex_ (), + serializer_regex_specified_ (false), + const_regex_ (), + const_regex_specified_ (false), + enumerator_regex_ (), + enumerator_regex_specified_ (false), + element_type_regex_ (), + element_type_regex_specified_ (false), + name_regex_trace_ (), + root_element_first_ (), + root_element_last_ (), + root_element_all_ (), + root_element_none_ (), + root_element_ (), + root_element_specified_ (false), + custom_type_ (), + custom_type_specified_ (false), + custom_type_regex_ (), + custom_type_regex_specified_ (false), + parts_ (1), + parts_specified_ (false), + parts_suffix_ ("-"), + parts_suffix_specified_ (false) + { + _parse (s, opt, arg); + } + + ::cli::usage_para options:: + print_usage (::std::wostream& os, ::cli::usage_para p) + { + CLI_POTENTIALLY_UNUSED (os); + + if (p == ::cli::usage_para::text) + os << ::std::endl; + + os << "--generate-polymorphic Generate polymorphism-aware code." << ::std::endl; + + os << "--polymorphic-type <type> Indicate that <type> is a root of a polymorphic" << ::std::endl + << " type hierarchy." << ::std::endl; + + os << "--polymorphic-type-all Indicate that all types should be treated as" << ::std::endl + << " polymorphic." << ::std::endl; + + os << "--polymorphic-plate <num> Specify the polymorphic map plate the generated" << ::std::endl + << " code should register on." << ::std::endl; + + os << "--ordered-type <type> Indicate that element order in <type> is" << ::std::endl + << " significant." << ::std::endl; + + os << "--ordered-type-derived Automatically treat types derived from ordered" << ::std::endl + << " bases as also ordered." << ::std::endl; + + os << "--ordered-type-mixed Automatically treat complex types with mixed" << ::std::endl + << " content as ordered." << ::std::endl; + + os << "--ordered-type-all Indicate that element order in all types is" << ::std::endl + << " significant." << ::std::endl; + + os << "--order-container <type> Specify a custom class template that should be" << ::std::endl + << " used as a container for the content order in" << ::std::endl + << " ordered types instead of the default std::vector." << ::std::endl; + + os << "--generate-serialization Generate serialization functions." << ::std::endl; + + os << "--generate-ostream Generate ostream insertion operators (operator<<)" << ::std::endl + << " for generated types." << ::std::endl; + + os << "--generate-doxygen Generate documentation comments suitable for" << ::std::endl + << " extraction by the Doxygen documentation system." << ::std::endl; + + os << "--generate-comparison Generate comparison operators (operator== and" << ::std::endl + << " operator!=) for complex types." << ::std::endl; + + os << "--generate-default-ctor Generate default constructors even for types that" << ::std::endl + << " have required members." << ::std::endl; + + os << "--generate-from-base-ctor Generate constructors that expect an instance of a" << ::std::endl + << " base type followed by all required members." << ::std::endl; + + os << "--suppress-assignment Suppress the generation of copy assignment" << ::std::endl + << " operators for complex types." << ::std::endl; + + os << "--generate-detach Generate detach functions for required elements" << ::std::endl + << " and attributes." << ::std::endl; + + os << "--generate-wildcard Generate accessors and modifiers as well as" << ::std::endl + << " parsing and serialization code for XML Schema" << ::std::endl + << " wildcards (any and anyAttribute)." << ::std::endl; + + os << "--generate-any-type Extract and store content of the XML Schema" << ::std::endl + << " anyType type as a DOM fragment." << ::std::endl; + + os << "--generate-insertion <os> Generate data representation stream insertion" << ::std::endl + << " operators for the <os> output stream type." << ::std::endl; + + os << "--generate-extraction <is> Generate data representation stream extraction" << ::std::endl + << " constructors for the <is> input stream type." << ::std::endl; + + os << "--generate-forward Generate a separate header file with forward" << ::std::endl + << " declarations for the types being generated." << ::std::endl; + + os << "--suppress-parsing Suppress the generation of the parsing functions" << ::std::endl + << " and constructors." << ::std::endl; + + os << "--generate-element-type Generate types instead of parsing and" << ::std::endl + << " serialization functions for root elements." << ::std::endl; + + os << "--generate-element-map Generate a root element map that allows uniform" << ::std::endl + << " parsing and serialization of multiple root" << ::std::endl + << " elements." << ::std::endl; + + os << "--generate-intellisense Generate workarounds for IntelliSense bugs in" << ::std::endl + << " Visual Studio 2005 (8.0)." << ::std::endl; + + os << "--omit-default-attributes Omit attributes with default and fixed values from" << ::std::endl + << " serialized XML documents." << ::std::endl; + + os << "--type-naming <style> Specify the type naming convention that should be" << ::std::endl + << " used in the generated code." << ::std::endl; + + os << "--function-naming <style> Specify the function naming convention that should" << ::std::endl + << " be used in the generated code." << ::std::endl; + + os << "--type-regex <regex> Add <regex> to the list of regular expressions" << ::std::endl + << " used to translate XML Schema type names to C++" << ::std::endl + << " type names." << ::std::endl; + + os << "--accessor-regex <regex> Add <regex> to the list of regular expressions" << ::std::endl + << " used to translate XML Schema names of" << ::std::endl + << " elements/attributes to C++ accessor function" << ::std::endl + << " names." << ::std::endl; + + os << "--one-accessor-regex <regex> Add <regex> to the list of regular expressions" << ::std::endl + << " used to translate XML Schema names of" << ::std::endl + << " elements/attributes with cardinality one to C++" << ::std::endl + << " accessor function names." << ::std::endl; + + os << "--opt-accessor-regex <regex> Add <regex> to the list of regular expressions" << ::std::endl + << " used to translate XML Schema names of" << ::std::endl + << " elements/attributes with cardinality optional to" << ::std::endl + << " C++ accessor function names." << ::std::endl; + + os << "--seq-accessor-regex <regex> Add <regex> to the list of regular expressions" << ::std::endl + << " used to translate XML Schema names of" << ::std::endl + << " elements/attributes with cardinality sequence to" << ::std::endl + << " C++ accessor function names." << ::std::endl; + + os << "--modifier-regex <regex> Add <regex> to the list of regular expressions" << ::std::endl + << " used to translate XML Schema names of" << ::std::endl + << " elements/attributes to C++ modifier function" << ::std::endl + << " names." << ::std::endl; + + os << "--one-modifier-regex <regex> Add <regex> to the list of regular expressions" << ::std::endl + << " used to translate XML Schema names of" << ::std::endl + << " elements/attributes with cardinality one to C++" << ::std::endl + << " modifier function names." << ::std::endl; + + os << "--opt-modifier-regex <regex> Add <regex> to the list of regular expressions" << ::std::endl + << " used to translate XML Schema names of" << ::std::endl + << " elements/attributes with cardinality optional to" << ::std::endl + << " C++ modifier function names." << ::std::endl; + + os << "--seq-modifier-regex <regex> Add <regex> to the list of regular expressions" << ::std::endl + << " used to translate XML Schema names of" << ::std::endl + << " elements/attributes with cardinality sequence to" << ::std::endl + << " C++ modifier function names." << ::std::endl; + + os << "--parser-regex <regex> Add <regex> to the list of regular expressions" << ::std::endl + << " used to translate XML Schema element names to C++" << ::std::endl + << " parsing function names." << ::std::endl; + + os << "--serializer-regex <regex> Add <regex> to the list of regular expressions" << ::std::endl + << " used to translate XML Schema element names to C++" << ::std::endl + << " serialization function names." << ::std::endl; + + os << "--const-regex <regex> Add <regex> to the list of regular expressions" << ::std::endl + << " used to translate XML Schema-derived names to C++" << ::std::endl + << " constant names." << ::std::endl; + + os << "--enumerator-regex <regex> Add <regex> to the list of regular expressions" << ::std::endl + << " used to translate XML Schema enumeration values to" << ::std::endl + << " C++ enumerator names." << ::std::endl; + + os << "--element-type-regex <regex> Add <regex> to the list of regular expressions" << ::std::endl + << " used to translate XML Schema element names to C++" << ::std::endl + << " element type names." << ::std::endl; + + os << "--name-regex-trace Trace the process of applying regular expressions" << ::std::endl + << " specified with the name transformation options." << ::std::endl; + + os << "--root-element-first Treat only the first global element as a document" << ::std::endl + << " root." << ::std::endl; + + os << "--root-element-last Treat only the last global element as a document" << ::std::endl + << " root." << ::std::endl; + + os << "--root-element-all Treat all global elements as document roots." << ::std::endl; + + os << "--root-element-none Do not treat any global elements as document" << ::std::endl + << " roots." << ::std::endl; + + os << "--root-element <element> Treat only <element> as a document root." << ::std::endl; + + os << "--custom-type <map> Use a custom C++ type instead of the generated" << ::std::endl + << " class." << ::std::endl; + + os << "--custom-type-regex <regex> Use custom C++ types instead of the generated" << ::std::endl + << " classes." << ::std::endl; + + os << "--parts <num> Split generated source code into <num> parts." << ::std::endl; + + os << "--parts-suffix <suffix> Use <suffix> instead of the default '-' to" << ::std::endl + << " separate the file name from the part number." << ::std::endl; + + p = ::cli::usage_para::option; + + return p; + } + + typedef + std::map<std::string, void (*) (options&, ::cli::scanner&)> + _cli_options_map; + + static _cli_options_map _cli_options_map_; + + struct _cli_options_map_init + { + _cli_options_map_init () + { + _cli_options_map_["--generate-polymorphic"] = + &::cli::thunk< options, &options::generate_polymorphic_ >; + _cli_options_map_["--polymorphic-type"] = + &::cli::thunk< options, NarrowStrings, &options::polymorphic_type_, + &options::polymorphic_type_specified_ >; + _cli_options_map_["--polymorphic-type-all"] = + &::cli::thunk< options, &options::polymorphic_type_all_ >; + _cli_options_map_["--polymorphic-plate"] = + &::cli::thunk< options, unsigned long, &options::polymorphic_plate_, + &options::polymorphic_plate_specified_ >; + _cli_options_map_["--ordered-type"] = + &::cli::thunk< options, NarrowStrings, &options::ordered_type_, + &options::ordered_type_specified_ >; + _cli_options_map_["--ordered-type-derived"] = + &::cli::thunk< options, &options::ordered_type_derived_ >; + _cli_options_map_["--ordered-type-mixed"] = + &::cli::thunk< options, &options::ordered_type_mixed_ >; + _cli_options_map_["--ordered-type-all"] = + &::cli::thunk< options, &options::ordered_type_all_ >; + _cli_options_map_["--order-container"] = + &::cli::thunk< options, NarrowString, &options::order_container_, + &options::order_container_specified_ >; + _cli_options_map_["--generate-serialization"] = + &::cli::thunk< options, &options::generate_serialization_ >; + _cli_options_map_["--generate-ostream"] = + &::cli::thunk< options, &options::generate_ostream_ >; + _cli_options_map_["--generate-doxygen"] = + &::cli::thunk< options, &options::generate_doxygen_ >; + _cli_options_map_["--generate-comparison"] = + &::cli::thunk< options, &options::generate_comparison_ >; + _cli_options_map_["--generate-default-ctor"] = + &::cli::thunk< options, &options::generate_default_ctor_ >; + _cli_options_map_["--generate-from-base-ctor"] = + &::cli::thunk< options, &options::generate_from_base_ctor_ >; + _cli_options_map_["--suppress-assignment"] = + &::cli::thunk< options, &options::suppress_assignment_ >; + _cli_options_map_["--generate-detach"] = + &::cli::thunk< options, &options::generate_detach_ >; + _cli_options_map_["--generate-wildcard"] = + &::cli::thunk< options, &options::generate_wildcard_ >; + _cli_options_map_["--generate-any-type"] = + &::cli::thunk< options, &options::generate_any_type_ >; + _cli_options_map_["--generate-insertion"] = + &::cli::thunk< options, NarrowStrings, &options::generate_insertion_, + &options::generate_insertion_specified_ >; + _cli_options_map_["--generate-extraction"] = + &::cli::thunk< options, NarrowStrings, &options::generate_extraction_, + &options::generate_extraction_specified_ >; + _cli_options_map_["--generate-forward"] = + &::cli::thunk< options, &options::generate_forward_ >; + _cli_options_map_["--suppress-parsing"] = + &::cli::thunk< options, &options::suppress_parsing_ >; + _cli_options_map_["--generate-element-type"] = + &::cli::thunk< options, &options::generate_element_type_ >; + _cli_options_map_["--generate-element-map"] = + &::cli::thunk< options, &options::generate_element_map_ >; + _cli_options_map_["--generate-intellisense"] = + &::cli::thunk< options, &options::generate_intellisense_ >; + _cli_options_map_["--omit-default-attributes"] = + &::cli::thunk< options, &options::omit_default_attributes_ >; + _cli_options_map_["--type-naming"] = + &::cli::thunk< options, NarrowString, &options::type_naming_, + &options::type_naming_specified_ >; + _cli_options_map_["--function-naming"] = + &::cli::thunk< options, NarrowString, &options::function_naming_, + &options::function_naming_specified_ >; + _cli_options_map_["--type-regex"] = + &::cli::thunk< options, NarrowStrings, &options::type_regex_, + &options::type_regex_specified_ >; + _cli_options_map_["--accessor-regex"] = + &::cli::thunk< options, NarrowStrings, &options::accessor_regex_, + &options::accessor_regex_specified_ >; + _cli_options_map_["--one-accessor-regex"] = + &::cli::thunk< options, NarrowStrings, &options::one_accessor_regex_, + &options::one_accessor_regex_specified_ >; + _cli_options_map_["--opt-accessor-regex"] = + &::cli::thunk< options, NarrowStrings, &options::opt_accessor_regex_, + &options::opt_accessor_regex_specified_ >; + _cli_options_map_["--seq-accessor-regex"] = + &::cli::thunk< options, NarrowStrings, &options::seq_accessor_regex_, + &options::seq_accessor_regex_specified_ >; + _cli_options_map_["--modifier-regex"] = + &::cli::thunk< options, NarrowStrings, &options::modifier_regex_, + &options::modifier_regex_specified_ >; + _cli_options_map_["--one-modifier-regex"] = + &::cli::thunk< options, NarrowStrings, &options::one_modifier_regex_, + &options::one_modifier_regex_specified_ >; + _cli_options_map_["--opt-modifier-regex"] = + &::cli::thunk< options, NarrowStrings, &options::opt_modifier_regex_, + &options::opt_modifier_regex_specified_ >; + _cli_options_map_["--seq-modifier-regex"] = + &::cli::thunk< options, NarrowStrings, &options::seq_modifier_regex_, + &options::seq_modifier_regex_specified_ >; + _cli_options_map_["--parser-regex"] = + &::cli::thunk< options, NarrowStrings, &options::parser_regex_, + &options::parser_regex_specified_ >; + _cli_options_map_["--serializer-regex"] = + &::cli::thunk< options, NarrowStrings, &options::serializer_regex_, + &options::serializer_regex_specified_ >; + _cli_options_map_["--const-regex"] = + &::cli::thunk< options, NarrowStrings, &options::const_regex_, + &options::const_regex_specified_ >; + _cli_options_map_["--enumerator-regex"] = + &::cli::thunk< options, NarrowStrings, &options::enumerator_regex_, + &options::enumerator_regex_specified_ >; + _cli_options_map_["--element-type-regex"] = + &::cli::thunk< options, NarrowStrings, &options::element_type_regex_, + &options::element_type_regex_specified_ >; + _cli_options_map_["--name-regex-trace"] = + &::cli::thunk< options, &options::name_regex_trace_ >; + _cli_options_map_["--root-element-first"] = + &::cli::thunk< options, &options::root_element_first_ >; + _cli_options_map_["--root-element-last"] = + &::cli::thunk< options, &options::root_element_last_ >; + _cli_options_map_["--root-element-all"] = + &::cli::thunk< options, &options::root_element_all_ >; + _cli_options_map_["--root-element-none"] = + &::cli::thunk< options, &options::root_element_none_ >; + _cli_options_map_["--root-element"] = + &::cli::thunk< options, NarrowStrings, &options::root_element_, + &options::root_element_specified_ >; + _cli_options_map_["--custom-type"] = + &::cli::thunk< options, NarrowStrings, &options::custom_type_, + &options::custom_type_specified_ >; + _cli_options_map_["--custom-type-regex"] = + &::cli::thunk< options, NarrowStrings, &options::custom_type_regex_, + &options::custom_type_regex_specified_ >; + _cli_options_map_["--parts"] = + &::cli::thunk< options, std::size_t, &options::parts_, + &options::parts_specified_ >; + _cli_options_map_["--parts-suffix"] = + &::cli::thunk< options, NarrowString, &options::parts_suffix_, + &options::parts_suffix_specified_ >; + } + }; + + static _cli_options_map_init _cli_options_map_init_; + + bool options:: + _parse (const char* o, ::cli::scanner& s) + { + _cli_options_map::const_iterator i (_cli_options_map_.find (o)); + + if (i != _cli_options_map_.end ()) + { + (*(i->second)) (*this, s); + return true; + } + + // options base + // + if (::CXX::options::_parse (o, s)) + return true; + + return false; + } + + bool options:: + _parse (::cli::scanner& s, + ::cli::unknown_mode opt_mode, + ::cli::unknown_mode arg_mode) + { + // Can't skip combined flags (--no-combined-flags). + // + assert (opt_mode != ::cli::unknown_mode::skip); + + bool r = false; + bool opt = true; + + while (s.more ()) + { + const char* o = s.peek (); + + if (std::strcmp (o, "--") == 0) + { + opt = false; + s.skip (); + r = true; + continue; + } + + if (opt) + { + if (_parse (o, s)) + { + r = true; + continue; + } + + if (std::strncmp (o, "-", 1) == 0 && o[1] != '\0') + { + // Handle combined option values. + // + std::string co; + if (const char* v = std::strchr (o, '=')) + { + co.assign (o, 0, v - o); + ++v; + + int ac (2); + char* av[] = + { + const_cast<char*> (co.c_str ()), + const_cast<char*> (v) + }; + + ::cli::argv_scanner ns (0, ac, av); + + if (_parse (co.c_str (), ns)) + { + // Parsed the option but not its value? + // + if (ns.end () != 2) + throw ::cli::invalid_value (co, v); + + s.next (); + r = true; + continue; + } + else + { + // Set the unknown option and fall through. + // + o = co.c_str (); + } + } + + // Handle combined flags. + // + char cf[3]; + { + const char* p = o + 1; + for (; *p != '\0'; ++p) + { + if (!((*p >= 'a' && *p <= 'z') || + (*p >= 'A' && *p <= 'Z') || + (*p >= '0' && *p <= '9'))) + break; + } + + if (*p == '\0') + { + for (p = o + 1; *p != '\0'; ++p) + { + std::strcpy (cf, "-"); + cf[1] = *p; + cf[2] = '\0'; + + int ac (1); + char* av[] = + { + cf + }; + + ::cli::argv_scanner ns (0, ac, av); + + if (!_parse (cf, ns)) + break; + } + + if (*p == '\0') + { + // All handled. + // + s.next (); + r = true; + continue; + } + else + { + // Set the unknown option and fall through. + // + o = cf; + } + } + } + + switch (opt_mode) + { + case ::cli::unknown_mode::skip: + { + s.skip (); + r = true; + continue; + } + case ::cli::unknown_mode::stop: + { + break; + } + case ::cli::unknown_mode::fail: + { + throw ::cli::unknown_option (o); + } + } + + break; + } + } + + switch (arg_mode) + { + case ::cli::unknown_mode::skip: + { + s.skip (); + r = true; + continue; + } + case ::cli::unknown_mode::stop: + { + break; + } + case ::cli::unknown_mode::fail: + { + throw ::cli::unknown_argument (o); + } + } + + break; + } + + return r; + } + } +} + +// Begin epilogue. +// +// +// End epilogue. + diff --git a/xsd/xsd/pregenerated/xsd/cxx/tree/options.hxx b/xsd/xsd/pregenerated/xsd/cxx/tree/options.hxx new file mode 100644 index 0000000..f5a808c --- /dev/null +++ b/xsd/xsd/pregenerated/xsd/cxx/tree/options.hxx @@ -0,0 +1,414 @@ +// -*- C++ -*- +// +// This file was generated by CLI, a command line interface +// compiler for C++. +// + +#ifndef XSD_CXX_TREE_OPTIONS_HXX +#define XSD_CXX_TREE_OPTIONS_HXX + +// Begin prologue. +// +// +// End prologue. + +#include <cstddef> + +#include <xsd/types.hxx> + +#include <xsd/cxx/options.hxx> + +namespace CXX +{ + namespace Tree + { + class options: public ::CXX::options + { + public: + options (); + + options (int& argc, + char** argv, + bool erase = false, + ::cli::unknown_mode option = ::cli::unknown_mode::fail, + ::cli::unknown_mode argument = ::cli::unknown_mode::stop); + + options (int start, + int& argc, + char** argv, + bool erase = false, + ::cli::unknown_mode option = ::cli::unknown_mode::fail, + ::cli::unknown_mode argument = ::cli::unknown_mode::stop); + + options (int& argc, + char** argv, + int& end, + bool erase = false, + ::cli::unknown_mode option = ::cli::unknown_mode::fail, + ::cli::unknown_mode argument = ::cli::unknown_mode::stop); + + options (int start, + int& argc, + char** argv, + int& end, + bool erase = false, + ::cli::unknown_mode option = ::cli::unknown_mode::fail, + ::cli::unknown_mode argument = ::cli::unknown_mode::stop); + + options (::cli::scanner&, + ::cli::unknown_mode option = ::cli::unknown_mode::fail, + ::cli::unknown_mode argument = ::cli::unknown_mode::stop); + + // Option accessors. + // + const bool& + generate_polymorphic () const; + + const NarrowStrings& + polymorphic_type () const; + + bool + polymorphic_type_specified () const; + + const bool& + polymorphic_type_all () const; + + const unsigned long& + polymorphic_plate () const; + + bool + polymorphic_plate_specified () const; + + const NarrowStrings& + ordered_type () const; + + bool + ordered_type_specified () const; + + const bool& + ordered_type_derived () const; + + const bool& + ordered_type_mixed () const; + + const bool& + ordered_type_all () const; + + const NarrowString& + order_container () const; + + bool + order_container_specified () const; + + const bool& + generate_serialization () const; + + const bool& + generate_ostream () const; + + const bool& + generate_doxygen () const; + + const bool& + generate_comparison () const; + + const bool& + generate_default_ctor () const; + + const bool& + generate_from_base_ctor () const; + + const bool& + suppress_assignment () const; + + const bool& + generate_detach () const; + + const bool& + generate_wildcard () const; + + const bool& + generate_any_type () const; + + const NarrowStrings& + generate_insertion () const; + + bool + generate_insertion_specified () const; + + const NarrowStrings& + generate_extraction () const; + + bool + generate_extraction_specified () const; + + const bool& + generate_forward () const; + + const bool& + suppress_parsing () const; + + const bool& + generate_element_type () const; + + const bool& + generate_element_map () const; + + const bool& + generate_intellisense () const; + + const bool& + omit_default_attributes () const; + + const NarrowString& + type_naming () const; + + bool + type_naming_specified () const; + + const NarrowString& + function_naming () const; + + bool + function_naming_specified () const; + + const NarrowStrings& + type_regex () const; + + bool + type_regex_specified () const; + + const NarrowStrings& + accessor_regex () const; + + bool + accessor_regex_specified () const; + + const NarrowStrings& + one_accessor_regex () const; + + bool + one_accessor_regex_specified () const; + + const NarrowStrings& + opt_accessor_regex () const; + + bool + opt_accessor_regex_specified () const; + + const NarrowStrings& + seq_accessor_regex () const; + + bool + seq_accessor_regex_specified () const; + + const NarrowStrings& + modifier_regex () const; + + bool + modifier_regex_specified () const; + + const NarrowStrings& + one_modifier_regex () const; + + bool + one_modifier_regex_specified () const; + + const NarrowStrings& + opt_modifier_regex () const; + + bool + opt_modifier_regex_specified () const; + + const NarrowStrings& + seq_modifier_regex () const; + + bool + seq_modifier_regex_specified () const; + + const NarrowStrings& + parser_regex () const; + + bool + parser_regex_specified () const; + + const NarrowStrings& + serializer_regex () const; + + bool + serializer_regex_specified () const; + + const NarrowStrings& + const_regex () const; + + bool + const_regex_specified () const; + + const NarrowStrings& + enumerator_regex () const; + + bool + enumerator_regex_specified () const; + + const NarrowStrings& + element_type_regex () const; + + bool + element_type_regex_specified () const; + + const bool& + name_regex_trace () const; + + const bool& + root_element_first () const; + + const bool& + root_element_last () const; + + const bool& + root_element_all () const; + + const bool& + root_element_none () const; + + const NarrowStrings& + root_element () const; + + bool + root_element_specified () const; + + const NarrowStrings& + custom_type () const; + + bool + custom_type_specified () const; + + const NarrowStrings& + custom_type_regex () const; + + bool + custom_type_regex_specified () const; + + const std::size_t& + parts () const; + + bool + parts_specified () const; + + const NarrowString& + parts_suffix () const; + + bool + parts_suffix_specified () const; + + // Print usage information. + // + static ::cli::usage_para + print_usage (::std::wostream&, + ::cli::usage_para = ::cli::usage_para::none); + + // Implementation details. + // + protected: + bool + _parse (const char*, ::cli::scanner&); + + private: + bool + _parse (::cli::scanner&, + ::cli::unknown_mode option, + ::cli::unknown_mode argument); + + public: + bool generate_polymorphic_; + NarrowStrings polymorphic_type_; + bool polymorphic_type_specified_; + bool polymorphic_type_all_; + unsigned long polymorphic_plate_; + bool polymorphic_plate_specified_; + NarrowStrings ordered_type_; + bool ordered_type_specified_; + bool ordered_type_derived_; + bool ordered_type_mixed_; + bool ordered_type_all_; + NarrowString order_container_; + bool order_container_specified_; + bool generate_serialization_; + bool generate_ostream_; + bool generate_doxygen_; + bool generate_comparison_; + bool generate_default_ctor_; + bool generate_from_base_ctor_; + bool suppress_assignment_; + bool generate_detach_; + bool generate_wildcard_; + bool generate_any_type_; + NarrowStrings generate_insertion_; + bool generate_insertion_specified_; + NarrowStrings generate_extraction_; + bool generate_extraction_specified_; + bool generate_forward_; + bool suppress_parsing_; + bool generate_element_type_; + bool generate_element_map_; + bool generate_intellisense_; + bool omit_default_attributes_; + NarrowString type_naming_; + bool type_naming_specified_; + NarrowString function_naming_; + bool function_naming_specified_; + NarrowStrings type_regex_; + bool type_regex_specified_; + NarrowStrings accessor_regex_; + bool accessor_regex_specified_; + NarrowStrings one_accessor_regex_; + bool one_accessor_regex_specified_; + NarrowStrings opt_accessor_regex_; + bool opt_accessor_regex_specified_; + NarrowStrings seq_accessor_regex_; + bool seq_accessor_regex_specified_; + NarrowStrings modifier_regex_; + bool modifier_regex_specified_; + NarrowStrings one_modifier_regex_; + bool one_modifier_regex_specified_; + NarrowStrings opt_modifier_regex_; + bool opt_modifier_regex_specified_; + NarrowStrings seq_modifier_regex_; + bool seq_modifier_regex_specified_; + NarrowStrings parser_regex_; + bool parser_regex_specified_; + NarrowStrings serializer_regex_; + bool serializer_regex_specified_; + NarrowStrings const_regex_; + bool const_regex_specified_; + NarrowStrings enumerator_regex_; + bool enumerator_regex_specified_; + NarrowStrings element_type_regex_; + bool element_type_regex_specified_; + bool name_regex_trace_; + bool root_element_first_; + bool root_element_last_; + bool root_element_all_; + bool root_element_none_; + NarrowStrings root_element_; + bool root_element_specified_; + NarrowStrings custom_type_; + bool custom_type_specified_; + NarrowStrings custom_type_regex_; + bool custom_type_regex_specified_; + std::size_t parts_; + bool parts_specified_; + NarrowString parts_suffix_; + bool parts_suffix_specified_; + }; + } +} + +#include <xsd/cxx/tree/options.ixx> + +// Begin epilogue. +// +// +// End epilogue. + +#endif // XSD_CXX_TREE_OPTIONS_HXX diff --git a/xsd/xsd/pregenerated/xsd/cxx/tree/options.ixx b/xsd/xsd/pregenerated/xsd/cxx/tree/options.ixx new file mode 100644 index 0000000..4d34fd9 --- /dev/null +++ b/xsd/xsd/pregenerated/xsd/cxx/tree/options.ixx @@ -0,0 +1,504 @@ +// -*- C++ -*- +// +// This file was generated by CLI, a command line interface +// compiler for C++. +// + +// Begin prologue. +// +// +// End prologue. + +namespace CXX +{ + namespace Tree + { + // options + // + + inline const bool& options:: + generate_polymorphic () const + { + return this->generate_polymorphic_; + } + + inline const NarrowStrings& options:: + polymorphic_type () const + { + return this->polymorphic_type_; + } + + inline bool options:: + polymorphic_type_specified () const + { + return this->polymorphic_type_specified_; + } + + inline const bool& options:: + polymorphic_type_all () const + { + return this->polymorphic_type_all_; + } + + inline const unsigned long& options:: + polymorphic_plate () const + { + return this->polymorphic_plate_; + } + + inline bool options:: + polymorphic_plate_specified () const + { + return this->polymorphic_plate_specified_; + } + + inline const NarrowStrings& options:: + ordered_type () const + { + return this->ordered_type_; + } + + inline bool options:: + ordered_type_specified () const + { + return this->ordered_type_specified_; + } + + inline const bool& options:: + ordered_type_derived () const + { + return this->ordered_type_derived_; + } + + inline const bool& options:: + ordered_type_mixed () const + { + return this->ordered_type_mixed_; + } + + inline const bool& options:: + ordered_type_all () const + { + return this->ordered_type_all_; + } + + inline const NarrowString& options:: + order_container () const + { + return this->order_container_; + } + + inline bool options:: + order_container_specified () const + { + return this->order_container_specified_; + } + + inline const bool& options:: + generate_serialization () const + { + return this->generate_serialization_; + } + + inline const bool& options:: + generate_ostream () const + { + return this->generate_ostream_; + } + + inline const bool& options:: + generate_doxygen () const + { + return this->generate_doxygen_; + } + + inline const bool& options:: + generate_comparison () const + { + return this->generate_comparison_; + } + + inline const bool& options:: + generate_default_ctor () const + { + return this->generate_default_ctor_; + } + + inline const bool& options:: + generate_from_base_ctor () const + { + return this->generate_from_base_ctor_; + } + + inline const bool& options:: + suppress_assignment () const + { + return this->suppress_assignment_; + } + + inline const bool& options:: + generate_detach () const + { + return this->generate_detach_; + } + + inline const bool& options:: + generate_wildcard () const + { + return this->generate_wildcard_; + } + + inline const bool& options:: + generate_any_type () const + { + return this->generate_any_type_; + } + + inline const NarrowStrings& options:: + generate_insertion () const + { + return this->generate_insertion_; + } + + inline bool options:: + generate_insertion_specified () const + { + return this->generate_insertion_specified_; + } + + inline const NarrowStrings& options:: + generate_extraction () const + { + return this->generate_extraction_; + } + + inline bool options:: + generate_extraction_specified () const + { + return this->generate_extraction_specified_; + } + + inline const bool& options:: + generate_forward () const + { + return this->generate_forward_; + } + + inline const bool& options:: + suppress_parsing () const + { + return this->suppress_parsing_; + } + + inline const bool& options:: + generate_element_type () const + { + return this->generate_element_type_; + } + + inline const bool& options:: + generate_element_map () const + { + return this->generate_element_map_; + } + + inline const bool& options:: + generate_intellisense () const + { + return this->generate_intellisense_; + } + + inline const bool& options:: + omit_default_attributes () const + { + return this->omit_default_attributes_; + } + + inline const NarrowString& options:: + type_naming () const + { + return this->type_naming_; + } + + inline bool options:: + type_naming_specified () const + { + return this->type_naming_specified_; + } + + inline const NarrowString& options:: + function_naming () const + { + return this->function_naming_; + } + + inline bool options:: + function_naming_specified () const + { + return this->function_naming_specified_; + } + + inline const NarrowStrings& options:: + type_regex () const + { + return this->type_regex_; + } + + inline bool options:: + type_regex_specified () const + { + return this->type_regex_specified_; + } + + inline const NarrowStrings& options:: + accessor_regex () const + { + return this->accessor_regex_; + } + + inline bool options:: + accessor_regex_specified () const + { + return this->accessor_regex_specified_; + } + + inline const NarrowStrings& options:: + one_accessor_regex () const + { + return this->one_accessor_regex_; + } + + inline bool options:: + one_accessor_regex_specified () const + { + return this->one_accessor_regex_specified_; + } + + inline const NarrowStrings& options:: + opt_accessor_regex () const + { + return this->opt_accessor_regex_; + } + + inline bool options:: + opt_accessor_regex_specified () const + { + return this->opt_accessor_regex_specified_; + } + + inline const NarrowStrings& options:: + seq_accessor_regex () const + { + return this->seq_accessor_regex_; + } + + inline bool options:: + seq_accessor_regex_specified () const + { + return this->seq_accessor_regex_specified_; + } + + inline const NarrowStrings& options:: + modifier_regex () const + { + return this->modifier_regex_; + } + + inline bool options:: + modifier_regex_specified () const + { + return this->modifier_regex_specified_; + } + + inline const NarrowStrings& options:: + one_modifier_regex () const + { + return this->one_modifier_regex_; + } + + inline bool options:: + one_modifier_regex_specified () const + { + return this->one_modifier_regex_specified_; + } + + inline const NarrowStrings& options:: + opt_modifier_regex () const + { + return this->opt_modifier_regex_; + } + + inline bool options:: + opt_modifier_regex_specified () const + { + return this->opt_modifier_regex_specified_; + } + + inline const NarrowStrings& options:: + seq_modifier_regex () const + { + return this->seq_modifier_regex_; + } + + inline bool options:: + seq_modifier_regex_specified () const + { + return this->seq_modifier_regex_specified_; + } + + inline const NarrowStrings& options:: + parser_regex () const + { + return this->parser_regex_; + } + + inline bool options:: + parser_regex_specified () const + { + return this->parser_regex_specified_; + } + + inline const NarrowStrings& options:: + serializer_regex () const + { + return this->serializer_regex_; + } + + inline bool options:: + serializer_regex_specified () const + { + return this->serializer_regex_specified_; + } + + inline const NarrowStrings& options:: + const_regex () const + { + return this->const_regex_; + } + + inline bool options:: + const_regex_specified () const + { + return this->const_regex_specified_; + } + + inline const NarrowStrings& options:: + enumerator_regex () const + { + return this->enumerator_regex_; + } + + inline bool options:: + enumerator_regex_specified () const + { + return this->enumerator_regex_specified_; + } + + inline const NarrowStrings& options:: + element_type_regex () const + { + return this->element_type_regex_; + } + + inline bool options:: + element_type_regex_specified () const + { + return this->element_type_regex_specified_; + } + + inline const bool& options:: + name_regex_trace () const + { + return this->name_regex_trace_; + } + + inline const bool& options:: + root_element_first () const + { + return this->root_element_first_; + } + + inline const bool& options:: + root_element_last () const + { + return this->root_element_last_; + } + + inline const bool& options:: + root_element_all () const + { + return this->root_element_all_; + } + + inline const bool& options:: + root_element_none () const + { + return this->root_element_none_; + } + + inline const NarrowStrings& options:: + root_element () const + { + return this->root_element_; + } + + inline bool options:: + root_element_specified () const + { + return this->root_element_specified_; + } + + inline const NarrowStrings& options:: + custom_type () const + { + return this->custom_type_; + } + + inline bool options:: + custom_type_specified () const + { + return this->custom_type_specified_; + } + + inline const NarrowStrings& options:: + custom_type_regex () const + { + return this->custom_type_regex_; + } + + inline bool options:: + custom_type_regex_specified () const + { + return this->custom_type_regex_specified_; + } + + inline const std::size_t& options:: + parts () const + { + return this->parts_; + } + + inline bool options:: + parts_specified () const + { + return this->parts_specified_; + } + + inline const NarrowString& options:: + parts_suffix () const + { + return this->parts_suffix_; + } + + inline bool options:: + parts_suffix_specified () const + { + return this->parts_suffix_specified_; + } + } +} + +// Begin epilogue. +// +// +// End epilogue. diff --git a/xsd/xsd/pregenerated/xsd/options.cxx b/xsd/xsd/pregenerated/xsd/options.cxx new file mode 100644 index 0000000..3022ec4 --- /dev/null +++ b/xsd/xsd/pregenerated/xsd/options.cxx @@ -0,0 +1,1297 @@ +// -*- C++ -*- +// +// This file was generated by CLI, a command line interface +// compiler for C++. +// + +// Begin prologue. +// +#include <xsd/options-parser.hxx> +// +// End prologue. + +#include <xsd/options.hxx> + +#include <map> +#include <set> +#include <string> +#include <vector> +#include <utility> +#include <ostream> +#include <sstream> +#include <cstring> +#include <fstream> + +namespace cli +{ + // unknown_option + // + unknown_option:: + ~unknown_option () noexcept + { + } + + void unknown_option:: + print (::std::wostream& os) const + { + os << "unknown option '" << option ().c_str () << "'"; + } + + const char* unknown_option:: + what () const noexcept + { + return "unknown option"; + } + + // unknown_argument + // + unknown_argument:: + ~unknown_argument () noexcept + { + } + + void unknown_argument:: + print (::std::wostream& os) const + { + os << "unknown argument '" << argument ().c_str () << "'"; + } + + const char* unknown_argument:: + what () const noexcept + { + return "unknown argument"; + } + + // missing_value + // + missing_value:: + ~missing_value () noexcept + { + } + + void missing_value:: + print (::std::wostream& os) const + { + os << "missing value for option '" << option ().c_str () << "'"; + } + + const char* missing_value:: + what () const noexcept + { + return "missing option value"; + } + + // invalid_value + // + invalid_value:: + ~invalid_value () noexcept + { + } + + void invalid_value:: + print (::std::wostream& os) const + { + os << "invalid value '" << value ().c_str () << "' for option '" + << option ().c_str () << "'"; + + if (!message ().empty ()) + os << ": " << message ().c_str (); + } + + const char* invalid_value:: + what () const noexcept + { + return "invalid option value"; + } + + // eos_reached + // + void eos_reached:: + print (::std::wostream& os) const + { + os << what (); + } + + const char* eos_reached:: + what () const noexcept + { + return "end of argument stream reached"; + } + + // file_io_failure + // + file_io_failure:: + ~file_io_failure () noexcept + { + } + + void file_io_failure:: + print (::std::wostream& os) const + { + os << "unable to open file '" << file ().c_str () << "' or read failure"; + } + + const char* file_io_failure:: + what () const noexcept + { + return "unable to open file or read failure"; + } + + // unmatched_quote + // + unmatched_quote:: + ~unmatched_quote () noexcept + { + } + + void unmatched_quote:: + print (::std::wostream& os) const + { + os << "unmatched quote in argument '" << argument ().c_str () << "'"; + } + + const char* unmatched_quote:: + what () const noexcept + { + return "unmatched quote"; + } + + // scanner + // + scanner:: + ~scanner () + { + } + + // argv_scanner + // + bool argv_scanner:: + more () + { + return i_ < argc_; + } + + const char* argv_scanner:: + peek () + { + if (i_ < argc_) + return argv_[i_]; + else + throw eos_reached (); + } + + const char* argv_scanner:: + next () + { + if (i_ < argc_) + { + const char* r (argv_[i_]); + + if (erase_) + { + for (int i (i_ + 1); i < argc_; ++i) + argv_[i - 1] = argv_[i]; + + --argc_; + argv_[argc_] = 0; + } + else + ++i_; + + ++start_position_; + return r; + } + else + throw eos_reached (); + } + + void argv_scanner:: + skip () + { + if (i_ < argc_) + { + ++i_; + ++start_position_; + } + else + throw eos_reached (); + } + + std::size_t argv_scanner:: + position () + { + return start_position_; + } + + // argv_file_scanner + // + int argv_file_scanner::zero_argc_ = 0; + std::string argv_file_scanner::empty_string_; + + bool argv_file_scanner:: + more () + { + if (!args_.empty ()) + return true; + + while (base::more ()) + { + // See if the next argument is the file option. + // + const char* a (base::peek ()); + const option_info* oi = 0; + const char* ov = 0; + + if (!skip_) + { + if ((oi = find (a)) != 0) + { + base::next (); + + if (!base::more ()) + throw missing_value (a); + + ov = base::next (); + } + else if (std::strncmp (a, "-", 1) == 0) + { + if ((ov = std::strchr (a, '=')) != 0) + { + std::string o (a, 0, ov - a); + if ((oi = find (o.c_str ())) != 0) + { + base::next (); + ++ov; + } + } + } + } + + if (oi != 0) + { + if (oi->search_func != 0) + { + std::string f (oi->search_func (ov, oi->arg)); + + if (!f.empty ()) + load (f); + } + else + load (ov); + + if (!args_.empty ()) + return true; + } + else + { + if (!skip_) + skip_ = (std::strcmp (a, "--") == 0); + + return true; + } + } + + return false; + } + + const char* argv_file_scanner:: + peek () + { + if (!more ()) + throw eos_reached (); + + return args_.empty () ? base::peek () : args_.front ().value.c_str (); + } + + const std::string& argv_file_scanner:: + peek_file () + { + if (!more ()) + throw eos_reached (); + + return args_.empty () ? empty_string_ : *args_.front ().file; + } + + std::size_t argv_file_scanner:: + peek_line () + { + if (!more ()) + throw eos_reached (); + + return args_.empty () ? 0 : args_.front ().line; + } + + const char* argv_file_scanner:: + next () + { + if (!more ()) + throw eos_reached (); + + if (args_.empty ()) + return base::next (); + else + { + hold_[i_ == 0 ? ++i_ : --i_].swap (args_.front ().value); + args_.pop_front (); + ++start_position_; + return hold_[i_].c_str (); + } + } + + void argv_file_scanner:: + skip () + { + if (!more ()) + throw eos_reached (); + + if (args_.empty ()) + return base::skip (); + else + { + args_.pop_front (); + ++start_position_; + } + } + + const argv_file_scanner::option_info* argv_file_scanner:: + find (const char* a) const + { + for (std::size_t i (0); i < options_count_; ++i) + if (std::strcmp (a, options_[i].option) == 0) + return &options_[i]; + + return 0; + } + + std::size_t argv_file_scanner:: + position () + { + return start_position_; + } + + void argv_file_scanner:: + load (const std::string& file) + { + using namespace std; + + ifstream is (file.c_str ()); + + if (!is.is_open ()) + throw file_io_failure (file); + + files_.push_back (file); + + arg a; + a.file = &*files_.rbegin (); + + for (a.line = 1; !is.eof (); ++a.line) + { + string line; + getline (is, line); + + if (is.fail () && !is.eof ()) + throw file_io_failure (file); + + string::size_type n (line.size ()); + + // Trim the line from leading and trailing whitespaces. + // + if (n != 0) + { + const char* f (line.c_str ()); + const char* l (f + n); + + const char* of (f); + while (f < l && (*f == ' ' || *f == '\t' || *f == '\r')) + ++f; + + --l; + + const char* ol (l); + while (l > f && (*l == ' ' || *l == '\t' || *l == '\r')) + --l; + + if (f != of || l != ol) + line = f <= l ? string (f, l - f + 1) : string (); + } + + // Ignore empty lines, those that start with #. + // + if (line.empty () || line[0] == '#') + continue; + + string::size_type p (string::npos); + if (line.compare (0, 1, "-") == 0) + { + p = line.find (' '); + + string::size_type q (line.find ('=')); + if (q != string::npos && q < p) + p = q; + } + + string s1; + if (p != string::npos) + { + s1.assign (line, 0, p); + + // Skip leading whitespaces in the argument. + // + if (line[p] == '=') + ++p; + else + { + n = line.size (); + for (++p; p < n; ++p) + { + char c (line[p]); + if (c != ' ' && c != '\t' && c != '\r') + break; + } + } + } + else if (!skip_) + skip_ = (line == "--"); + + string s2 (line, p != string::npos ? p : 0); + + // If the string (which is an option value or argument) is + // wrapped in quotes, remove them. + // + n = s2.size (); + char cf (s2[0]), cl (s2[n - 1]); + + if (cf == '"' || cf == '\'' || cl == '"' || cl == '\'') + { + if (n == 1 || cf != cl) + throw unmatched_quote (s2); + + s2 = string (s2, 1, n - 2); + } + + if (!s1.empty ()) + { + // See if this is another file option. + // + const option_info* oi; + if (!skip_ && (oi = find (s1.c_str ()))) + { + if (s2.empty ()) + throw missing_value (oi->option); + + if (oi->search_func != 0) + { + string f (oi->search_func (s2.c_str (), oi->arg)); + if (!f.empty ()) + load (f); + } + else + { + // If the path of the file being parsed is not simple and the + // path of the file that needs to be loaded is relative, then + // complete the latter using the former as a base. + // +#ifndef _WIN32 + string::size_type p (file.find_last_of ('/')); + bool c (p != string::npos && s2[0] != '/'); +#else + string::size_type p (file.find_last_of ("/\\")); + bool c (p != string::npos && s2[1] != ':'); +#endif + if (c) + s2.insert (0, file, 0, p + 1); + + load (s2); + } + + continue; + } + + a.value = s1; + args_.push_back (a); + } + + a.value = s2; + args_.push_back (a); + } + } + + template <typename X> + struct parser + { + static void + parse (X& x, bool& xs, scanner& s) + { + using namespace std; + + const char* o (s.next ()); + if (s.more ()) + { + string v (s.next ()); + istringstream is (v); + if (!(is >> x && is.peek () == istringstream::traits_type::eof ())) + throw invalid_value (o, v); + } + else + throw missing_value (o); + + xs = true; + } + }; + + template <> + struct parser<bool> + { + static void + parse (bool& x, bool& xs, scanner& s) + { + const char* o (s.next ()); + + if (s.more ()) + { + const char* v (s.next ()); + + if (std::strcmp (v, "1") == 0 || + std::strcmp (v, "true") == 0 || + std::strcmp (v, "TRUE") == 0 || + std::strcmp (v, "True") == 0) + x = true; + else if (std::strcmp (v, "0") == 0 || + std::strcmp (v, "false") == 0 || + std::strcmp (v, "FALSE") == 0 || + std::strcmp (v, "False") == 0) + x = false; + else + throw invalid_value (o, v); + } + else + throw missing_value (o); + + xs = true; + } + }; + + template <> + struct parser<std::string> + { + static void + parse (std::string& x, bool& xs, scanner& s) + { + const char* o (s.next ()); + + if (s.more ()) + x = s.next (); + else + throw missing_value (o); + + xs = true; + } + }; + + template <typename X> + struct parser<std::pair<X, std::size_t> > + { + static void + parse (std::pair<X, std::size_t>& x, bool& xs, scanner& s) + { + x.second = s.position (); + parser<X>::parse (x.first, xs, s); + } + }; + + template <typename X> + struct parser<std::vector<X> > + { + static void + parse (std::vector<X>& c, bool& xs, scanner& s) + { + X x; + bool dummy; + parser<X>::parse (x, dummy, s); + c.push_back (x); + xs = true; + } + }; + + template <typename X, typename C> + struct parser<std::set<X, C> > + { + static void + parse (std::set<X, C>& c, bool& xs, scanner& s) + { + X x; + bool dummy; + parser<X>::parse (x, dummy, s); + c.insert (x); + xs = true; + } + }; + + template <typename K, typename V, typename C> + struct parser<std::map<K, V, C> > + { + static void + parse (std::map<K, V, C>& m, bool& xs, scanner& s) + { + const char* o (s.next ()); + + if (s.more ()) + { + std::size_t pos (s.position ()); + std::string ov (s.next ()); + std::string::size_type p = ov.find ('='); + + K k = K (); + V v = V (); + std::string kstr (ov, 0, p); + std::string vstr (ov, (p != std::string::npos ? p + 1 : ov.size ())); + + int ac (2); + char* av[] = + { + const_cast<char*> (o), + 0 + }; + + bool dummy; + if (!kstr.empty ()) + { + av[1] = const_cast<char*> (kstr.c_str ()); + argv_scanner s (0, ac, av, false, pos); + parser<K>::parse (k, dummy, s); + } + + if (!vstr.empty ()) + { + av[1] = const_cast<char*> (vstr.c_str ()); + argv_scanner s (0, ac, av, false, pos); + parser<V>::parse (v, dummy, s); + } + + m[k] = v; + } + else + throw missing_value (o); + + xs = true; + } + }; + + template <typename K, typename V, typename C> + struct parser<std::multimap<K, V, C> > + { + static void + parse (std::multimap<K, V, C>& m, bool& xs, scanner& s) + { + const char* o (s.next ()); + + if (s.more ()) + { + std::size_t pos (s.position ()); + std::string ov (s.next ()); + std::string::size_type p = ov.find ('='); + + K k = K (); + V v = V (); + std::string kstr (ov, 0, p); + std::string vstr (ov, (p != std::string::npos ? p + 1 : ov.size ())); + + int ac (2); + char* av[] = + { + const_cast<char*> (o), + 0 + }; + + bool dummy; + if (!kstr.empty ()) + { + av[1] = const_cast<char*> (kstr.c_str ()); + argv_scanner s (0, ac, av, false, pos); + parser<K>::parse (k, dummy, s); + } + + if (!vstr.empty ()) + { + av[1] = const_cast<char*> (vstr.c_str ()); + argv_scanner s (0, ac, av, false, pos); + parser<V>::parse (v, dummy, s); + } + + m.insert (typename std::multimap<K, V, C>::value_type (k, v)); + } + else + throw missing_value (o); + + xs = true; + } + }; + + template <typename X, typename T, T X::*M> + void + thunk (X& x, scanner& s) + { + parser<T>::parse (x.*M, s); + } + + template <typename X, bool X::*M> + void + thunk (X& x, scanner& s) + { + s.next (); + x.*M = true; + } + + template <typename X, typename T, T X::*M, bool X::*S> + void + thunk (X& x, scanner& s) + { + parser<T>::parse (x.*M, x.*S, s); + } +} + +#include <map> + +// help_options +// + +help_options:: +help_options () +: build2_metadata_ (), + build2_metadata_specified_ (false), + help_ (), + version_ (), + proprietary_license_ () +{ +} + +help_options:: +help_options (int& argc, + char** argv, + bool erase, + ::cli::unknown_mode opt, + ::cli::unknown_mode arg) +: build2_metadata_ (), + build2_metadata_specified_ (false), + help_ (), + version_ (), + proprietary_license_ () +{ + ::cli::argv_scanner s (argc, argv, erase); + _parse (s, opt, arg); +} + +help_options:: +help_options (int start, + int& argc, + char** argv, + bool erase, + ::cli::unknown_mode opt, + ::cli::unknown_mode arg) +: build2_metadata_ (), + build2_metadata_specified_ (false), + help_ (), + version_ (), + proprietary_license_ () +{ + ::cli::argv_scanner s (start, argc, argv, erase); + _parse (s, opt, arg); +} + +help_options:: +help_options (int& argc, + char** argv, + int& end, + bool erase, + ::cli::unknown_mode opt, + ::cli::unknown_mode arg) +: build2_metadata_ (), + build2_metadata_specified_ (false), + help_ (), + version_ (), + proprietary_license_ () +{ + ::cli::argv_scanner s (argc, argv, erase); + _parse (s, opt, arg); + end = s.end (); +} + +help_options:: +help_options (int start, + int& argc, + char** argv, + int& end, + bool erase, + ::cli::unknown_mode opt, + ::cli::unknown_mode arg) +: build2_metadata_ (), + build2_metadata_specified_ (false), + help_ (), + version_ (), + proprietary_license_ () +{ + ::cli::argv_scanner s (start, argc, argv, erase); + _parse (s, opt, arg); + end = s.end (); +} + +help_options:: +help_options (::cli::scanner& s, + ::cli::unknown_mode opt, + ::cli::unknown_mode arg) +: build2_metadata_ (), + build2_metadata_specified_ (false), + help_ (), + version_ (), + proprietary_license_ () +{ + _parse (s, opt, arg); +} + +::cli::usage_para help_options:: +print_usage (::std::wostream& os, ::cli::usage_para p) +{ + CLI_POTENTIALLY_UNUSED (os); + + return p; +} + +typedef +std::map<std::string, void (*) (help_options&, ::cli::scanner&)> +_cli_help_options_map; + +static _cli_help_options_map _cli_help_options_map_; + +struct _cli_help_options_map_init +{ + _cli_help_options_map_init () + { + _cli_help_options_map_["--build2-metadata"] = + &::cli::thunk< help_options, std::uint64_t, &help_options::build2_metadata_, + &help_options::build2_metadata_specified_ >; + _cli_help_options_map_["--help"] = + &::cli::thunk< help_options, &help_options::help_ >; + _cli_help_options_map_["--version"] = + &::cli::thunk< help_options, &help_options::version_ >; + _cli_help_options_map_["--proprietary-license"] = + &::cli::thunk< help_options, &help_options::proprietary_license_ >; + } +}; + +static _cli_help_options_map_init _cli_help_options_map_init_; + +bool help_options:: +_parse (const char* o, ::cli::scanner& s) +{ + _cli_help_options_map::const_iterator i (_cli_help_options_map_.find (o)); + + if (i != _cli_help_options_map_.end ()) + { + (*(i->second)) (*this, s); + return true; + } + + return false; +} + +bool help_options:: +_parse (::cli::scanner& s, + ::cli::unknown_mode opt_mode, + ::cli::unknown_mode arg_mode) +{ + // Can't skip combined flags (--no-combined-flags). + // + assert (opt_mode != ::cli::unknown_mode::skip); + + bool r = false; + bool opt = true; + + while (s.more ()) + { + const char* o = s.peek (); + + if (std::strcmp (o, "--") == 0) + { + opt = false; + s.skip (); + r = true; + continue; + } + + if (opt) + { + if (_parse (o, s)) + { + r = true; + continue; + } + + if (std::strncmp (o, "-", 1) == 0 && o[1] != '\0') + { + // Handle combined option values. + // + std::string co; + if (const char* v = std::strchr (o, '=')) + { + co.assign (o, 0, v - o); + ++v; + + int ac (2); + char* av[] = + { + const_cast<char*> (co.c_str ()), + const_cast<char*> (v) + }; + + ::cli::argv_scanner ns (0, ac, av); + + if (_parse (co.c_str (), ns)) + { + // Parsed the option but not its value? + // + if (ns.end () != 2) + throw ::cli::invalid_value (co, v); + + s.next (); + r = true; + continue; + } + else + { + // Set the unknown option and fall through. + // + o = co.c_str (); + } + } + + // Handle combined flags. + // + char cf[3]; + { + const char* p = o + 1; + for (; *p != '\0'; ++p) + { + if (!((*p >= 'a' && *p <= 'z') || + (*p >= 'A' && *p <= 'Z') || + (*p >= '0' && *p <= '9'))) + break; + } + + if (*p == '\0') + { + for (p = o + 1; *p != '\0'; ++p) + { + std::strcpy (cf, "-"); + cf[1] = *p; + cf[2] = '\0'; + + int ac (1); + char* av[] = + { + cf + }; + + ::cli::argv_scanner ns (0, ac, av); + + if (!_parse (cf, ns)) + break; + } + + if (*p == '\0') + { + // All handled. + // + s.next (); + r = true; + continue; + } + else + { + // Set the unknown option and fall through. + // + o = cf; + } + } + } + + switch (opt_mode) + { + case ::cli::unknown_mode::skip: + { + s.skip (); + r = true; + continue; + } + case ::cli::unknown_mode::stop: + { + break; + } + case ::cli::unknown_mode::fail: + { + throw ::cli::unknown_option (o); + } + } + + break; + } + } + + switch (arg_mode) + { + case ::cli::unknown_mode::skip: + { + s.skip (); + r = true; + continue; + } + case ::cli::unknown_mode::stop: + { + break; + } + case ::cli::unknown_mode::fail: + { + throw ::cli::unknown_argument (o); + } + } + + break; + } + + return r; +} + +// options +// + +options:: +options () +: disable_warning_ (), + disable_warning_specified_ (false), + options_file_ (), + options_file_specified_ (false), + show_sloc_ (), + sloc_limit_ (), + sloc_limit_specified_ (false), + proprietary_license_ (), + custom_literals_ (), + custom_literals_specified_ (false), + preserve_anonymous_ (), + show_anonymous_ (), + anonymous_regex_ (), + anonymous_regex_specified_ (false), + anonymous_regex_trace_ (), + morph_anonymous_ (), + location_map_ (), + location_map_specified_ (false), + location_regex_ (), + location_regex_specified_ (false), + location_regex_trace_ (), + file_per_type_ (), + type_file_regex_ (), + type_file_regex_specified_ (false), + type_file_regex_trace_ (), + schema_file_regex_ (), + schema_file_regex_specified_ (false), + schema_file_regex_trace_ (), + fat_type_file_ (), + file_list_ (), + file_list_specified_ (false), + file_list_only_ (), + file_list_prologue_ (), + file_list_prologue_specified_ (false), + file_list_epilogue_ (), + file_list_epilogue_specified_ (false), + file_list_delim_ ("\n"), + file_list_delim_specified_ (false), + disable_multi_import_ (), + disable_full_check_ () +{ +} + +::cli::usage_para options:: +print_usage (::std::wostream& os, ::cli::usage_para p) +{ + CLI_POTENTIALLY_UNUSED (os); + + if (p == ::cli::usage_para::text) + os << ::std::endl; + + os << "--disable-warning <warn> Disable printing warning with id <warn>." << ::std::endl; + + os << "--options-file <file> Read additional options from <file>." << ::std::endl; + + os << "--show-sloc Show the number of generated physical source lines" << ::std::endl + << " of code (SLOC)." << ::std::endl; + + os << "--sloc-limit <num> Check that the number of generated physical source" << ::std::endl + << " lines of code (SLOC) does not exceed <num>." << ::std::endl; + + os << "--proprietary-license Indicate that the generated code is licensed under" << ::std::endl + << " a proprietary license instead of the GPL." << ::std::endl; + + os << "--custom-literals <file> Load custom XML string to C++ literal mappings" << ::std::endl + << " from <file>." << ::std::endl; + + os << "--preserve-anonymous Preserve anonymous types." << ::std::endl; + + os << "--show-anonymous Show elements and attributes that are of anonymous" << ::std::endl + << " types." << ::std::endl; + + os << "--anonymous-regex <regex> Add <regex> to the list of regular expressions" << ::std::endl + << " used to derive names for anonymous types from the" << ::std::endl + << " enclosing attributes/elements." << ::std::endl; + + os << "--anonymous-regex-trace Trace the process of applying regular expressions" << ::std::endl + << " specified with the --anonymous-regex option." << ::std::endl; + + os << "--location-map <ol>=<nl> Map the original schema location <ol> that is" << ::std::endl + << " specified in the XML Schema include or import" << ::std::endl + << " elements to new schema location <nl>." << ::std::endl; + + os << "--location-regex <regex> Add <regex> to the list of regular expressions" << ::std::endl + << " used to map schema locations that are specified in" << ::std::endl + << " the XML Schema include or import elements." << ::std::endl; + + os << "--location-regex-trace Trace the process of applying regular expressions" << ::std::endl + << " specified with the --location-regex option." << ::std::endl; + + os << "--file-per-type Generate a separate set of C++ files for each type" << ::std::endl + << " defined in XML Schema." << ::std::endl; + + os << "--type-file-regex <regex> Add <regex> to the list of regular expressions" << ::std::endl + << " used to translate type names to file names when" << ::std::endl + << " the --file-per-type option is specified." << ::std::endl; + + os << "--type-file-regex-trace Trace the process of applying regular expressions" << ::std::endl + << " specified with the --type-file-regex option." << ::std::endl; + + os << "--schema-file-regex <regex> Add <regex> to the list of regular expressions" << ::std::endl + << " used to translate schema file names when the" << ::std::endl + << " --file-per-type option is specified." << ::std::endl; + + os << "--schema-file-regex-trace Trace the process of applying regular expressions" << ::std::endl + << " specified with the --schema-file-regex option." << ::std::endl; + + os << "--fat-type-file Generate code corresponding to global elements" << ::std::endl + << " into type files instead of schema files when the" << ::std::endl + << " --type-file-regex option is specified." << ::std::endl; + + os << "--file-list <file> Write a list of generated C++ files to <file> or" << ::std::endl + << " to stdout if <file> is -." << ::std::endl; + + os << "--file-list-only Only write the list of C++ files that would be" << ::std::endl + << " generated without actually generating them." << ::std::endl; + + os << "--file-list-prologue <text> Insert <text> at the beginning of the file list." << ::std::endl; + + os << "--file-list-epilogue <text> Insert <text> at the end of the file list." << ::std::endl; + + os << "--file-list-delim <text> Delimit file names written to the file list with" << ::std::endl + << " <text> instead of new lines." << ::std::endl; + + p = ::cli::usage_para::option; + + return p; +} + +typedef +std::map<std::string, void (*) (options&, ::cli::scanner&)> +_cli_options_map; + +static _cli_options_map _cli_options_map_; + +struct _cli_options_map_init +{ + _cli_options_map_init () + { + _cli_options_map_["--disable-warning"] = + &::cli::thunk< options, NarrowStrings, &options::disable_warning_, + &options::disable_warning_specified_ >; + _cli_options_map_["--options-file"] = + &::cli::thunk< options, std::string, &options::options_file_, + &options::options_file_specified_ >; + _cli_options_map_["--show-sloc"] = + &::cli::thunk< options, &options::show_sloc_ >; + _cli_options_map_["--sloc-limit"] = + &::cli::thunk< options, std::size_t, &options::sloc_limit_, + &options::sloc_limit_specified_ >; + _cli_options_map_["--proprietary-license"] = + &::cli::thunk< options, &options::proprietary_license_ >; + _cli_options_map_["--custom-literals"] = + &::cli::thunk< options, NarrowString, &options::custom_literals_, + &options::custom_literals_specified_ >; + _cli_options_map_["--preserve-anonymous"] = + &::cli::thunk< options, &options::preserve_anonymous_ >; + _cli_options_map_["--show-anonymous"] = + &::cli::thunk< options, &options::show_anonymous_ >; + _cli_options_map_["--anonymous-regex"] = + &::cli::thunk< options, NarrowStrings, &options::anonymous_regex_, + &options::anonymous_regex_specified_ >; + _cli_options_map_["--anonymous-regex-trace"] = + &::cli::thunk< options, &options::anonymous_regex_trace_ >; + _cli_options_map_["--morph-anonymous"] = + &::cli::thunk< options, &options::morph_anonymous_ >; + _cli_options_map_["--location-map"] = + &::cli::thunk< options, NarrowStrings, &options::location_map_, + &options::location_map_specified_ >; + _cli_options_map_["--location-regex"] = + &::cli::thunk< options, NarrowStrings, &options::location_regex_, + &options::location_regex_specified_ >; + _cli_options_map_["--location-regex-trace"] = + &::cli::thunk< options, &options::location_regex_trace_ >; + _cli_options_map_["--file-per-type"] = + &::cli::thunk< options, &options::file_per_type_ >; + _cli_options_map_["--type-file-regex"] = + &::cli::thunk< options, NarrowStrings, &options::type_file_regex_, + &options::type_file_regex_specified_ >; + _cli_options_map_["--type-file-regex-trace"] = + &::cli::thunk< options, &options::type_file_regex_trace_ >; + _cli_options_map_["--schema-file-regex"] = + &::cli::thunk< options, NarrowStrings, &options::schema_file_regex_, + &options::schema_file_regex_specified_ >; + _cli_options_map_["--schema-file-regex-trace"] = + &::cli::thunk< options, &options::schema_file_regex_trace_ >; + _cli_options_map_["--fat-type-file"] = + &::cli::thunk< options, &options::fat_type_file_ >; + _cli_options_map_["--file-list"] = + &::cli::thunk< options, NarrowString, &options::file_list_, + &options::file_list_specified_ >; + _cli_options_map_["--file-list-only"] = + &::cli::thunk< options, &options::file_list_only_ >; + _cli_options_map_["--file-list-prologue"] = + &::cli::thunk< options, NarrowString, &options::file_list_prologue_, + &options::file_list_prologue_specified_ >; + _cli_options_map_["--file-list-epilogue"] = + &::cli::thunk< options, NarrowString, &options::file_list_epilogue_, + &options::file_list_epilogue_specified_ >; + _cli_options_map_["--file-list-delim"] = + &::cli::thunk< options, NarrowString, &options::file_list_delim_, + &options::file_list_delim_specified_ >; + _cli_options_map_["--disable-multi-import"] = + &::cli::thunk< options, &options::disable_multi_import_ >; + _cli_options_map_["--disable-full-check"] = + &::cli::thunk< options, &options::disable_full_check_ >; + } +}; + +static _cli_options_map_init _cli_options_map_init_; + +bool options:: +_parse (const char* o, ::cli::scanner& s) +{ + _cli_options_map::const_iterator i (_cli_options_map_.find (o)); + + if (i != _cli_options_map_.end ()) + { + (*(i->second)) (*this, s); + return true; + } + + return false; +} + +// Begin epilogue. +// +// +// End epilogue. + diff --git a/xsd/xsd/pregenerated/xsd/options.hxx b/xsd/xsd/pregenerated/xsd/options.hxx new file mode 100644 index 0000000..0f4383c --- /dev/null +++ b/xsd/xsd/pregenerated/xsd/options.hxx @@ -0,0 +1,702 @@ +// -*- C++ -*- +// +// This file was generated by CLI, a command line interface +// compiler for C++. +// + +#ifndef XSD_OPTIONS_HXX +#define XSD_OPTIONS_HXX + +// Begin prologue. +// +// +// End prologue. + +#include <list> +#include <deque> +#include <iosfwd> +#include <string> +#include <cstddef> +#include <exception> + +#ifndef CLI_POTENTIALLY_UNUSED +# if defined(_MSC_VER) || defined(__xlC__) +# define CLI_POTENTIALLY_UNUSED(x) (void*)&x +# else +# define CLI_POTENTIALLY_UNUSED(x) (void)x +# endif +#endif + +namespace cli +{ + class usage_para + { + public: + enum value + { + none, + text, + option + }; + + usage_para (value); + + operator value () const + { + return v_; + } + + private: + value v_; + }; + + class unknown_mode + { + public: + enum value + { + skip, + stop, + fail + }; + + unknown_mode (value); + + operator value () const + { + return v_; + } + + private: + value v_; + }; + + // Exceptions. + // + + class exception: public std::exception + { + public: + virtual void + print (::std::wostream&) const = 0; + }; + + ::std::wostream& + operator<< (::std::wostream&, const exception&); + + class unknown_option: public exception + { + public: + virtual + ~unknown_option () noexcept; + + unknown_option (const std::string& option); + + const std::string& + option () const; + + virtual void + print (::std::wostream&) const; + + virtual const char* + what () const noexcept; + + private: + std::string option_; + }; + + class unknown_argument: public exception + { + public: + virtual + ~unknown_argument () noexcept; + + unknown_argument (const std::string& argument); + + const std::string& + argument () const; + + virtual void + print (::std::wostream&) const; + + virtual const char* + what () const noexcept; + + private: + std::string argument_; + }; + + class missing_value: public exception + { + public: + virtual + ~missing_value () noexcept; + + missing_value (const std::string& option); + + const std::string& + option () const; + + virtual void + print (::std::wostream&) const; + + virtual const char* + what () const noexcept; + + private: + std::string option_; + }; + + class invalid_value: public exception + { + public: + virtual + ~invalid_value () noexcept; + + invalid_value (const std::string& option, + const std::string& value, + const std::string& message = std::string ()); + + const std::string& + option () const; + + const std::string& + value () const; + + const std::string& + message () const; + + virtual void + print (::std::wostream&) const; + + virtual const char* + what () const noexcept; + + private: + std::string option_; + std::string value_; + std::string message_; + }; + + class eos_reached: public exception + { + public: + virtual void + print (::std::wostream&) const; + + virtual const char* + what () const noexcept; + }; + + class file_io_failure: public exception + { + public: + virtual + ~file_io_failure () noexcept; + + file_io_failure (const std::string& file); + + const std::string& + file () const; + + virtual void + print (::std::wostream&) const; + + virtual const char* + what () const noexcept; + + private: + std::string file_; + }; + + class unmatched_quote: public exception + { + public: + virtual + ~unmatched_quote () noexcept; + + unmatched_quote (const std::string& argument); + + const std::string& + argument () const; + + virtual void + print (::std::wostream&) const; + + virtual const char* + what () const noexcept; + + private: + std::string argument_; + }; + + // Command line argument scanner interface. + // + // The values returned by next() are guaranteed to be valid + // for the two previous arguments up until a call to a third + // peek() or next(). + // + // The position() function returns a monotonically-increasing + // number which, if stored, can later be used to determine the + // relative position of the argument returned by the following + // call to next(). Note that if multiple scanners are used to + // extract arguments from multiple sources, then the end + // position of the previous scanner should be used as the + // start position of the next. + // + class scanner + { + public: + virtual + ~scanner (); + + virtual bool + more () = 0; + + virtual const char* + peek () = 0; + + virtual const char* + next () = 0; + + virtual void + skip () = 0; + + virtual std::size_t + position () = 0; + }; + + class argv_scanner: public scanner + { + public: + argv_scanner (int& argc, + char** argv, + bool erase = false, + std::size_t start_position = 0); + + argv_scanner (int start, + int& argc, + char** argv, + bool erase = false, + std::size_t start_position = 0); + + int + end () const; + + virtual bool + more (); + + virtual const char* + peek (); + + virtual const char* + next (); + + virtual void + skip (); + + virtual std::size_t + position (); + + protected: + std::size_t start_position_; + int i_; + int& argc_; + char** argv_; + bool erase_; + }; + + class argv_file_scanner: public argv_scanner + { + public: + argv_file_scanner (int& argc, + char** argv, + const std::string& option, + bool erase = false, + std::size_t start_position = 0); + + argv_file_scanner (int start, + int& argc, + char** argv, + const std::string& option, + bool erase = false, + std::size_t start_position = 0); + + argv_file_scanner (const std::string& file, + const std::string& option, + std::size_t start_position = 0); + + struct option_info + { + // If search_func is not NULL, it is called, with the arg + // value as the second argument, to locate the options file. + // If it returns an empty string, then the file is ignored. + // + const char* option; + std::string (*search_func) (const char*, void* arg); + void* arg; + }; + + argv_file_scanner (int& argc, + char** argv, + const option_info* options, + std::size_t options_count, + bool erase = false, + std::size_t start_position = 0); + + argv_file_scanner (int start, + int& argc, + char** argv, + const option_info* options, + std::size_t options_count, + bool erase = false, + std::size_t start_position = 0); + + argv_file_scanner (const std::string& file, + const option_info* options = 0, + std::size_t options_count = 0, + std::size_t start_position = 0); + + virtual bool + more (); + + virtual const char* + peek (); + + virtual const char* + next (); + + virtual void + skip (); + + virtual std::size_t + position (); + + // Return the file path if the peeked at argument came from a file and + // the empty string otherwise. The reference is guaranteed to be valid + // till the end of the scanner lifetime. + // + const std::string& + peek_file (); + + // Return the 1-based line number if the peeked at argument came from + // a file and zero otherwise. + // + std::size_t + peek_line (); + + private: + const option_info* + find (const char*) const; + + void + load (const std::string& file); + + typedef argv_scanner base; + + const std::string option_; + option_info option_info_; + const option_info* options_; + std::size_t options_count_; + + struct arg + { + std::string value; + const std::string* file; + std::size_t line; + }; + + std::deque<arg> args_; + std::list<std::string> files_; + + // Circular buffer of two arguments. + // + std::string hold_[2]; + std::size_t i_; + + bool skip_; + + static int zero_argc_; + static std::string empty_string_; + }; + + template <typename X> + struct parser; +} + +#include <cstddef> + +#include <cstdint> + +#include <xsd/types.hxx> + +class help_options +{ + public: + help_options (); + + help_options (int& argc, + char** argv, + bool erase = false, + ::cli::unknown_mode option = ::cli::unknown_mode::fail, + ::cli::unknown_mode argument = ::cli::unknown_mode::stop); + + help_options (int start, + int& argc, + char** argv, + bool erase = false, + ::cli::unknown_mode option = ::cli::unknown_mode::fail, + ::cli::unknown_mode argument = ::cli::unknown_mode::stop); + + help_options (int& argc, + char** argv, + int& end, + bool erase = false, + ::cli::unknown_mode option = ::cli::unknown_mode::fail, + ::cli::unknown_mode argument = ::cli::unknown_mode::stop); + + help_options (int start, + int& argc, + char** argv, + int& end, + bool erase = false, + ::cli::unknown_mode option = ::cli::unknown_mode::fail, + ::cli::unknown_mode argument = ::cli::unknown_mode::stop); + + help_options (::cli::scanner&, + ::cli::unknown_mode option = ::cli::unknown_mode::fail, + ::cli::unknown_mode argument = ::cli::unknown_mode::stop); + + // Option accessors. + // + const std::uint64_t& + build2_metadata () const; + + bool + build2_metadata_specified () const; + + const bool& + help () const; + + const bool& + version () const; + + const bool& + proprietary_license () const; + + // Print usage information. + // + static ::cli::usage_para + print_usage (::std::wostream&, + ::cli::usage_para = ::cli::usage_para::none); + + // Implementation details. + // + protected: + bool + _parse (const char*, ::cli::scanner&); + + private: + bool + _parse (::cli::scanner&, + ::cli::unknown_mode option, + ::cli::unknown_mode argument); + + public: + std::uint64_t build2_metadata_; + bool build2_metadata_specified_; + bool help_; + bool version_; + bool proprietary_license_; +}; + +class options +{ + public: + // Option accessors. + // + const NarrowStrings& + disable_warning () const; + + bool + disable_warning_specified () const; + + const std::string& + options_file () const; + + bool + options_file_specified () const; + + const bool& + show_sloc () const; + + const std::size_t& + sloc_limit () const; + + bool + sloc_limit_specified () const; + + const bool& + proprietary_license () const; + + const NarrowString& + custom_literals () const; + + bool + custom_literals_specified () const; + + const bool& + preserve_anonymous () const; + + const bool& + show_anonymous () const; + + const NarrowStrings& + anonymous_regex () const; + + bool + anonymous_regex_specified () const; + + const bool& + anonymous_regex_trace () const; + + const bool& + morph_anonymous () const; + + const NarrowStrings& + location_map () const; + + bool + location_map_specified () const; + + const NarrowStrings& + location_regex () const; + + bool + location_regex_specified () const; + + const bool& + location_regex_trace () const; + + const bool& + file_per_type () const; + + const NarrowStrings& + type_file_regex () const; + + bool + type_file_regex_specified () const; + + const bool& + type_file_regex_trace () const; + + const NarrowStrings& + schema_file_regex () const; + + bool + schema_file_regex_specified () const; + + const bool& + schema_file_regex_trace () const; + + const bool& + fat_type_file () const; + + const NarrowString& + file_list () const; + + bool + file_list_specified () const; + + const bool& + file_list_only () const; + + const NarrowString& + file_list_prologue () const; + + bool + file_list_prologue_specified () const; + + const NarrowString& + file_list_epilogue () const; + + bool + file_list_epilogue_specified () const; + + const NarrowString& + file_list_delim () const; + + bool + file_list_delim_specified () const; + + const bool& + disable_multi_import () const; + + const bool& + disable_full_check () const; + + // Print usage information. + // + static ::cli::usage_para + print_usage (::std::wostream&, + ::cli::usage_para = ::cli::usage_para::none); + + // Implementation details. + // + protected: + options (); + + bool + _parse (const char*, ::cli::scanner&); + + public: + NarrowStrings disable_warning_; + bool disable_warning_specified_; + std::string options_file_; + bool options_file_specified_; + bool show_sloc_; + std::size_t sloc_limit_; + bool sloc_limit_specified_; + bool proprietary_license_; + NarrowString custom_literals_; + bool custom_literals_specified_; + bool preserve_anonymous_; + bool show_anonymous_; + NarrowStrings anonymous_regex_; + bool anonymous_regex_specified_; + bool anonymous_regex_trace_; + bool morph_anonymous_; + NarrowStrings location_map_; + bool location_map_specified_; + NarrowStrings location_regex_; + bool location_regex_specified_; + bool location_regex_trace_; + bool file_per_type_; + NarrowStrings type_file_regex_; + bool type_file_regex_specified_; + bool type_file_regex_trace_; + NarrowStrings schema_file_regex_; + bool schema_file_regex_specified_; + bool schema_file_regex_trace_; + bool fat_type_file_; + NarrowString file_list_; + bool file_list_specified_; + bool file_list_only_; + NarrowString file_list_prologue_; + bool file_list_prologue_specified_; + NarrowString file_list_epilogue_; + bool file_list_epilogue_specified_; + NarrowString file_list_delim_; + bool file_list_delim_specified_; + bool disable_multi_import_; + bool disable_full_check_; +}; + +#include <xsd/options.ixx> + +// Begin epilogue. +// +// +// End epilogue. + +#endif // XSD_OPTIONS_HXX diff --git a/xsd/xsd/pregenerated/xsd/options.ixx b/xsd/xsd/pregenerated/xsd/options.ixx new file mode 100644 index 0000000..d87e59c --- /dev/null +++ b/xsd/xsd/pregenerated/xsd/options.ixx @@ -0,0 +1,555 @@ +// -*- C++ -*- +// +// This file was generated by CLI, a command line interface +// compiler for C++. +// + +// Begin prologue. +// +// +// End prologue. + +#include <cassert> + +namespace cli +{ + // usage_para + // + inline usage_para:: + usage_para (value v) + : v_ (v) + { + } + + // unknown_mode + // + inline unknown_mode:: + unknown_mode (value v) + : v_ (v) + { + } + + // exception + // + inline ::std::wostream& + operator<< (::std::wostream& os, const exception& e) + { + e.print (os); + return os; + } + + // unknown_option + // + inline unknown_option:: + unknown_option (const std::string& option) + : option_ (option) + { + } + + inline const std::string& unknown_option:: + option () const + { + return option_; + } + + // unknown_argument + // + inline unknown_argument:: + unknown_argument (const std::string& argument) + : argument_ (argument) + { + } + + inline const std::string& unknown_argument:: + argument () const + { + return argument_; + } + + // missing_value + // + inline missing_value:: + missing_value (const std::string& option) + : option_ (option) + { + } + + inline const std::string& missing_value:: + option () const + { + return option_; + } + + // invalid_value + // + inline invalid_value:: + invalid_value (const std::string& option, + const std::string& value, + const std::string& message) + : option_ (option), + value_ (value), + message_ (message) + { + } + + inline const std::string& invalid_value:: + option () const + { + return option_; + } + + inline const std::string& invalid_value:: + value () const + { + return value_; + } + + inline const std::string& invalid_value:: + message () const + { + return message_; + } + + // file_io_failure + // + inline file_io_failure:: + file_io_failure (const std::string& file) + : file_ (file) + { + } + + inline const std::string& file_io_failure:: + file () const + { + return file_; + } + + // unmatched_quote + // + inline unmatched_quote:: + unmatched_quote (const std::string& argument) + : argument_ (argument) + { + } + + inline const std::string& unmatched_quote:: + argument () const + { + return argument_; + } + + // argv_scanner + // + inline argv_scanner:: + argv_scanner (int& argc, + char** argv, + bool erase, + std::size_t sp) + : start_position_ (sp + 1), + i_ (1), + argc_ (argc), + argv_ (argv), + erase_ (erase) + { + } + + inline argv_scanner:: + argv_scanner (int start, + int& argc, + char** argv, + bool erase, + std::size_t sp) + : start_position_ (sp + static_cast<std::size_t> (start)), + i_ (start), + argc_ (argc), + argv_ (argv), + erase_ (erase) + { + } + + inline int argv_scanner:: + end () const + { + return i_; + } + + // argv_file_scanner + // + inline argv_file_scanner:: + argv_file_scanner (int& argc, + char** argv, + const std::string& option, + bool erase, + std::size_t sp) + : argv_scanner (argc, argv, erase, sp), + option_ (option), + options_ (&option_info_), + options_count_ (1), + i_ (1), + skip_ (false) + { + option_info_.option = option_.c_str (); + option_info_.search_func = 0; + } + + inline argv_file_scanner:: + argv_file_scanner (int start, + int& argc, + char** argv, + const std::string& option, + bool erase, + std::size_t sp) + : argv_scanner (start, argc, argv, erase, sp), + option_ (option), + options_ (&option_info_), + options_count_ (1), + i_ (1), + skip_ (false) + { + option_info_.option = option_.c_str (); + option_info_.search_func = 0; + } + + inline argv_file_scanner:: + argv_file_scanner (const std::string& file, + const std::string& option, + std::size_t sp) + : argv_scanner (0, zero_argc_, 0, sp), + option_ (option), + options_ (&option_info_), + options_count_ (1), + i_ (1), + skip_ (false) + { + option_info_.option = option_.c_str (); + option_info_.search_func = 0; + + load (file); + } + + inline argv_file_scanner:: + argv_file_scanner (int& argc, + char** argv, + const option_info* options, + std::size_t options_count, + bool erase, + std::size_t sp) + : argv_scanner (argc, argv, erase, sp), + options_ (options), + options_count_ (options_count), + i_ (1), + skip_ (false) + { + } + + inline argv_file_scanner:: + argv_file_scanner (int start, + int& argc, + char** argv, + const option_info* options, + std::size_t options_count, + bool erase, + std::size_t sp) + : argv_scanner (start, argc, argv, erase, sp), + options_ (options), + options_count_ (options_count), + i_ (1), + skip_ (false) + { + } + + inline argv_file_scanner:: + argv_file_scanner (const std::string& file, + const option_info* options, + std::size_t options_count, + std::size_t sp) + : argv_scanner (0, zero_argc_, 0, sp), + options_ (options), + options_count_ (options_count), + i_ (1), + skip_ (false) + { + load (file); + } +} + +// help_options +// + +inline const std::uint64_t& help_options:: +build2_metadata () const +{ + return this->build2_metadata_; +} + +inline bool help_options:: +build2_metadata_specified () const +{ + return this->build2_metadata_specified_; +} + +inline const bool& help_options:: +help () const +{ + return this->help_; +} + +inline const bool& help_options:: +version () const +{ + return this->version_; +} + +inline const bool& help_options:: +proprietary_license () const +{ + return this->proprietary_license_; +} + +// options +// + +inline const NarrowStrings& options:: +disable_warning () const +{ + return this->disable_warning_; +} + +inline bool options:: +disable_warning_specified () const +{ + return this->disable_warning_specified_; +} + +inline const std::string& options:: +options_file () const +{ + return this->options_file_; +} + +inline bool options:: +options_file_specified () const +{ + return this->options_file_specified_; +} + +inline const bool& options:: +show_sloc () const +{ + return this->show_sloc_; +} + +inline const std::size_t& options:: +sloc_limit () const +{ + return this->sloc_limit_; +} + +inline bool options:: +sloc_limit_specified () const +{ + return this->sloc_limit_specified_; +} + +inline const bool& options:: +proprietary_license () const +{ + return this->proprietary_license_; +} + +inline const NarrowString& options:: +custom_literals () const +{ + return this->custom_literals_; +} + +inline bool options:: +custom_literals_specified () const +{ + return this->custom_literals_specified_; +} + +inline const bool& options:: +preserve_anonymous () const +{ + return this->preserve_anonymous_; +} + +inline const bool& options:: +show_anonymous () const +{ + return this->show_anonymous_; +} + +inline const NarrowStrings& options:: +anonymous_regex () const +{ + return this->anonymous_regex_; +} + +inline bool options:: +anonymous_regex_specified () const +{ + return this->anonymous_regex_specified_; +} + +inline const bool& options:: +anonymous_regex_trace () const +{ + return this->anonymous_regex_trace_; +} + +inline const bool& options:: +morph_anonymous () const +{ + return this->morph_anonymous_; +} + +inline const NarrowStrings& options:: +location_map () const +{ + return this->location_map_; +} + +inline bool options:: +location_map_specified () const +{ + return this->location_map_specified_; +} + +inline const NarrowStrings& options:: +location_regex () const +{ + return this->location_regex_; +} + +inline bool options:: +location_regex_specified () const +{ + return this->location_regex_specified_; +} + +inline const bool& options:: +location_regex_trace () const +{ + return this->location_regex_trace_; +} + +inline const bool& options:: +file_per_type () const +{ + return this->file_per_type_; +} + +inline const NarrowStrings& options:: +type_file_regex () const +{ + return this->type_file_regex_; +} + +inline bool options:: +type_file_regex_specified () const +{ + return this->type_file_regex_specified_; +} + +inline const bool& options:: +type_file_regex_trace () const +{ + return this->type_file_regex_trace_; +} + +inline const NarrowStrings& options:: +schema_file_regex () const +{ + return this->schema_file_regex_; +} + +inline bool options:: +schema_file_regex_specified () const +{ + return this->schema_file_regex_specified_; +} + +inline const bool& options:: +schema_file_regex_trace () const +{ + return this->schema_file_regex_trace_; +} + +inline const bool& options:: +fat_type_file () const +{ + return this->fat_type_file_; +} + +inline const NarrowString& options:: +file_list () const +{ + return this->file_list_; +} + +inline bool options:: +file_list_specified () const +{ + return this->file_list_specified_; +} + +inline const bool& options:: +file_list_only () const +{ + return this->file_list_only_; +} + +inline const NarrowString& options:: +file_list_prologue () const +{ + return this->file_list_prologue_; +} + +inline bool options:: +file_list_prologue_specified () const +{ + return this->file_list_prologue_specified_; +} + +inline const NarrowString& options:: +file_list_epilogue () const +{ + return this->file_list_epilogue_; +} + +inline bool options:: +file_list_epilogue_specified () const +{ + return this->file_list_epilogue_specified_; +} + +inline const NarrowString& options:: +file_list_delim () const +{ + return this->file_list_delim_; +} + +inline bool options:: +file_list_delim_specified () const +{ + return this->file_list_delim_specified_; +} + +inline const bool& options:: +disable_multi_import () const +{ + return this->disable_multi_import_; +} + +inline const bool& options:: +disable_full_check () const +{ + return this->disable_full_check_; +} + +// Begin epilogue. +// +// +// End epilogue. diff --git a/xsd/processing/cardinality/processor.cxx b/xsd/xsd/processing/cardinality/processor.cxx index 2a5292e..c8c5dc5 100644 --- a/xsd/processing/cardinality/processor.cxx +++ b/xsd/xsd/processing/cardinality/processor.cxx @@ -1,14 +1,14 @@ -// file : processing/cardinality/processor.cxx +// file : xsd/processing/cardinality/processor.cxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file #include <map> -#include <xsd-frontend/semantic-graph.hxx> -#include <xsd-frontend/traversal.hxx> +#include <libxsd-frontend/semantic-graph.hxx> +#include <libxsd-frontend/traversal.hxx> -#include <elements.hxx> +#include <xsd/elements.hxx> -#include <processing/cardinality/processor.hxx> +#include <xsd/processing/cardinality/processor.hxx> using namespace std; diff --git a/xsd/xsd/processing/cardinality/processor.hxx b/xsd/xsd/processing/cardinality/processor.hxx new file mode 100644 index 0000000..93a85fb --- /dev/null +++ b/xsd/xsd/processing/cardinality/processor.hxx @@ -0,0 +1,28 @@ +// file : xsd/processing/cardinality/processor.hxx +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_PROCESSING_CARDINALITY_PROCESSOR_HXX +#define XSD_PROCESSING_CARDINALITY_PROCESSOR_HXX + +#include <libxsd-frontend/semantic-graph/elements.hxx> // Path +#include <libxsd-frontend/semantic-graph/schema.hxx> + +#include <xsd/types.hxx> + +namespace Processing +{ + namespace Cardinality + { + class Processor + { + public: + struct Failed {}; + + void + process (XSDFrontend::SemanticGraph::Schema&, + XSDFrontend::SemanticGraph::Path const& file); + }; + } +} + +#endif // XSD_PROCESSING_CARDINALITY_PROCESSOR_HXX diff --git a/xsd/processing/inheritance/processor.cxx b/xsd/xsd/processing/inheritance/processor.cxx index 9269852..6c0e40e 100644 --- a/xsd/processing/inheritance/processor.cxx +++ b/xsd/xsd/processing/inheritance/processor.cxx @@ -1,15 +1,15 @@ -// file : processing/inheritance/processor.cxx +// file : xsd/processing/inheritance/processor.cxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file #include <set> #include <iostream> -#include <processing/inheritance/processor.hxx> +#include <xsd/processing/inheritance/processor.hxx> -#include <elements.hxx> +#include <xsd/elements.hxx> -#include <xsd-frontend/semantic-graph.hxx> -#include <xsd-frontend/traversal.hxx> +#include <libxsd-frontend/semantic-graph.hxx> +#include <libxsd-frontend/traversal.hxx> using namespace std; diff --git a/xsd/xsd/processing/inheritance/processor.hxx b/xsd/xsd/processing/inheritance/processor.hxx new file mode 100644 index 0000000..2a70e02 --- /dev/null +++ b/xsd/xsd/processing/inheritance/processor.hxx @@ -0,0 +1,28 @@ +// file : xsd/processing/inheritance/processor.hxx +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_PROCESSING_INHERITANCE_PROCESSOR_HXX +#define XSD_PROCESSING_INHERITANCE_PROCESSOR_HXX + +#include <libxsd-frontend/semantic-graph/elements.hxx> // Path +#include <libxsd-frontend/semantic-graph/schema.hxx> + +#include <xsd/types.hxx> + +namespace Processing +{ + namespace Inheritance + { + class Processor + { + public: + struct Failed {}; + + void + process (XSDFrontend::SemanticGraph::Schema&, + XSDFrontend::SemanticGraph::Path const& file); + }; + } +} + +#endif // XSD_PROCESSING_INHERITANCE_PROCESSOR_HXX diff --git a/xsd/type-map/lexer.cxx b/xsd/xsd/type-map/lexer.cxx index 26600c5..ae318d1 100644 --- a/xsd/type-map/lexer.cxx +++ b/xsd/xsd/type-map/lexer.cxx @@ -3,7 +3,7 @@ #include <iostream> -#include <type-map/lexer.hxx> +#include <xsd/type-map/lexer.hxx> using std::wcerr; using std::endl; diff --git a/xsd/type-map/lexer.hxx b/xsd/xsd/type-map/lexer.hxx index ab16eb1..a0e1e44 100644 --- a/xsd/type-map/lexer.hxx +++ b/xsd/xsd/type-map/lexer.hxx @@ -7,7 +7,7 @@ #include <locale> #include <iosfwd> -#include <types.hxx> +#include <xsd/types.hxx> namespace TypeMap { diff --git a/xsd/type-map/parser.cxx b/xsd/xsd/type-map/parser.cxx index 39389f7..f11fac3 100644 --- a/xsd/type-map/parser.cxx +++ b/xsd/xsd/type-map/parser.cxx @@ -3,9 +3,9 @@ #include <iostream> -#include <cutl/re.hxx> +#include <libcutl/re.hxx> -#include <type-map/parser.hxx> +#include <xsd/type-map/parser.hxx> using std::endl; diff --git a/xsd/type-map/parser.hxx b/xsd/xsd/type-map/parser.hxx index eceb255..ec9ea49 100644 --- a/xsd/type-map/parser.hxx +++ b/xsd/xsd/type-map/parser.hxx @@ -4,10 +4,10 @@ #ifndef XSD_TYPE_MAP_PARSER_HXX #define XSD_TYPE_MAP_PARSER_HXX -#include <types.hxx> +#include <xsd/types.hxx> -#include <type-map/type-map.hxx> -#include <type-map/lexer.hxx> +#include <xsd/type-map/type-map.hxx> +#include <xsd/type-map/lexer.hxx> namespace TypeMap { diff --git a/xsd/type-map/type-map.hxx b/xsd/xsd/type-map/type-map.hxx index 374591e..dd2ec2c 100644 --- a/xsd/type-map/type-map.hxx +++ b/xsd/xsd/type-map/type-map.hxx @@ -1,14 +1,14 @@ // file : xsd/type-map/type-map.hxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#ifndef XSD_TYPE_MAP_TYPE_MAP_HXX -#define XSD_TYPE_MAP_TYPE_MAP_HXX +#ifndef XSD_XSD_TYPE_MAP_TYPE_MAP_HXX +#define XSD_XSD_TYPE_MAP_TYPE_MAP_HXX #include <vector> -#include <cutl/re.hxx> +#include <libcutl/re.hxx> -#include <types.hxx> +#include <xsd/types.hxx> namespace TypeMap { @@ -175,4 +175,4 @@ namespace TypeMap typedef std::vector<Namespace> Namespaces; } -#endif // XSD_TYPE_MAP_TYPE_MAP_HXX +#endif // XSD_XSD_TYPE_MAP_TYPE_MAP_HXX diff --git a/xsd/types.hxx b/xsd/xsd/types.hxx index 51af830..b3306dd 100644 --- a/xsd/types.hxx +++ b/xsd/xsd/types.hxx @@ -1,13 +1,13 @@ // file : xsd/types.hxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#ifndef TYPES_HXX -#define TYPES_HXX +#ifndef XSD_TYPES_HXX +#define XSD_TYPES_HXX #include <vector> #include <cstddef> // std::size_t -#include <xsd-frontend/types.hxx> +#include <libxsd-frontend/types.hxx> using std::size_t; @@ -16,4 +16,4 @@ using XSDFrontend::NarrowString; typedef std::vector<NarrowString> NarrowStrings; -#endif // TYPES_HXX +#endif // XSD_TYPES_HXX diff --git a/xsd/xsd/version.hxx.in b/xsd/xsd/version.hxx.in new file mode 100644 index 0000000..9bfd8a8 --- /dev/null +++ b/xsd/xsd/version.hxx.in @@ -0,0 +1,55 @@ +// file : xsd/version.hxx.in +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_VERSION // Note: using the version macro itself. + +// The numeric version format is AAAAABBBBBCCCCCDDDE where: +// +// AAAAA - major version number +// BBBBB - minor version number +// CCCCC - bugfix version number +// DDD - alpha / beta (DDD + 500) version number +// E - final (0) / snapshot (1) +// +// When DDDE is not 0, 1 is subtracted from AAAAABBBBBCCCCC. For example: +// +// Version AAAAABBBBBCCCCCDDDE +// +// 0.1.0 0000000001000000000 +// 0.1.2 0000000001000020000 +// 1.2.3 0000100002000030000 +// 2.2.0-a.1 0000200001999990010 +// 3.0.0-b.2 0000299999999995020 +// 2.2.0-a.1.z 0000200001999990011 +// +#define XSD_VERSION $xsd.version.project_number$ULL +#define XSD_VERSION_STR "$xsd.version.project$" +#define XSD_VERSION_ID "$xsd.version.project_id$" +#define XSD_VERSION_FULL "$xsd.version$" + +#define XSD_VERSION_MAJOR $xsd.version.major$ +#define XSD_VERSION_MINOR $xsd.version.minor$ +#define XSD_VERSION_PATCH $xsd.version.patch$ + +#define XSD_PRE_RELEASE $xsd.version.pre_release$ + +#define XSD_SNAPSHOT $xsd.version.snapshot_sn$ULL +#define XSD_SNAPSHOT_ID "$xsd.version.snapshot_id$" + +#include <xercesc/util/XercesVersion.hpp> + +// Check that we have a compatible Xerces version (3.0.0 or later). +// +#if _XERCES_VERSION < 30000 +# error Xerces-C++ 2-series is not supported +#endif + +#include <libcutl/version.hxx> + +$libcutl.check(LIBCUTL_VERSION, LIBCUTL_SNAPSHOT)$ + +#include <libxsd-frontend/version.hxx> + +$libxsd_frontend.check(LIBXSD_FRONTEND_VERSION, LIBXSD_FRONTEND_SNAPSHOT)$ + +#endif // XSD_VERSION diff --git a/xsd/xsd.cxx b/xsd/xsd/xsd.cxx index bcf7307..d2b0faf 100644 --- a/xsd/xsd.cxx +++ b/xsd/xsd/xsd.cxx @@ -3,36 +3,36 @@ #include <map> #include <vector> -#include <memory> // std::auto_ptr +#include <memory> // std::unique_ptr #include <cstddef> // std::size_t #include <iostream> #include <fstream> #include <xercesc/util/PlatformUtils.hpp> -#include <cutl/re.hxx> +#include <libcutl/re.hxx> -#include <xsd-frontend/parser.hxx> -#include <xsd-frontend/transformations/anonymous.hxx> -#include <xsd-frontend/transformations/enum-synthesis.cxx> -#include <xsd-frontend/transformations/restriction.hxx> -#include <xsd-frontend/transformations/schema-per-type.hxx> -#include <xsd-frontend/transformations/simplifier.hxx> +#include <libxsd-frontend/parser.hxx> +#include <libxsd-frontend/transformations/anonymous.hxx> +#include <libxsd-frontend/transformations/enum-synthesis.hxx> +#include <libxsd-frontend/transformations/restriction.hxx> +#include <libxsd-frontend/transformations/schema-per-type.hxx> +#include <libxsd-frontend/transformations/simplifier.hxx> -#include <cxx/tree/options.hxx> -#include <cxx/parser/options.hxx> +#include <xsd/version.hxx> -#include <cxx/tree/generator.hxx> -#include <cxx/parser/generator.hxx> +#include <xsd/cxx/tree/options.hxx> +#include <xsd/cxx/parser/options.hxx> -#include <processing/cardinality/processor.hxx> -#include <processing/inheritance/processor.hxx> +#include <xsd/cxx/tree/generator.hxx> +#include <xsd/cxx/parser/generator.hxx> -#include <xsd.hxx> -#include <types.hxx> -#include <options.hxx> +#include <xsd/processing/cardinality/processor.hxx> +#include <xsd/processing/inheritance/processor.hxx> -#include "../libxsd/xsd/cxx/version.hxx" +#include <xsd/xsd.hxx> +#include <xsd/types.hxx> +#include <xsd/options.hxx> namespace SemanticGraph = XSDFrontend::SemanticGraph; namespace Transformations = XSDFrontend::Transformations; @@ -154,6 +154,24 @@ main (int argc, char* argv[]) cli::argv_file_scanner args (argc, argv, "--options-file"); help_options help_ops (args, cli::unknown_mode::stop); + // Handle --build2-metadata (see also buildfile). + // + if (help_ops.build2_metadata_specified ()) + { + wostream& o (wcout); + + // Note that the export.metadata variable should be the first non- + // blank/comment line. + // + o << "# build2 buildfile xsd" << endl + << "export.metadata = 1 xsd" << endl + << "xsd.name = [string] xsd" << endl + << "xsd.version = [string] '" << XSD_VERSION_FULL << '\'' << endl + << "xsd.checksum = [string] '" << XSD_VERSION_FULL << '\'' << endl; + + return 0; + } + NarrowString cmd; if (args.more ()) cmd = args.next (); @@ -163,8 +181,8 @@ main (int argc, char* argv[]) wostream& o (wcout); o << "CodeSynthesis XSD XML Schema to C++ compiler " << - XSD_STR_VERSION << endl - << "Copyright (c) 2005-2020 Code Synthesis Tools CC." << endl; + XSD_VERSION_STR << endl + << "Copyright (c) " << XSD_COPYRIGHT << "." << endl; if (!help_ops.proprietary_license () && cmd == "version") { @@ -178,7 +196,7 @@ main (int argc, char* argv[]) { o << "The compiler was invoked in the Proprietary License mode. You " << "should have\nreceived a proprietary license from Code Synthesis " - << "Tools CC that entitles\nyou to use it in this mode." << endl; + << "that entitles you to\nuse it in this mode." << endl; } else { @@ -269,10 +287,10 @@ main (int argc, char* argv[]) // We need to parse command line options before we can get to // the arguments. // - auto_ptr<CXX::Tree::options> tree_ops ( + unique_ptr<CXX::Tree::options> tree_ops ( cmd == "cxx-tree" ? new CXX::Tree::options (args) : 0); - auto_ptr<CXX::Parser::options> parser_ops ( + unique_ptr<CXX::Parser::options> parser_ops ( cmd == "cxx-parser" ? new CXX::Parser::options (args) : 0); CXX::options& common_ops ( @@ -280,6 +298,14 @@ main (int argc, char* argv[]) ? static_cast<CXX::options&> (*tree_ops) : static_cast<CXX::options&> (*parser_ops)); + // Validate options. + // + if (common_ops.file_list_only () && !common_ops.file_list_specified ()) + { + e << "error: --file-list-only specified without --file-list" << endl; + return 1; + } + // Disabled warnings. // WarningSet disabled_w; @@ -434,7 +460,7 @@ main (int argc, char* argv[]) loc_translator, disabled_w); - auto_ptr<SemanticGraph::Schema> schema; + unique_ptr<SemanticGraph::Schema> schema; if (cmd == "cxx-tree" || cmd == "cxx-parser") { @@ -612,7 +638,7 @@ main (int argc, char* argv[]) loc_translator, disabled_w); - auto_ptr<SemanticGraph::Schema> schema (parser.parse (paths)); + unique_ptr<SemanticGraph::Schema> schema (parser.parse (paths)); // Morph anonymous types. // @@ -752,38 +778,43 @@ main (int argc, char* argv[]) try { OutputFileStream ofs; - SemanticGraph::Path path (fl); + if (fl != "-") + { + SemanticGraph::Path path (fl); - ofs.open (path.string ().c_str (), ios_base::out); + ofs.open (path.string ().c_str (), ios_base::out); - if (!ofs.is_open ()) - { - wcerr << path << ": error: unable to open in write mode" << endl; - return 1; + if (!ofs.is_open ()) + { + wcerr << path << ": error: unable to open in write mode" << endl; + return 1; + } } + std::ostream& os (ofs.is_open () ? ofs : cout); + NarrowString d (common_ops.file_list_delim ()); expand_nl (d); if (NarrowString p = common_ops.file_list_prologue ()) { expand_nl (p); - ofs << p; + os << p; } for (FileList::iterator i (file_list.begin ()), e (file_list.end ()); i != e;) { - ofs << *i; + os << *i; if (++i != e) - ofs << d; + os << d; } if (NarrowString e = common_ops.file_list_epilogue ()) { expand_nl (e); - ofs << e; + os << e; } } catch (SemanticGraph::InvalidPath const&) diff --git a/xsd/xsd.hxx b/xsd/xsd/xsd.hxx index f1bbd5f..5ce2926 100644 --- a/xsd/xsd.hxx +++ b/xsd/xsd/xsd.hxx @@ -1,19 +1,19 @@ // file : xsd/xsd.hxx // license : GNU GPL v2 + exceptions; see accompanying LICENSE file -#ifndef XSD_HXX -#define XSD_HXX +#ifndef XSD_XSD_HXX +#define XSD_XSD_HXX #include <set> #include <vector> #include <cstdio> // std::remove -#include <cutl/shared-ptr.hxx> -#include <cutl/fs/auto-remove.hxx> +#include <libcutl/shared-ptr.hxx> +#include <libcutl/fs/auto-remove.hxx> -#include <xsd-frontend/semantic-graph/elements.hxx> // Path +#include <libxsd-frontend/semantic-graph/elements.hxx> // Path -#include <types.hxx> +#include <xsd/types.hxx> typedef std::set<NarrowString> WarningSet; typedef std::vector<NarrowString> FileList; @@ -21,4 +21,4 @@ typedef std::vector<NarrowString> FileList; typedef cutl::fs::auto_remove AutoUnlink; typedef cutl::fs::auto_removes AutoUnlinks; -#endif // XSD_HXX +#endif // XSD_XSD_HXX |