From a15cf65c44d5c224169c32ef5495b68c758134b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Sun, 18 May 2014 16:08:14 +0200 Subject: Imported Upstream version 3.3.0.2 --- libxsd-frontend/GPLv2 | 340 ++ libxsd-frontend/INSTALL | 28 + libxsd-frontend/LICENSE | 22 + libxsd-frontend/NEWS | 281 ++ libxsd-frontend/README | 13 + libxsd-frontend/build/bootstrap.make | 46 + .../build/cxx/configuration-dynamic.make | 14 + .../build/cxx/gnu/configuration-dynamic.make | 8 + .../build/export/libxsd-frontend/stub.make | 10 + libxsd-frontend/build/import/libboost/LICENSE | 340 ++ .../import/libboost/configuration-dynamic.make | 8 + .../build/import/libboost/configuration-rules.make | 15 + libxsd-frontend/build/import/libboost/configure | 74 + .../build/import/libboost/filesystem/rules.make | 53 + .../build/import/libboost/filesystem/stub.make | 36 + libxsd-frontend/build/import/libboost/version | 1 + libxsd-frontend/build/import/libcult/LICENSE | 340 ++ .../import/libcult/configuration-dynamic.make | 4 + .../build/import/libcult/configuration-rules.make | 15 + libxsd-frontend/build/import/libcult/configure | 55 + libxsd-frontend/build/import/libcult/stub.make | 30 + .../build/import/libfrontend-elements/LICENSE | 340 ++ .../configuration-dynamic.make | 4 + .../libfrontend-elements/configuration-rules.make | 15 + .../build/import/libfrontend-elements/configure | 55 + .../build/import/libfrontend-elements/stub.make | 30 + libxsd-frontend/build/import/libxerces-c/LICENSE | 340 ++ .../import/libxerces-c/configuration-dynamic.make | 1 + .../import/libxerces-c/configuration-rules.make | 15 + libxsd-frontend/build/import/libxerces-c/configure | 73 + .../build/import/libxerces-c/rules.make | 52 + libxsd-frontend/build/import/libxerces-c/stub.make | 32 + libxsd-frontend/build/import/libxerces-c/version | 1 + .../build/import/libxsd-frontend/LICENSE | 1 + .../libxsd-frontend/configuration-rules.make | 15 + .../build/import/libxsd-frontend/configure | 55 + .../build/import/libxsd-frontend/stub.make | 30 + .../build/ld/configuration-lib-dynamic.make | 13 + libxsd-frontend/makefile | 17 + libxsd-frontend/tests/dump/driver.cxx | 734 +++ libxsd-frontend/tests/dump/makefile | 56 + libxsd-frontend/tests/makefile | 17 + libxsd-frontend/tests/schema/annotation/makefile | 35 + .../tests/schema/annotation/test-000.std | 67 + .../tests/schema/annotation/test-000.xsd | 120 + .../tests/schema/annotation/test-001.std | 36 + .../tests/schema/annotation/test-001.xsd | 53 + libxsd-frontend/tests/schema/anonymous/makefile | 35 + .../tests/schema/anonymous/test-000.std | 30 + .../tests/schema/anonymous/test-000.xsd | 42 + .../tests/schema/anonymous/test-001.std | 38 + .../tests/schema/anonymous/test-001.xsd | 47 + .../tests/schema/attribute-group/makefile | 35 + .../tests/schema/attribute-group/test-000.std | 17 + .../tests/schema/attribute-group/test-000.xsd | 31 + .../tests/schema/attribute-group/test-001.std | 12 + .../tests/schema/attribute-group/test-001.xsd | 20 + libxsd-frontend/tests/schema/default/makefile | 35 + libxsd-frontend/tests/schema/default/test-000.std | 28 + libxsd-frontend/tests/schema/default/test-000.xsd | 23 + libxsd-frontend/tests/schema/default/test-001.std | 15 + libxsd-frontend/tests/schema/default/test-001.xsd | 11 + .../tests/schema/element-group/makefile | 35 + .../tests/schema/element-group/test-000.std | 33 + .../tests/schema/element-group/test-000.xsd | 39 + .../tests/schema/element-group/test-001.std | 137 + .../tests/schema/element-group/test-001.xsd | 33 + .../tests/schema/element-group/test-002.std | 24 + .../tests/schema/element-group/test-002.xsd | 26 + libxsd-frontend/tests/schema/enumeration/makefile | 35 + .../tests/schema/enumeration/test-000.std | 62 + .../tests/schema/enumeration/test-000.xsd | 72 + libxsd-frontend/tests/schema/makefile | 25 + libxsd-frontend/tests/schema/union/makefile | 35 + libxsd-frontend/tests/schema/union/test-000.std | 37 + libxsd-frontend/tests/schema/union/test-000.xsd | 40 + libxsd-frontend/tests/schema/union/test-001.std | 15 + libxsd-frontend/tests/schema/union/test-001.xsd | 21 + libxsd-frontend/version | 1 + libxsd-frontend/xsd-frontend/makefile | 126 + libxsd-frontend/xsd-frontend/parser.cxx | 5126 ++++++++++++++++++++ libxsd-frontend/xsd-frontend/parser.hxx | 76 + libxsd-frontend/xsd-frontend/schema-dom-parser.cxx | 196 + libxsd-frontend/xsd-frontend/schema-dom-parser.hxx | 93 + libxsd-frontend/xsd-frontend/semantic-graph.hxx | 27 + .../xsd-frontend/semantic-graph/annotation.cxx | 50 + .../xsd-frontend/semantic-graph/annotation.hxx | 89 + .../xsd-frontend/semantic-graph/any-attribute.cxx | 114 + .../xsd-frontend/semantic-graph/any-attribute.hxx | 85 + .../xsd-frontend/semantic-graph/any.cxx | 125 + .../xsd-frontend/semantic-graph/any.hxx | 90 + .../semantic-graph/attribute-group.cxx | 39 + .../semantic-graph/attribute-group.hxx | 27 + .../xsd-frontend/semantic-graph/attribute.cxx | 44 + .../xsd-frontend/semantic-graph/attribute.hxx | 39 + .../xsd-frontend/semantic-graph/complex.cxx | 45 + .../xsd-frontend/semantic-graph/complex.hxx | 78 + .../xsd-frontend/semantic-graph/compositors.cxx | 124 + .../xsd-frontend/semantic-graph/compositors.hxx | 263 + .../xsd-frontend/semantic-graph/element-group.cxx | 38 + .../xsd-frontend/semantic-graph/element-group.hxx | 45 + .../xsd-frontend/semantic-graph/element.cxx | 63 + .../xsd-frontend/semantic-graph/element.hxx | 105 + .../xsd-frontend/semantic-graph/elements.cxx | 350 ++ .../xsd-frontend/semantic-graph/elements.hxx | 1247 +++++ .../xsd-frontend/semantic-graph/enumeration.cxx | 67 + .../xsd-frontend/semantic-graph/enumeration.hxx | 35 + .../xsd-frontend/semantic-graph/fundamental.cxx.m4 | 216 + .../xsd-frontend/semantic-graph/fundamental.hxx.m4 | 165 + .../xsd-frontend/semantic-graph/fundamental.m4 | 18 + .../xsd-frontend/semantic-graph/list.cxx | 37 + .../xsd-frontend/semantic-graph/list.hxx | 25 + .../xsd-frontend/semantic-graph/namespace.cxx | 37 + .../xsd-frontend/semantic-graph/namespace.hxx | 32 + .../xsd-frontend/semantic-graph/particle.cxx | 61 + .../xsd-frontend/semantic-graph/particle.hxx | 145 + .../xsd-frontend/semantic-graph/schema.cxx | 139 + .../xsd-frontend/semantic-graph/schema.hxx | 281 ++ .../xsd-frontend/semantic-graph/union.cxx | 37 + .../xsd-frontend/semantic-graph/union.hxx | 25 + .../xsd-frontend/transformations/anonymous.cxx | 739 +++ .../xsd-frontend/transformations/anonymous.hxx | 60 + .../transformations/enum-synthesis.cxx | 249 + .../transformations/enum-synthesis.hxx | 33 + .../xsd-frontend/transformations/restriction.cxx | 582 +++ .../xsd-frontend/transformations/restriction.hxx | 39 + .../transformations/schema-per-type.cxx | 453 ++ .../transformations/schema-per-type.hxx | 61 + .../xsd-frontend/transformations/simplifier.cxx | 167 + .../xsd-frontend/transformations/simplifier.hxx | 33 + libxsd-frontend/xsd-frontend/traversal.hxx | 26 + .../xsd-frontend/traversal/any-attribute.hxx | 22 + libxsd-frontend/xsd-frontend/traversal/any.hxx | 22 + .../xsd-frontend/traversal/attribute-group.cxx | 30 + .../xsd-frontend/traversal/attribute-group.hxx | 30 + .../xsd-frontend/traversal/attribute.cxx | 48 + .../xsd-frontend/traversal/attribute.hxx | 41 + libxsd-frontend/xsd-frontend/traversal/complex.cxx | 64 + libxsd-frontend/xsd-frontend/traversal/complex.hxx | 45 + .../xsd-frontend/traversal/compositors.cxx | 165 + .../xsd-frontend/traversal/compositors.hxx | 136 + .../xsd-frontend/traversal/element-group.cxx | 43 + .../xsd-frontend/traversal/element-group.hxx | 36 + libxsd-frontend/xsd-frontend/traversal/element.cxx | 48 + libxsd-frontend/xsd-frontend/traversal/element.hxx | 39 + .../xsd-frontend/traversal/elements.cxx | 77 + .../xsd-frontend/traversal/elements.hxx | 480 ++ .../xsd-frontend/traversal/elements.txx | 11 + .../xsd-frontend/traversal/enumeration.cxx | 91 + .../xsd-frontend/traversal/enumeration.hxx | 60 + .../xsd-frontend/traversal/fundamental.cxx | 13 + .../xsd-frontend/traversal/fundamental.hxx | 234 + libxsd-frontend/xsd-frontend/traversal/list.cxx | 48 + libxsd-frontend/xsd-frontend/traversal/list.hxx | 39 + .../xsd-frontend/traversal/namespace.cxx | 13 + .../xsd-frontend/traversal/namespace.hxx | 45 + .../xsd-frontend/traversal/particle.cxx | 31 + .../xsd-frontend/traversal/particle.hxx | 30 + libxsd-frontend/xsd-frontend/traversal/schema.cxx | 13 + libxsd-frontend/xsd-frontend/traversal/schema.hxx | 150 + libxsd-frontend/xsd-frontend/traversal/union.cxx | 48 + libxsd-frontend/xsd-frontend/traversal/union.hxx | 39 + libxsd-frontend/xsd-frontend/types.hxx | 18 + libxsd-frontend/xsd-frontend/xml.hxx | 567 +++ 164 files changed, 20271 insertions(+) create mode 100644 libxsd-frontend/GPLv2 create mode 100644 libxsd-frontend/INSTALL create mode 100644 libxsd-frontend/LICENSE create mode 100644 libxsd-frontend/NEWS create mode 100644 libxsd-frontend/README create mode 100644 libxsd-frontend/build/bootstrap.make create mode 100644 libxsd-frontend/build/cxx/configuration-dynamic.make create mode 100644 libxsd-frontend/build/cxx/gnu/configuration-dynamic.make create mode 100644 libxsd-frontend/build/export/libxsd-frontend/stub.make create mode 100644 libxsd-frontend/build/import/libboost/LICENSE create mode 100644 libxsd-frontend/build/import/libboost/configuration-dynamic.make create mode 100644 libxsd-frontend/build/import/libboost/configuration-rules.make create mode 100755 libxsd-frontend/build/import/libboost/configure create mode 100644 libxsd-frontend/build/import/libboost/filesystem/rules.make create mode 100644 libxsd-frontend/build/import/libboost/filesystem/stub.make create mode 100644 libxsd-frontend/build/import/libboost/version create mode 100644 libxsd-frontend/build/import/libcult/LICENSE create mode 100644 libxsd-frontend/build/import/libcult/configuration-dynamic.make create mode 100644 libxsd-frontend/build/import/libcult/configuration-rules.make create mode 100755 libxsd-frontend/build/import/libcult/configure create mode 100644 libxsd-frontend/build/import/libcult/stub.make create mode 100644 libxsd-frontend/build/import/libfrontend-elements/LICENSE create mode 100644 libxsd-frontend/build/import/libfrontend-elements/configuration-dynamic.make create mode 100644 libxsd-frontend/build/import/libfrontend-elements/configuration-rules.make create mode 100755 libxsd-frontend/build/import/libfrontend-elements/configure create mode 100644 libxsd-frontend/build/import/libfrontend-elements/stub.make create mode 100644 libxsd-frontend/build/import/libxerces-c/LICENSE create mode 100644 libxsd-frontend/build/import/libxerces-c/configuration-dynamic.make create mode 100644 libxsd-frontend/build/import/libxerces-c/configuration-rules.make create mode 100755 libxsd-frontend/build/import/libxerces-c/configure create mode 100644 libxsd-frontend/build/import/libxerces-c/rules.make create mode 100644 libxsd-frontend/build/import/libxerces-c/stub.make create mode 100644 libxsd-frontend/build/import/libxerces-c/version create mode 120000 libxsd-frontend/build/import/libxsd-frontend/LICENSE create mode 100644 libxsd-frontend/build/import/libxsd-frontend/configuration-rules.make create mode 100755 libxsd-frontend/build/import/libxsd-frontend/configure create mode 100644 libxsd-frontend/build/import/libxsd-frontend/stub.make create mode 100644 libxsd-frontend/build/ld/configuration-lib-dynamic.make create mode 100644 libxsd-frontend/makefile create mode 100644 libxsd-frontend/tests/dump/driver.cxx create mode 100644 libxsd-frontend/tests/dump/makefile create mode 100644 libxsd-frontend/tests/makefile create mode 100644 libxsd-frontend/tests/schema/annotation/makefile create mode 100644 libxsd-frontend/tests/schema/annotation/test-000.std create mode 100644 libxsd-frontend/tests/schema/annotation/test-000.xsd create mode 100644 libxsd-frontend/tests/schema/annotation/test-001.std create mode 100644 libxsd-frontend/tests/schema/annotation/test-001.xsd create mode 100644 libxsd-frontend/tests/schema/anonymous/makefile create mode 100644 libxsd-frontend/tests/schema/anonymous/test-000.std create mode 100644 libxsd-frontend/tests/schema/anonymous/test-000.xsd create mode 100644 libxsd-frontend/tests/schema/anonymous/test-001.std create mode 100644 libxsd-frontend/tests/schema/anonymous/test-001.xsd create mode 100644 libxsd-frontend/tests/schema/attribute-group/makefile create mode 100644 libxsd-frontend/tests/schema/attribute-group/test-000.std create mode 100644 libxsd-frontend/tests/schema/attribute-group/test-000.xsd create mode 100644 libxsd-frontend/tests/schema/attribute-group/test-001.std create mode 100644 libxsd-frontend/tests/schema/attribute-group/test-001.xsd create mode 100644 libxsd-frontend/tests/schema/default/makefile create mode 100644 libxsd-frontend/tests/schema/default/test-000.std create mode 100644 libxsd-frontend/tests/schema/default/test-000.xsd create mode 100644 libxsd-frontend/tests/schema/default/test-001.std create mode 100644 libxsd-frontend/tests/schema/default/test-001.xsd create mode 100644 libxsd-frontend/tests/schema/element-group/makefile create mode 100644 libxsd-frontend/tests/schema/element-group/test-000.std create mode 100644 libxsd-frontend/tests/schema/element-group/test-000.xsd create mode 100644 libxsd-frontend/tests/schema/element-group/test-001.std create mode 100644 libxsd-frontend/tests/schema/element-group/test-001.xsd create mode 100644 libxsd-frontend/tests/schema/element-group/test-002.std create mode 100644 libxsd-frontend/tests/schema/element-group/test-002.xsd create mode 100644 libxsd-frontend/tests/schema/enumeration/makefile create mode 100644 libxsd-frontend/tests/schema/enumeration/test-000.std create mode 100644 libxsd-frontend/tests/schema/enumeration/test-000.xsd create mode 100644 libxsd-frontend/tests/schema/makefile create mode 100644 libxsd-frontend/tests/schema/union/makefile create mode 100644 libxsd-frontend/tests/schema/union/test-000.std create mode 100644 libxsd-frontend/tests/schema/union/test-000.xsd create mode 100644 libxsd-frontend/tests/schema/union/test-001.std create mode 100644 libxsd-frontend/tests/schema/union/test-001.xsd create mode 100644 libxsd-frontend/version create mode 100644 libxsd-frontend/xsd-frontend/makefile create mode 100644 libxsd-frontend/xsd-frontend/parser.cxx create mode 100644 libxsd-frontend/xsd-frontend/parser.hxx create mode 100644 libxsd-frontend/xsd-frontend/schema-dom-parser.cxx create mode 100644 libxsd-frontend/xsd-frontend/schema-dom-parser.hxx create mode 100644 libxsd-frontend/xsd-frontend/semantic-graph.hxx create mode 100644 libxsd-frontend/xsd-frontend/semantic-graph/annotation.cxx create mode 100644 libxsd-frontend/xsd-frontend/semantic-graph/annotation.hxx create mode 100644 libxsd-frontend/xsd-frontend/semantic-graph/any-attribute.cxx create mode 100644 libxsd-frontend/xsd-frontend/semantic-graph/any-attribute.hxx create mode 100644 libxsd-frontend/xsd-frontend/semantic-graph/any.cxx create mode 100644 libxsd-frontend/xsd-frontend/semantic-graph/any.hxx create mode 100644 libxsd-frontend/xsd-frontend/semantic-graph/attribute-group.cxx create mode 100644 libxsd-frontend/xsd-frontend/semantic-graph/attribute-group.hxx create mode 100644 libxsd-frontend/xsd-frontend/semantic-graph/attribute.cxx create mode 100644 libxsd-frontend/xsd-frontend/semantic-graph/attribute.hxx create mode 100644 libxsd-frontend/xsd-frontend/semantic-graph/complex.cxx create mode 100644 libxsd-frontend/xsd-frontend/semantic-graph/complex.hxx create mode 100644 libxsd-frontend/xsd-frontend/semantic-graph/compositors.cxx create mode 100644 libxsd-frontend/xsd-frontend/semantic-graph/compositors.hxx create mode 100644 libxsd-frontend/xsd-frontend/semantic-graph/element-group.cxx create mode 100644 libxsd-frontend/xsd-frontend/semantic-graph/element-group.hxx create mode 100644 libxsd-frontend/xsd-frontend/semantic-graph/element.cxx create mode 100644 libxsd-frontend/xsd-frontend/semantic-graph/element.hxx create mode 100644 libxsd-frontend/xsd-frontend/semantic-graph/elements.cxx create mode 100644 libxsd-frontend/xsd-frontend/semantic-graph/elements.hxx create mode 100644 libxsd-frontend/xsd-frontend/semantic-graph/enumeration.cxx create mode 100644 libxsd-frontend/xsd-frontend/semantic-graph/enumeration.hxx create mode 100644 libxsd-frontend/xsd-frontend/semantic-graph/fundamental.cxx.m4 create mode 100644 libxsd-frontend/xsd-frontend/semantic-graph/fundamental.hxx.m4 create mode 100644 libxsd-frontend/xsd-frontend/semantic-graph/fundamental.m4 create mode 100644 libxsd-frontend/xsd-frontend/semantic-graph/list.cxx create mode 100644 libxsd-frontend/xsd-frontend/semantic-graph/list.hxx create mode 100644 libxsd-frontend/xsd-frontend/semantic-graph/namespace.cxx create mode 100644 libxsd-frontend/xsd-frontend/semantic-graph/namespace.hxx create mode 100644 libxsd-frontend/xsd-frontend/semantic-graph/particle.cxx create mode 100644 libxsd-frontend/xsd-frontend/semantic-graph/particle.hxx create mode 100644 libxsd-frontend/xsd-frontend/semantic-graph/schema.cxx create mode 100644 libxsd-frontend/xsd-frontend/semantic-graph/schema.hxx create mode 100644 libxsd-frontend/xsd-frontend/semantic-graph/union.cxx create mode 100644 libxsd-frontend/xsd-frontend/semantic-graph/union.hxx create mode 100644 libxsd-frontend/xsd-frontend/transformations/anonymous.cxx create mode 100644 libxsd-frontend/xsd-frontend/transformations/anonymous.hxx create mode 100644 libxsd-frontend/xsd-frontend/transformations/enum-synthesis.cxx create mode 100644 libxsd-frontend/xsd-frontend/transformations/enum-synthesis.hxx create mode 100644 libxsd-frontend/xsd-frontend/transformations/restriction.cxx create mode 100644 libxsd-frontend/xsd-frontend/transformations/restriction.hxx create mode 100644 libxsd-frontend/xsd-frontend/transformations/schema-per-type.cxx create mode 100644 libxsd-frontend/xsd-frontend/transformations/schema-per-type.hxx create mode 100644 libxsd-frontend/xsd-frontend/transformations/simplifier.cxx create mode 100644 libxsd-frontend/xsd-frontend/transformations/simplifier.hxx create mode 100644 libxsd-frontend/xsd-frontend/traversal.hxx create mode 100644 libxsd-frontend/xsd-frontend/traversal/any-attribute.hxx create mode 100644 libxsd-frontend/xsd-frontend/traversal/any.hxx create mode 100644 libxsd-frontend/xsd-frontend/traversal/attribute-group.cxx create mode 100644 libxsd-frontend/xsd-frontend/traversal/attribute-group.hxx create mode 100644 libxsd-frontend/xsd-frontend/traversal/attribute.cxx create mode 100644 libxsd-frontend/xsd-frontend/traversal/attribute.hxx create mode 100644 libxsd-frontend/xsd-frontend/traversal/complex.cxx create mode 100644 libxsd-frontend/xsd-frontend/traversal/complex.hxx create mode 100644 libxsd-frontend/xsd-frontend/traversal/compositors.cxx create mode 100644 libxsd-frontend/xsd-frontend/traversal/compositors.hxx create mode 100644 libxsd-frontend/xsd-frontend/traversal/element-group.cxx create mode 100644 libxsd-frontend/xsd-frontend/traversal/element-group.hxx create mode 100644 libxsd-frontend/xsd-frontend/traversal/element.cxx create mode 100644 libxsd-frontend/xsd-frontend/traversal/element.hxx create mode 100644 libxsd-frontend/xsd-frontend/traversal/elements.cxx create mode 100644 libxsd-frontend/xsd-frontend/traversal/elements.hxx create mode 100644 libxsd-frontend/xsd-frontend/traversal/elements.txx create mode 100644 libxsd-frontend/xsd-frontend/traversal/enumeration.cxx create mode 100644 libxsd-frontend/xsd-frontend/traversal/enumeration.hxx create mode 100644 libxsd-frontend/xsd-frontend/traversal/fundamental.cxx create mode 100644 libxsd-frontend/xsd-frontend/traversal/fundamental.hxx create mode 100644 libxsd-frontend/xsd-frontend/traversal/list.cxx create mode 100644 libxsd-frontend/xsd-frontend/traversal/list.hxx create mode 100644 libxsd-frontend/xsd-frontend/traversal/namespace.cxx create mode 100644 libxsd-frontend/xsd-frontend/traversal/namespace.hxx create mode 100644 libxsd-frontend/xsd-frontend/traversal/particle.cxx create mode 100644 libxsd-frontend/xsd-frontend/traversal/particle.hxx create mode 100644 libxsd-frontend/xsd-frontend/traversal/schema.cxx create mode 100644 libxsd-frontend/xsd-frontend/traversal/schema.hxx create mode 100644 libxsd-frontend/xsd-frontend/traversal/union.cxx create mode 100644 libxsd-frontend/xsd-frontend/traversal/union.hxx create mode 100644 libxsd-frontend/xsd-frontend/types.hxx create mode 100644 libxsd-frontend/xsd-frontend/xml.hxx (limited to 'libxsd-frontend') diff --git a/libxsd-frontend/GPLv2 b/libxsd-frontend/GPLv2 new file mode 100644 index 0000000..3912109 --- /dev/null +++ b/libxsd-frontend/GPLv2 @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/libxsd-frontend/INSTALL b/libxsd-frontend/INSTALL new file mode 100644 index 0000000..756b7e4 --- /dev/null +++ b/libxsd-frontend/INSTALL @@ -0,0 +1,28 @@ +Prerequisites + + build-time: + + - build >= 0.3.7 http://www.codesynthesis.com/projects/build/ + - g++ >= 3.4.3 http://gcc.gnu.org + + run-time: + + - libfrontend-elements >= 1.1.4 http://kolpackov.net/projects/libfrontend-elements/ + - libcult >= 1.4.6 http://kolpackov.net/projects/libcult/ + - libxerces-c >= 2.6.0 http://xerces.apache.org/xerces-c/ + - libboost_filesystem >= 1.33.1 http://boost.org + + +Building libxsd-frontend + + To build in the source directory simply run 'make'. You can also + build in a separate directory, e.g., + + $ mkdir libxsd-frontend-i686-pc-linux-gnu + $ cd libxsd-frontend-i686-pc-linux-gnu + $ make -f ../libxsd-frontend-x.y.z/makefile + + +Installing libxsd-frontend + + Not supported in this version. diff --git a/libxsd-frontend/LICENSE b/libxsd-frontend/LICENSE new file mode 100644 index 0000000..33b4cbc --- /dev/null +++ b/libxsd-frontend/LICENSE @@ -0,0 +1,22 @@ +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License version 2 as +published by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +In addition, as a special exception, Code Synthesis Tools CC gives +permission to link this program with the Xerces-C++ library (or with +modified versions of Xerces-C++ that use the same license as Xerces-C++), +and distribute linked combinations including the two. You must obey +the GNU General Public License version 2 in all respects for all of +the code used other than Xerces-C++. If you modify this copy of the +program, you may extend this exception to your version of the program, +but you are not obligated to do so. If you do not wish to do so, delete +this exception statement from your version. diff --git a/libxsd-frontend/NEWS b/libxsd-frontend/NEWS new file mode 100644 index 0000000..aca46a7 --- /dev/null +++ b/libxsd-frontend/NEWS @@ -0,0 +1,281 @@ +Version 1.17.0 + + * Add support for resolving default/fixed values of QName type. Now + the qualified value is represented in the # form. + + * Anonymous transformation now passes the actual file path instead of + the empty string to the AnonymousNameTranslator::translate() function + for the translation unit. + + * Anonymous transformation now names anonymous union member types. + + * Do not copy ref'ed default values for non-optional attributes. + + * Change predicate names in the semantic graph to consistently end + with _p. + + * New transformation: enum synthesis. + + * Add union information to the semantics graph. + + * Add support for translating schema file paths. + +Version 1.16.0 + + * New transformation: simplifier. It simplifies the schema graph + by, for example, removing empty compositors where it would not + change the semantics of the schema. + + * Added min() and max() accessors to the Particle and Compositor + semantic graph nodes. + + * Added optional strong include key to the schema-per-type + transformation. + +Version 1.15.0 + + * Support for the simple type/simple content restriction facets. + + * Support for suppressing frontend warnings. + + * Support for suppressing full schema checking. + + * Support for the interface changes introduced in Xerces-C++ 3.0.0.b2. + +Version 1.14.0 + + * Support for referencing names in including schema in chameleon inclusion. + + * Support for native paths in include/import directives. + + * Support for UTF-32 and UTF-16 in wchar_t. + + * Fixed a bug in import stubs. + + * Got rid of warnings reported by g++-4.3. + +Version 1.13.0 + + * Support for anonymous list item and simple type restriction base + in both parser and anonymous transformation. + +Version 1.12.0 + + * New transformations: anonymous and schema-per-type. + + * Optional location translator can now be passed to parser's + c-tor to translate included and imported schema locations. + + * Support for the upcoming Xerces-C++ 3.0.0 release. + + * Upgraded to the new boost import stub. + + * Upgraded to the new xerces-c import stub. + +Version 1.11.0 + + * New transformation, xsd-frontend/transformations/restriction.hxx, + copies omitted attributes and establishes associations between + attributes, elements, and wildcards in complex type inheritance + by restriction. + + * Upgraded to the new boost import stub. + +Version 1.10.1 + + * Add XML Schema error detection that is missing in Xerces-C++. + + * Update Xerces-C++ import stub to use the include directory + instead of src for header inclusion. + +Version 1.10.0 + + * New semantic graph node Annotation and edge Annotates. The parser + now handles XML Schema annotations and builds the corresponding + representation in the semantic graph. + + * The library no longer depends on the internal Xerces-C++ headers + and can be built against an installed version of Xerces-C++. + +Version 1.9.1 + + * Element wildcard (SemanticGraph::Any) is now present in the complex + type scope with an auto-generated name. + + * Additional regression tests for wildcard parsing. + +Version 1.9.0 + + * Upgraded to build-0.3.0. + +Version 1.8.3 + + * Fix for a bug in the edge case of empty prefix namespace resolution. + +Version 1.8.2 + + * Fix for a bug in element ordering. + + +Version 1.8.1 + + * Fix for a bug in element group forward reference resolution. + + * Set of regression tests. + + +Version 1.8.0 + + * Support for the anyAttribute wildcard. + + * Substitution edge is now propagated to referenced elements. + + * Special parsing method which returns a graph that virtually + corresponds to the XML Schema namespace definition with all + the built-in type. + + * Mixed content flag in SemanticGraph::Complex. + + * Optional proper handling of inheritance by restriction. + + +Version 1.7.0 + + * Added Restricts and Extends edges that model XML Schema inheritance + by restriction and inheritance by extension, respectively. The parser + was adjusted to use these edges instead of the generic Inherits edge. + + * Implemented handling of the complex content inheritance by restriction. + + * Fixed the chameleon inclusion code to create one Schema node per each + unique namespace. + + * Removed support for multiple inheritance in Complex. + + * Added a constructor that takes one node traverser to all edge traversers. + + +Version 1.6.1 + + * Bug fixes in the parser. + + +Version 1.6.0 + + * Support for traversing inheritance graph of enumerations. + + * Support for removal of Names edges. + + +Version 1.5.0 + + * Semantic graph now captures containment relations for elements. New + semantic graph nodes: particle, compositor, all, choice, sequence. + + * Element and attribute groups are not first-class semantic graph + nodes: element-group and attribute-group. References to groups + are still fully resolved (i.e., their content is copied into + referencing constructs). + + +Version 1.4.1 + + * Upgraded to the version-aware libboost import stub. + + +Version 1.4.0 + + * Moved to the build 0.2 series. + + * Support for the default and fixed values in attribute and element + definitions. + + +Version 1.3.0 + + * Several bug fixes in the parser. + + * Basic support for union. Union member types are not yet tracked. + + +Version 1.2.0 + + * Bug fixes in the parser. + + * Support for the 'substitutes' relation. + + * A flag that indicates whether an element is global. + + +Version 1.1.0 + + * Basic support for inheritance-by-restriction of complex types. + + * Support for mixed content model by simply ignoring the attribute. + + * Support for xsd:anyAttribute by simply ignoring the declaration. + + * Support for xsd:any. + + * Support for the element/attribute-belongs-to-a-namespace relation + for qualified elements and attributes. + + +Version 1.0.6 + + * Bug fixes in the parser. + + * Support for xsd:list. + + * Support for the 'refType' extension attribute which allows to specify + referenced type for IDREF/IDREFS data types. + + +Version 1.0.5 + + * Bug fixes in the parser. + + * SemanticGraph::Scope::NamesList uses List container instead of Vector. + This allows changing the semantic graph while traversing it. + + * SemanticGraph::Schema graph node supports multiple incoming Contains + edges. + + * Traversal::Scope has been extended to support traversal of changing + semantic graphs. + + +Version 1.0.4 + + * Diagnostics improvements. + + * Bug fixes in the filesystem path handling logic. + + +Version 1.0.3 + + * Bug fixes in the filesystem path handling logic. + + +Version 1.0.2 + + * Parser now handles subsequent inclusion/importing of the same + schema by creating an appropriate edge in the semantic graph. + Note that this may result in the semantic graph having cycles + of Includes/Imports/Sources edges. + + * Support for iteration over Belongs edges in SemanticGraph::Type. + + +Version 1.0.1 + + * Diagnostics improvements. + + * Build system improvements. + + * Code cleanups. + + +Version 1.0.0 + + * First public release. diff --git a/libxsd-frontend/README b/libxsd-frontend/README new file mode 100644 index 0000000..afc6e58 --- /dev/null +++ b/libxsd-frontend/README @@ -0,0 +1,13 @@ +libxsd-frontend is a compiler frontend for the W3C XML Schema definition +language. It includes parser, semantic graph types and traversal mechanism. + +See the NEWS file for the user-visible changes from the previous release. + +See the LICENSE file for distribution conditions. + +See the INSTALL file for prerequisites and installation instructions. + +The project page is at http://codesynthesis.com/projects/libxsd-frontend/. + +Send bug reports or any other feedback to the +libxsd-frontend-users@codesynthesis.com mailing list. diff --git a/libxsd-frontend/build/bootstrap.make b/libxsd-frontend/build/bootstrap.make new file mode 100644 index 0000000..4db3c99 --- /dev/null +++ b/libxsd-frontend/build/bootstrap.make @@ -0,0 +1,46 @@ +# file : build/bootstrap.make +# author : Boris Kolpackov +# copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +# license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +project_name := libxsd-frontend + +# First try to include the bundled bootstrap.make if it exist. If that +# fails, let make search for the external bootstrap.make. +# +build := build-0.3 + +-include $(dir $(lastword $(MAKEFILE_LIST)))../../$(build)/bootstrap.make + +ifeq ($(patsubst %build/bootstrap.make,,$(lastword $(MAKEFILE_LIST))),) +include $(build)/bootstrap.make +endif + +# Aliases +# +.PHONY: $(out_base)/ \ + $(out_base)/.test \ + $(out_base)/.clean + +ifdef %interactive% + +.PHONY: test clean + +test: $(out_base)/.test +clean: $(out_base)/.clean + +ifneq ($(filter $(.DEFAULT_GOAL),test clean),) +.DEFAULT_GOAL := +endif + +endif + +# Don't include dependency info for certain targets. +# +define include-dep +$(call -include,$1) +endef + +ifneq ($(filter $(MAKECMDGOALS),clean cleandoc disfigure),) +include-dep = +endif diff --git a/libxsd-frontend/build/cxx/configuration-dynamic.make b/libxsd-frontend/build/cxx/configuration-dynamic.make new file mode 100644 index 0000000..568ab40 --- /dev/null +++ b/libxsd-frontend/build/cxx/configuration-dynamic.make @@ -0,0 +1,14 @@ +cxx_id := gnu +cxx_optimize := n +cxx_debug := n +cxx_rpath := n +cxx_pp_extra_options := $(CPPFLAGS) +cxx_extra_options := $(CXXFLAGS) +cxx_ld_extra_options := $(LDFLAGS) +cxx_extra_libs := $(LIBS) + +r := $(shell echo $(LDFLAGS) | sed -e 's/-L *\([^ ]*\)/-L\1/g') +r := $(patsubst -L%,%,$(filter -L%,$(r))) +r := $(shell echo $(r) | sed -e 's/ /:/g') + +cxx_extra_lib_paths := $(r) diff --git a/libxsd-frontend/build/cxx/gnu/configuration-dynamic.make b/libxsd-frontend/build/cxx/gnu/configuration-dynamic.make new file mode 100644 index 0000000..f3fe64d --- /dev/null +++ b/libxsd-frontend/build/cxx/gnu/configuration-dynamic.make @@ -0,0 +1,8 @@ +ifneq ($(CXX),) +cxx_gnu := $(CXX) +else +cxx_gnu := g++ +endif + +cxx_gnu_libraries := +cxx_gnu_optimization_options := diff --git a/libxsd-frontend/build/export/libxsd-frontend/stub.make b/libxsd-frontend/build/export/libxsd-frontend/stub.make new file mode 100644 index 0000000..adae4b7 --- /dev/null +++ b/libxsd-frontend/build/export/libxsd-frontend/stub.make @@ -0,0 +1,10 @@ +# file : build/import/libxsd-frontend/stub.make +# author : Boris Kolpackov +# copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +# license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +$(call include-once,$(src_root)/xsd-frontend/makefile,$(out_root)) + +$(call export,\ + l: $(out_root)/xsd-frontend/xsd-frontend.l,\ + cpp-options: $(out_root)/xsd-frontend/xsd-frontend.l.cpp-options) diff --git a/libxsd-frontend/build/import/libboost/LICENSE b/libxsd-frontend/build/import/libboost/LICENSE new file mode 100644 index 0000000..3912109 --- /dev/null +++ b/libxsd-frontend/build/import/libboost/LICENSE @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/libxsd-frontend/build/import/libboost/configuration-dynamic.make b/libxsd-frontend/build/import/libboost/configuration-dynamic.make new file mode 100644 index 0000000..ab55882 --- /dev/null +++ b/libxsd-frontend/build/import/libboost/configuration-dynamic.make @@ -0,0 +1,8 @@ +libboost_installed := y +libboost_suffix := $(BOOST_LIB_SUFFIX) + +ifeq ($(BOOST_LINK_SYSTEM),n) +libboost_system := n +else +libboost_system := y +endif diff --git a/libxsd-frontend/build/import/libboost/configuration-rules.make b/libxsd-frontend/build/import/libboost/configuration-rules.make new file mode 100644 index 0000000..40fff9f --- /dev/null +++ b/libxsd-frontend/build/import/libboost/configuration-rules.make @@ -0,0 +1,15 @@ +# file : build/import/libboost/configuration-rules.make +# author : Boris Kolpackov +# copyright : Copyright (c) 2005-2010 Boris Kolpackov +# license : GNU GPL v2; see accompanying LICENSE file + +$(dcf_root)/import/libboost/configuration-dynamic.make: | $(dcf_root)/import/libboost/. + $(call message,,$(scf_root)/import/libboost/configure $@) + +ifndef %foreign% + +disfigure:: + $(call message,rm $(dcf_root)/import/libboost/configuration-dynamic.make,\ +rm -f $(dcf_root)/import/libboost/configuration-dynamic.make) + +endif diff --git a/libxsd-frontend/build/import/libboost/configure b/libxsd-frontend/build/import/libboost/configure new file mode 100755 index 0000000..c924a30 --- /dev/null +++ b/libxsd-frontend/build/import/libboost/configure @@ -0,0 +1,74 @@ +#! /usr/bin/env bash + +# file : build/import/libboost/configure +# author : Boris Kolpackov +# copyright : Copyright (c) 2005-2010 Boris Kolpackov +# license : GNU GPL v2; see accompanying LICENSE file + + +# $1 - out config file +# +# bld_root - build root +# project_name - project name +# + +source $bld_root/dialog.bash + + +$echo +$echo "Configuring external dependency on 'boost libraries' for '$project_name'." +$echo + +$echo +$echo "Would you like to configure dependency on the installed version" +$echo "of 'boost libraries' as opposed to the development build?" +$echo + +installed=`read_y_n y` + +if [ "$installed" = "n" ]; then + + $echo + $echo "Please enter the 'boost' root directory." + $echo + + root=`read_path --directory --exist` + + $echo + $echo "Please select the library type you would like to use:" + $echo + $echo "(1) archive" + $echo "(2) shared object" + $echo + + type=`read_option "archive shared" "shared"` +fi + +$echo +$echo "Link explicitly to the boost system library? This library" +$echo "is available since boost 1.35.0 and linking to it explicitly" +$echo "may be required by newer linkers." +$echo + +link_system=`read_y_n y` + +$echo +$echo "Please enter optional suffix that may be embedded into the" +$echo "boost library names. For example, if your library names are in" +$echo "the libboost_regex-gcc41-mt-d.so form, then enter -gcc41-mt-d" +$echo "Otherwise leave this field blank." +$echo + +suffix= +read -e -p "[]: " suffix + +echo libboost_installed := $installed >$1 +echo libboost_suffix := $suffix >>$1 +echo libboost_system := $link_system >>$1 + +if [ "$installed" = "n" ]; then + + echo libboost_root := $root >>$1 + echo libboost_type := $type >>$1 + +fi diff --git a/libxsd-frontend/build/import/libboost/filesystem/rules.make b/libxsd-frontend/build/import/libboost/filesystem/rules.make new file mode 100644 index 0000000..b5febd3 --- /dev/null +++ b/libxsd-frontend/build/import/libboost/filesystem/rules.make @@ -0,0 +1,53 @@ +# file : build/import/libboost/filesystem/rules.make +# author : Boris Kolpackov +# copyright : Copyright (c) 2005-2010 Boris Kolpackov +# license : GNU GPL v2; see accompanying LICENSE file + +#@@ Should use message everywhere. +# + +$(dcf_root)/import/libboost/%: root := $(libboost_root) + +$(dcf_root)/import/libboost/filesystem/filesystem.l: \ + | $(dcf_root)/import/libboost/filesystem/. + +ifeq ($(libboost_type),archive) + +ifeq ($(libboost_system),y) +$(dcf_root)/import/libboost/filesystem/filesystem.l: \ + $(libboost_root)/stage/lib/libboost_filesystem$(libboost_suffix).a \ + $(libboost_root)/stage/lib/libboost_system$(libboost_suffix).a +else +$(dcf_root)/import/libboost/filesystem/filesystem.l: \ + $(libboost_root)/stage/lib/libboost_filesystem$(libboost_suffix).a +endif + @echo $^ >$@ + +else + +ifeq ($(libboost_system),y) +$(dcf_root)/import/libboost/filesystem/filesystem.l: \ + $(libboost_root)/stage/lib/libboost_filesystem$(libboost_suffix).so \ + $(libboost_root)/stage/lib/libboost_system$(libboost_suffix).so +else +$(dcf_root)/import/libboost/filesystem/filesystem.l: \ + $(libboost_root)/stage/lib/libboost_filesystem$(libboost_suffix).so +endif + @echo $^ >$@ + @echo rpath:$(root)/stage/lib >>$@ + +endif + + +$(dcf_root)/import/libboost/filesystem/filesystem.l.cpp-options: \ + | $(dcf_root)/import/libboost/filesystem/. + @echo include: -I$(root) >$@ + +ifndef %foreign% + +disfigure:: + $(call message,rm $(dcf_root)/import/libboost/filesystem/filesystem.l,\ +rm -f $(dcf_root)/import/libboost/filesystem/filesystem.l) + $(call message,,rm -f $(dcf_root)/import/libboost/filesystem/filesystem.l.cpp-options) + +endif diff --git a/libxsd-frontend/build/import/libboost/filesystem/stub.make b/libxsd-frontend/build/import/libboost/filesystem/stub.make new file mode 100644 index 0000000..fb7398d --- /dev/null +++ b/libxsd-frontend/build/import/libboost/filesystem/stub.make @@ -0,0 +1,36 @@ +# file : build/import/libboost/filesystem/stub.make +# author : Boris Kolpackov +# copyright : Copyright (c) 2005-2010 Boris Kolpackov +# license : GNU GPL v2; see accompanying LICENSE file + +$(call include-once,$(scf_root)/import/libboost/configuration-rules.make,$(dcf_root)) + +libboost_installed := + +$(call -include,$(dcf_root)/import/libboost/configuration-dynamic.make) + +ifdef libboost_installed + +ifeq ($(libboost_installed),y) + +ifeq ($(libboost_system),y) +$(call export,l: -lboost_filesystem$(libboost_suffix) -lboost_system$(libboost_suffix),cpp_options: ) +else +$(call export,l: -lboost_filesystem$(libboost_suffix),cpp_options: ) +endif + +else + +$(call include-once,$(scf_root)/import/libboost/filesystem/rules.make,$(dcf_root)) + +$(call export,\ + l: $(dcf_root)/import/libboost/filesystem/filesystem.l,\ + cpp-options: $(dcf_root)/import/libboost/filesystem/filesystem.l.cpp-options) + +endif + +else + +.NOTPARALLEL: + +endif diff --git a/libxsd-frontend/build/import/libboost/version b/libxsd-frontend/build/import/libboost/version new file mode 100644 index 0000000..faef31a --- /dev/null +++ b/libxsd-frontend/build/import/libboost/version @@ -0,0 +1 @@ +0.7.0 diff --git a/libxsd-frontend/build/import/libcult/LICENSE b/libxsd-frontend/build/import/libcult/LICENSE new file mode 100644 index 0000000..3912109 --- /dev/null +++ b/libxsd-frontend/build/import/libcult/LICENSE @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/libxsd-frontend/build/import/libcult/configuration-dynamic.make b/libxsd-frontend/build/import/libcult/configuration-dynamic.make new file mode 100644 index 0000000..73c92bb --- /dev/null +++ b/libxsd-frontend/build/import/libcult/configuration-dynamic.make @@ -0,0 +1,4 @@ +libcult_installed := n +src_root := $(abspath $(src_root)/../libcult) +scf_root := $(src_root)/build +out_root := $(src_root) diff --git a/libxsd-frontend/build/import/libcult/configuration-rules.make b/libxsd-frontend/build/import/libcult/configuration-rules.make new file mode 100644 index 0000000..dc19df4 --- /dev/null +++ b/libxsd-frontend/build/import/libcult/configuration-rules.make @@ -0,0 +1,15 @@ +# file : build/import/libcult/configuration-rules.make +# author : Boris Kolpackov +# copyright : Copyright (c) 2005-2009 Boris Kolpackov +# license : GNU GPL v2; see accompanying LICENSE file + +$(dcf_root)/import/libcult/configuration-dynamic.make: | $(dcf_root)/import/libcult/. + $(call message,,$(scf_root)/import/libcult/configure $@) + +ifndef %foreign% + +disfigure:: + $(call message,rm $(dcf_root)/import/libcult/configuration-dynamic.make,\ +rm -f $(dcf_root)/import/libcult/configuration-dynamic.make) + +endif diff --git a/libxsd-frontend/build/import/libcult/configure b/libxsd-frontend/build/import/libcult/configure new file mode 100755 index 0000000..afa4c9c --- /dev/null +++ b/libxsd-frontend/build/import/libcult/configure @@ -0,0 +1,55 @@ +#! /usr/bin/env bash + +# file : build/import/libcult/configure +# author : Boris Kolpackov +# copyright : Copyright (c) 2005-2009 Boris Kolpackov +# license : GNU GPL v2; see accompanying LICENSE file + + +# $1 - out file +# +# bld_root - build root +# project_name - project name +# + +source $bld_root/dialog.bash + + +$echo +$echo "Configuring external dependency on 'libcult' for '$project_name'." +$echo + +$echo +$echo "Would you like to configure dependency on the installed " +$echo "version of 'libcult' as opposed to the development build?" +$echo + +installed=`read_y_n y` + +path= + +if [ "$installed" = "n" ]; then + +$echo +$echo "Please enter the src_root for 'libcult'." +$echo + +src_root=`read_path --directory --exist` + +$echo +$echo "Please enter the out_root for 'libcult'." +$echo + +out_root=`read_path --directory $src_root` + +fi + +echo libcult_installed := $installed >$1 + +if [ "$installed" = "n" ]; then + +echo src_root := $src_root >>$1 +echo scf_root := \$\(src_root\)/build >>$1 +echo out_root := $out_root >>$1 + +fi diff --git a/libxsd-frontend/build/import/libcult/stub.make b/libxsd-frontend/build/import/libcult/stub.make new file mode 100644 index 0000000..f5f7691 --- /dev/null +++ b/libxsd-frontend/build/import/libcult/stub.make @@ -0,0 +1,30 @@ +# file : build/import/libcult/stub.make +# author : Boris Kolpackov +# copyright : Copyright (c) 2005-2009 Boris Kolpackov +# license : GNU GPL v2; see accompanying LICENSE file + +$(call include-once,$(scf_root)/import/libcult/configuration-rules.make,$(dcf_root)) + +libcult_installed := + +$(call -include,$(dcf_root)/import/libcult/configuration-dynamic.make) + +ifdef libcult_installed + +ifeq ($(libcult_installed),y) + +$(call export,l: -lcult,cpp-options: ) + +else + +# Include export stub. +# +$(call include,$(scf_root)/export/libcult/stub.make) + +endif + +else + +.NOTPARALLEL: + +endif diff --git a/libxsd-frontend/build/import/libfrontend-elements/LICENSE b/libxsd-frontend/build/import/libfrontend-elements/LICENSE new file mode 100644 index 0000000..3912109 --- /dev/null +++ b/libxsd-frontend/build/import/libfrontend-elements/LICENSE @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/libxsd-frontend/build/import/libfrontend-elements/configuration-dynamic.make b/libxsd-frontend/build/import/libfrontend-elements/configuration-dynamic.make new file mode 100644 index 0000000..70d0da6 --- /dev/null +++ b/libxsd-frontend/build/import/libfrontend-elements/configuration-dynamic.make @@ -0,0 +1,4 @@ +libfrontend_elements_installed := n +src_root := $(abspath $(src_root)/../libfrontend-elements) +scf_root := $(src_root)/build +out_root := $(src_root) diff --git a/libxsd-frontend/build/import/libfrontend-elements/configuration-rules.make b/libxsd-frontend/build/import/libfrontend-elements/configuration-rules.make new file mode 100644 index 0000000..a7db697 --- /dev/null +++ b/libxsd-frontend/build/import/libfrontend-elements/configuration-rules.make @@ -0,0 +1,15 @@ +# file : build/import/libfrontend-elements/configuration-rules.make +# author : Boris Kolpackov +# copyright : Copyright (c) 2005-2009 Boris Kolpackov +# license : GNU GPL v2; see accompanying LICENSE file + +$(dcf_root)/import/libfrontend-elements/configuration-dynamic.make: | $(dcf_root)/import/libfrontend-elements/. + $(call message,,$(scf_root)/import/libfrontend-elements/configure $@) + +ifndef %foreign% + +disfigure:: + $(call message,rm $(dcf_root)/import/libfrontend-elements/configuration-dynamic.make,\ +rm -f $(dcf_root)/import/libfrontend-elements/configuration-dynamic.make) + +endif diff --git a/libxsd-frontend/build/import/libfrontend-elements/configure b/libxsd-frontend/build/import/libfrontend-elements/configure new file mode 100755 index 0000000..d02b4f7 --- /dev/null +++ b/libxsd-frontend/build/import/libfrontend-elements/configure @@ -0,0 +1,55 @@ +#! /usr/bin/env bash + +# file : build/import/libfrontend-elements/configure +# author : Boris Kolpackov +# copyright : Copyright (c) 2005-2009 Boris Kolpackov +# license : GNU GPL v2; see accompanying LICENSE file + + +# $1 - out file +# +# bld_root - build root +# project_name - project name +# + +source $bld_root/dialog.bash + + +$echo +$echo "Configuring external dependency on 'libfrontend-elements' for '$project_name'." +$echo + +$echo +$echo "Would you like to configure dependency on the installed version" +$echo "of 'libfrontend-elements' as opposed to the development build?" +$echo + +installed=`read_y_n y` + +path= + +if [ "$installed" = "n" ]; then + +$echo +$echo "Please enter the src_root for 'libfrontend-elements'." +$echo + +src_root=`read_path --directory --exist` + +$echo +$echo "Please enter the out_root for 'libfrontend-elements'." +$echo + +out_root=`read_path --directory $src_root` + +fi + +echo libfrontend_elements_installed := $installed >$1 + +if [ "$installed" = "n" ]; then + +echo src_root := $src_root >>$1 +echo scf_root := \$\(src_root\)/build >>$1 +echo out_root := $out_root >>$1 + +fi diff --git a/libxsd-frontend/build/import/libfrontend-elements/stub.make b/libxsd-frontend/build/import/libfrontend-elements/stub.make new file mode 100644 index 0000000..d701305 --- /dev/null +++ b/libxsd-frontend/build/import/libfrontend-elements/stub.make @@ -0,0 +1,30 @@ +# file : build/import/libfrontend-elements/stub.make +# author : Boris Kolpackov +# copyright : Copyright (c) 2005-2009 Boris Kolpackov +# license : GNU GPL v2; see accompanying LICENSE file + +$(call include-once,$(scf_root)/import/libfrontend-elements/configuration-rules.make,$(dcf_root)) + +libfrontend_elements_installed := + +$(call -include,$(dcf_root)/import/libfrontend-elements/configuration-dynamic.make) + +ifdef libfrontend_elements_installed + +ifeq ($(libfrontend_elements_installed),y) + +$(call export,l: -lfrontend-elements -lcult,cpp_options: ) + +else + +# Include export stub. +# +$(call include,$(scf_root)/export/libfrontend-elements/stub.make) + +endif + +else + +.NOTPARALLEL: + +endif diff --git a/libxsd-frontend/build/import/libxerces-c/LICENSE b/libxsd-frontend/build/import/libxerces-c/LICENSE new file mode 100644 index 0000000..3912109 --- /dev/null +++ b/libxsd-frontend/build/import/libxerces-c/LICENSE @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/libxsd-frontend/build/import/libxerces-c/configuration-dynamic.make b/libxsd-frontend/build/import/libxerces-c/configuration-dynamic.make new file mode 100644 index 0000000..91f61b2 --- /dev/null +++ b/libxsd-frontend/build/import/libxerces-c/configuration-dynamic.make @@ -0,0 +1 @@ +libxerces_c_installed := y diff --git a/libxsd-frontend/build/import/libxerces-c/configuration-rules.make b/libxsd-frontend/build/import/libxerces-c/configuration-rules.make new file mode 100644 index 0000000..fdb2263 --- /dev/null +++ b/libxsd-frontend/build/import/libxerces-c/configuration-rules.make @@ -0,0 +1,15 @@ +# file : build/import/libxerces-c/configuration-rules.make +# author : Boris Kolpackov +# copyright : Copyright (c) 2005-2009 Boris Kolpackov +# license : GNU GPL v2; see accompanying LICENSE file + +$(dcf_root)/import/libxerces-c/configuration-dynamic.make: | $(dcf_root)/import/libxerces-c/. + $(call message,,$(scf_root)/import/libxerces-c/configure $@) + +ifndef %foreign% + +disfigure:: + $(call message,rm $(dcf_root)/import/libxerces-c/configuration-dynamic.make,\ +rm -f $(dcf_root)/import/libxerces-c/configuration-dynamic.make) + +endif diff --git a/libxsd-frontend/build/import/libxerces-c/configure b/libxsd-frontend/build/import/libxerces-c/configure new file mode 100755 index 0000000..26e56a7 --- /dev/null +++ b/libxsd-frontend/build/import/libxerces-c/configure @@ -0,0 +1,73 @@ +#! /usr/bin/env bash + +# file : build/import/libxerces-c/configure +# author : Boris Kolpackov +# copyright : Copyright (c) 2005-2009 Boris Kolpackov +# license : GNU GPL v2; see accompanying LICENSE file + + +# $1 - out config file +# +# bld_root - build root +# project_name - project name +# + +source $bld_root/dialog.bash + + +$echo +$echo "Configuring external dependency on 'libxerces-c' for '$project_name'." +$echo + +$echo +$echo "Would you like to configure dependency on the installed version" +$echo "of 'libxerces-c' as opposed to the development build?" +$echo + +installed=`read_y_n y` + +path= +type= + +if [ "$installed" = "n" ]; then + + version= + + while [ -z "$version" ]; do + + $echo + $echo "Please enter the 'libxerces-c' root directory." + $echo + + root=`read_path --directory --exist` + + version=`sed -e 's/^VER=\([^_]*\)_\([^_]*\)_\([^_]*\)[ ]*$/\1.\2.\3/' \ +-e t -e d $root/version.incl 2>/dev/null` + + if [ $? != 0 -o -z "$version" ]; then + + version= + echo "Unable to read version information from $root/version.incl" + fi + done + + $echo + $echo "Please select the library type you would like to use:" + $echo + $echo "(1) archive" + $echo "(2) shared object" + $echo + + type=`read_option "archive shared" "shared"` + +fi + +echo libxerces_c_installed := $installed >$1 + +if [ "$installed" = "n" ]; then + + echo libxerces_c_root := $root >>$1 + echo libxerces_c_type := $type >>$1 + echo libxerces_c_version := $version >>$1 + +fi diff --git a/libxsd-frontend/build/import/libxerces-c/rules.make b/libxsd-frontend/build/import/libxerces-c/rules.make new file mode 100644 index 0000000..7cdca8c --- /dev/null +++ b/libxsd-frontend/build/import/libxerces-c/rules.make @@ -0,0 +1,52 @@ +# file : build/import/libxerces-c/rules.make +# author : Boris Kolpackov +# copyright : Copyright (c) 2005-2009 Boris Kolpackov +# license : GNU GPL v2; see accompanying LICENSE file + +$(dcf_root)/import/libxerces-c/%: root := $(libxerces_c_root) + +ifneq ($(filter 3.%,$(libxerces_c_version)),) + +# 3.x.y +# +ifeq ($(libxerces_c_type),archive) + +$(dcf_root)/import/libxerces-c/xerces-c.l: $(libxerces_c_root)/src/.libs/libxerces-c.a + @echo $< >$@ +else + +$(dcf_root)/import/libxerces-c/xerces-c.l: $(libxerces_c_root)/src/.libs/libxerces-c.so + @echo $< >$@ + @echo rpath:$(root)/src/.libs >>$@ +endif + +$(dcf_root)/import/libxerces-c/xerces-c.l.cpp-options: + @echo include: -I$(root)/src >$@ +else + +# 2.x.y +# +ifeq ($(libxerces_c_type),archive) + +$(dcf_root)/import/libxerces-c/xerces-c.l: $(libxerces_c_root)/lib/libxerces-c.a + @echo $< >$@ +else + +$(dcf_root)/import/libxerces-c/xerces-c.l: $(libxerces_c_root)/lib/libxerces-c.so + @echo $< >$@ + @echo rpath:$(root)/lib >>$@ +endif + +$(dcf_root)/import/libxerces-c/xerces-c.l.cpp-options: + @echo include: -I$(root)/include >$@ +endif + + +ifndef %foreign% + +disfigure:: + $(call message,rm $(dcf_root)/import/libxerces-c/xerces-c.l,\ +rm -f $(dcf_root)/import/libxerces-c/xerces-c.l) + $(call message,,rm -f $(dcf_root)/import/libxerces-c/xerces-c.l.cpp-options) + +endif diff --git a/libxsd-frontend/build/import/libxerces-c/stub.make b/libxsd-frontend/build/import/libxerces-c/stub.make new file mode 100644 index 0000000..d4de5ec --- /dev/null +++ b/libxsd-frontend/build/import/libxerces-c/stub.make @@ -0,0 +1,32 @@ +# file : build/import/libxerces-c/stub.make +# author : Boris Kolpackov +# copyright : Copyright (c) 2005-2009 Boris Kolpackov +# license : GNU GPL v2; see accompanying LICENSE file + +$(call include-once,$(scf_root)/import/libxerces-c/configuration-rules.make,$(dcf_root)) + +libxerces_c_installed := + +$(call -include,$(dcf_root)/import/libxerces-c/configuration-dynamic.make) + +ifdef libxerces_c_installed + +ifeq ($(libxerces_c_installed),y) + +$(call export,l: -lxerces-c,cpp-options: ) + +else + +$(call include-once,$(scf_root)/import/libxerces-c/rules.make,$(dcf_root)) + +$(call export,\ + l: $(dcf_root)/import/libxerces-c/xerces-c.l,\ + cpp-options: $(dcf_root)/import/libxerces-c/xerces-c.l.cpp-options) + +endif + +else + +.NOTPARALLEL: + +endif diff --git a/libxsd-frontend/build/import/libxerces-c/version b/libxsd-frontend/build/import/libxerces-c/version new file mode 100644 index 0000000..a918a2a --- /dev/null +++ b/libxsd-frontend/build/import/libxerces-c/version @@ -0,0 +1 @@ +0.6.0 diff --git a/libxsd-frontend/build/import/libxsd-frontend/LICENSE b/libxsd-frontend/build/import/libxsd-frontend/LICENSE new file mode 120000 index 0000000..5853aae --- /dev/null +++ b/libxsd-frontend/build/import/libxsd-frontend/LICENSE @@ -0,0 +1 @@ +../../../LICENSE \ No newline at end of file diff --git a/libxsd-frontend/build/import/libxsd-frontend/configuration-rules.make b/libxsd-frontend/build/import/libxsd-frontend/configuration-rules.make new file mode 100644 index 0000000..29e8083 --- /dev/null +++ b/libxsd-frontend/build/import/libxsd-frontend/configuration-rules.make @@ -0,0 +1,15 @@ +# file : build/import/libxsd-frontend/configuration-rules.make +# author : Boris Kolpackov +# copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +# license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +$(dcf_root)/import/libxsd-frontend/configuration-dynamic.make: | $(dcf_root)/import/libxsd-frontend/. + $(call message,,$(scf_root)/import/libxsd-frontend/configure $@) + +ifndef %foreign% + +disfigure:: + $(call message,rm $(dcf_root)/import/libxsd-frontend/configuration-dynamic.make,\ +rm -f $(dcf_root)/import/libxsd-frontend/configuration-dynamic.make) + +endif diff --git a/libxsd-frontend/build/import/libxsd-frontend/configure b/libxsd-frontend/build/import/libxsd-frontend/configure new file mode 100755 index 0000000..cc6881c --- /dev/null +++ b/libxsd-frontend/build/import/libxsd-frontend/configure @@ -0,0 +1,55 @@ +#! /usr/bin/env bash + +# file : build/import/libxsd-frontend/configure +# author : Boris Kolpackov +# copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +# license : GNU GPL v2 + exceptions; see accompanying LICENSE file + + +# $1 - out file +# +# bld_root - build root +# project_name - project name +# + +source $bld_root/dialog.bash + + +$echo +$echo "Configuring external dependency on 'libxsd-frontend' for '$project_name'." +$echo + +$echo +$echo "Would you like to configure dependency on the installed " +$echo "version of 'libxsd-frontend' as opposed to the development build?" +$echo + +installed=`read_y_n y` + +path= + +if [ "$installed" = "n" ]; then + +$echo +$echo "Please enter the src_root for 'libxsd-frontend'." +$echo + +src_root=`read_path --directory --exist` + +$echo +$echo "Please enter the out_root for 'libxsd-frontend'." +$echo + +out_root=`read_path --directory $src_root` + +fi + +echo libxsd_frontend_installed := $installed >$1 + +if [ "$installed" = "n" ]; then + +echo src_root := $src_root >>$1 +echo scf_root := \$\(src_root\)/build >>$1 +echo out_root := $out_root >>$1 + +fi diff --git a/libxsd-frontend/build/import/libxsd-frontend/stub.make b/libxsd-frontend/build/import/libxsd-frontend/stub.make new file mode 100644 index 0000000..3721928 --- /dev/null +++ b/libxsd-frontend/build/import/libxsd-frontend/stub.make @@ -0,0 +1,30 @@ +# file : build/import/libxsd-frontend/stub.make +# author : Boris Kolpackov +# copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +# license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +$(call include-once,$(scf_root)/import/libxsd-frontend/configuration-rules.make,$(dcf_root)) + +libxsd_frontend_installed := + +$(call -include,$(dcf_root)/import/libxsd-frontend/configuration-dynamic.make) + +ifdef libxsd_frontend_installed + +ifeq ($(libxsd_frontend_installed),y) + +$(call export,l: -lxsd-frontend -lfrontend-elements -lcult -lboost_filesystem -lxerces-c,cpp_options: ) + +else + +# Include export stub. +# +$(call include,$(scf_root)/export/libxsd-frontend/stub.make) + +endif + +else + +.NOTPARALLEL: + +endif diff --git a/libxsd-frontend/build/ld/configuration-lib-dynamic.make b/libxsd-frontend/build/ld/configuration-lib-dynamic.make new file mode 100644 index 0000000..74c8885 --- /dev/null +++ b/libxsd-frontend/build/ld/configuration-lib-dynamic.make @@ -0,0 +1,13 @@ +ld_lib_type := archive + +ifneq ($(AR),) +ld_lib_ar := $(AR) +else +ld_lib_ar := ar +endif + +ifneq ($(RANLIB),) +ld_lib_ranlib := $(RANLIB) +else +ld_lib_ranlib := ranlib +endif diff --git a/libxsd-frontend/makefile b/libxsd-frontend/makefile new file mode 100644 index 0000000..de97507 --- /dev/null +++ b/libxsd-frontend/makefile @@ -0,0 +1,17 @@ +# file : makefile +# author : Boris Kolpackov +# copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +# license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +include $(dir $(lastword $(MAKEFILE_LIST)))build/bootstrap.make + +default := $(out_base)/ +test := $(out_base)/.test +clean := $(out_base)/.clean + +$(default): $(out_base)/xsd-frontend/ $(out_base)/tests/ +$(test): $(out_base)/tests/.test +$(clean): $(out_base)/xsd-frontend/.clean $(out_base)/tests/.clean + +$(call import,$(src_base)/xsd-frontend/makefile) +$(call import,$(src_base)/tests/makefile) diff --git a/libxsd-frontend/tests/dump/driver.cxx b/libxsd-frontend/tests/dump/driver.cxx new file mode 100644 index 0000000..5217ebf --- /dev/null +++ b/libxsd-frontend/tests/dump/driver.cxx @@ -0,0 +1,734 @@ +// file : tests/dump/driver.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2006-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include + +#include +#include +#include + +#include +#include + +#include + +using namespace Cult::Types; +using namespace XSDFrontend; + +using std::wcerr; +using std::wcout; +using std::endl; + +UnsignedLong indent = 0; + +std::wostream& +ind (std::wostream& os) +{ + for (UnsignedLong n (0); n < indent; ++n) + os << L" "; + + return os; +} + +namespace +{ + typedef Cult::Types::WideString String; + + // Nameable which is named in the namespace scope. + // + String + ref_name (SemanticGraph::Nameable& n) + { + String const& scope (n.scope ().name ()); + + return scope + (scope.empty () ? L"" : L"#") + n.name (); + } + + struct List: Traversal::List + { + virtual Void + traverse (Type& l) + { + if (l.annotated_p ()) + wcout << ind << "<" << l.annotation ().documentation () << ">" + << endl; + + wcout << ind << "list " << + (l.named_p () ? l.name () : String ("")); + + SemanticGraph::Type& t (l.argumented ().type ()); + + if (t.named_p ()) + wcout << " " << ref_name (t) << endl; + else + { + wcout << endl + << ind << "{" << endl; + indent++; + + edge_traverser ().dispatch (l.argumented ()); + + indent--; + wcout << ind << "}" << endl; + } + } + }; + + struct Union: Traversal::Union + { + virtual Void + traverse (Type& u) + { + if (u.annotated_p ()) + wcout << ind << "<" << u.annotation ().documentation () << ">" + << endl; + + wcout << ind << "union " << + (u.named_p () ? u.name () : String ("")) << " "; + + for (Type::ArgumentedIterator i (u.argumented_begin ()); + i != u.argumented_end (); ++i) + { + SemanticGraph::Type& t (i->type ()); + + if (t.named_p ()) + wcout << ref_name (t) << " "; + else + { + wcout << endl + << ind << "{" << endl; + indent++; + + edge_traverser ().dispatch (*i); + + indent--; + wcout << ind << "}" << endl; + } + } + + wcout << endl; + } + }; + + struct Enumerator: Traversal::Enumerator + { + virtual Void + traverse (Type& e) + { + if (e.annotated_p ()) + wcout << ind << "<" << e.annotation ().documentation () << ">" + << endl; + + wcout << ind << "enumerator " << e.name () << endl; + } + }; + + struct Enumeration: Traversal::Enumeration + { + virtual Void + traverse (Type& e) + { + if (e.annotated_p ()) + wcout << ind << "<" << e.annotation ().documentation () << ">" + << endl; + + wcout << ind << "enumeration " << + (e.named_p () ? e.name () : String ("")) << ": " << + ref_name (e.inherits ().base ()) << endl + << ind << "{" << endl; + + indent++; + Traversal::Enumeration::traverse (e); + indent--; + + wcout << ind << "}" << endl; + } + }; + + struct ContainsParticle: Traversal::ContainsParticle + { + virtual Void + traverse (Type& cp) + { + wcout << ind << "[" << cp.min () << ", "; + + if (cp.max () == 0) + wcout << "unbounded] "; + else + wcout << cp.max () << "] "; + + Traversal::ContainsParticle::traverse (cp); + } + }; + + struct ContainsCompositor: Traversal::ContainsCompositor + { + virtual Void + traverse (Type& cc) + { + wcout << ind << "[" << cc.min () << ", "; + + if (cc.max () == 0) + wcout << "unbounded] "; + else + wcout << cc.max () << "] "; + + Traversal::ContainsCompositor::traverse (cc); + } + }; + + struct Compositor: Traversal::All, + Traversal::Choice, + Traversal::Sequence + { + virtual Void + traverse (SemanticGraph::All& a) + { + wcout << "all" << endl + << ind << "{" << endl; + + indent++; + + Traversal::All::traverse (a); + + indent--; + + wcout << ind << "}" << endl; + } + + virtual Void + traverse (SemanticGraph::Choice& c) + { + wcout << "choice" << endl + << ind << "{" << endl; + + indent++; + + Traversal::Choice::traverse (c); + + indent--; + + wcout << ind << "}" << endl; + } + + virtual Void + traverse (SemanticGraph::Sequence& s) + { + wcout << "sequence" << endl + << ind << "{" << endl; + + indent++; + + Traversal::Sequence::traverse (s); + + indent--; + + wcout << ind << "}" << endl; + } + }; + + struct Attribute: Traversal::Attribute + { + virtual Void + traverse (Type& a) + { + if (a.annotated_p ()) + wcout << ind << "<" << a.annotation ().documentation () << ">" + << endl; + + wcout << ind << (a.optional_p () ? "optional" : "required") + << " attribute " << a.name (); + + if (a.fixed_p ()) + wcout << "==" << a.value (); + else if (a.default_p ()) + wcout << "=" << a.value (); + + SemanticGraph::Type& t (a.type ()); + + if (t.named_p ()) + wcout << " " << ref_name (t) << endl; + else + { + wcout << endl + << ind << "{" << endl; + indent++; + + belongs (a); + + indent--; + wcout << ind << "}" << endl; + } + } + }; + + struct AnyAttribute: Traversal::AnyAttribute + { + virtual Void + traverse (Type& a) + { + if (a.annotated_p ()) + wcout << ind << "<" << a.annotation ().documentation () << ">" + << endl; + + wcout << ind << "any-attribute '" << a.name () << "'" << endl; + } + }; + + struct Element: Traversal::Element + { + virtual Void + traverse (Type& e) + { + wcout << "element " << e.name (); + + if (e.fixed_p ()) + wcout << "==" << e.value (); + else if (e.default_p ()) + wcout << "=" << e.value (); + + SemanticGraph::Type& t (e.type ()); + + if (t.named_p ()) + wcout << " " << ref_name (t) << endl; + else + { + wcout << endl + << ind << "{" << endl; + indent++; + + belongs (e); + + indent--; + wcout << ind << "}" << endl; + } + } + }; + + struct ElementFlat: Traversal::Element + { + virtual Void + traverse (Type& e) + { + if (e.annotated_p ()) + wcout << ind << "<" << e.annotation ().documentation () << ">" + << endl; + + wcout << ind << "element " << e.name (); + + if (e.fixed_p ()) + wcout << "==" << e.value (); + else if (e.default_p ()) + wcout << "=" << e.value (); + + wcout << endl; + } + }; + + struct Any: Traversal::Any + { + virtual Void + traverse (Type& a) + { + wcout << "any '" << a.name () << "'" << endl; + } + }; + + struct AnyFlat: Traversal::Any + { + virtual Void + traverse (Type& a) + { + if (a.annotated_p ()) + wcout << ind << "<" << a.annotation ().documentation () << ">" + << endl; + + wcout << ind << "any '" << a.name () << "'" << endl; + } + }; + + struct Complex: Traversal::Complex + { + virtual Void + traverse (Type& c) + { + // Anonymous type definition can recursively refer to itself. + // + if (c.context ().count ("seen")) + { + wcout << ind << "complex " << endl; + return; + } + + c.context ().set ("seen", true); + + if (c.annotated_p ()) + wcout << ind << "<" << c.annotation ().documentation () << ">" + << endl; + + wcout << ind << "complex " << + (c.named_p () ? c.name () : String ("")); + + if (c.inherits_p ()) + wcout << ": " << ref_name (c.inherits ().base ()); + + wcout << endl + << ind << "{" << endl; + indent++; + + Traversal::Complex::traverse (c); + + indent--; + wcout << ind << "}" << endl; + + c.context ().remove ("seen"); + } + }; + + struct GlobalAttribute: Traversal::Attribute + { + virtual Void + traverse (Type& a) + { + if (a.annotated_p ()) + wcout << ind << "<" << a.annotation ().documentation () << ">" + << endl; + + wcout << ind << "attribute " << a.name (); + + if (a.fixed_p ()) + wcout << "==" << a.value (); + else if (a.default_p ()) + wcout << "=" << a.value (); + + SemanticGraph::Type& t (a.type ()); + + if (t.named_p ()) + wcout << " " << ref_name (t) << endl; + else + { + wcout << endl + << ind << "{" << endl; + indent++; + + belongs (a); + + indent--; + wcout << ind << "}" << endl; + } + } + }; + + struct GlobalElement: Traversal::Element + { + virtual Void + traverse (Type& e) + { + if (e.annotated_p ()) + wcout << ind << "<" << e.annotation ().documentation () << ">" + << endl; + + wcout << ind << "element " << e.name (); + + if (e.fixed_p ()) + wcout << "==" << e.value (); + else if (e.default_p ()) + wcout << "=" << e.value (); + + SemanticGraph::Type& t (e.type ()); + + if (t.named_p ()) + wcout << " " << ref_name (t) << endl; + else + { + wcout << endl + << ind << "{" << endl; + indent++; + + belongs (e); + + indent--; + wcout << ind << "}" << endl; + } + } + }; + + struct Namespace: Traversal::Namespace + { + virtual Void + traverse (Type& n) + { + wcout << ind << "namespace " << n.name () << endl + << ind << "{" << endl; + indent++; + Traversal::Namespace::traverse (n); + indent--; + wcout << ind << "}" << endl; + } + }; + + // Go into implied/included/imported schemas while making sure + // we don't recurse forever. + // + struct Uses: Traversal::Imports, + Traversal::Includes, + Traversal::Sources + //Traversal::Implies @@ Need a --with-implies option + { + virtual Void + traverse (SemanticGraph::Imports& i) + { + if (traverse_uses (i, "imports")) + Traversal::Imports::traverse (i); + } + + virtual Void + traverse (SemanticGraph::Includes& i) + { + if (traverse_uses (i, "includes")) + Traversal::Includes::traverse (i); + } + + virtual Void + traverse (SemanticGraph::Sources& s) + { + if (traverse_uses (s, "sources")) + Traversal::Sources::traverse (s); + } + + /* + virtual Void + traverse (SemanticGraph::Implies& i) + { + if (traverse_uses (i, "implies")) + Traversal::Implies::traverse (i); + } + */ + + Boolean + traverse_uses (SemanticGraph::Uses& u, String const& type) + { + SemanticGraph::Schema& s (u.schema ()); + + if (s.context ().count ("seen")) + { + wcout << ind << "recursively " << type << " " << u.path () << endl; + return false; + } + + s.context ().set ("seen", true); + + if (s.annotated_p ()) + wcout << ind << "<" << s.annotation ().documentation () << ">" << endl; + + wcout << ind << type << " " << u.path () << endl; + + return true; + } + }; + + struct Schema: Traversal::Schema + { + virtual Void + traverse (Type& s) + { + wcout << ind << "{" << endl; + indent++; + Traversal::Schema::traverse (s); + indent--; + wcout << ind << "}" << endl; + } + }; +} + +struct AnonymousNameTranslator: Transformations::AnonymousNameTranslator +{ + virtual WideString + translate (WideString const& /*file*/, + WideString const& ns, + WideString const& name, + WideString const& xpath) + { + wcout << "anonymous: " << ns << " " << name << " " << xpath << endl; + return name; + } +}; + + +Int +main (Int argc, Char* argv[]) +{ + try + { + if (argc < 2) + { + wcerr << argv[0] << ": error: no input file." << endl; + return 1; + } + + // Parse options. + // + Int i (1); + Boolean anon (false); + Boolean enum_synth (false); + + for (; i < argc; ++i) + { + if (argv[i] == NarrowString ("--anonymous")) + anon = true; + else if (argv[i] == NarrowString ("--enum-synthesis")) + enum_synth = true; + else + break; + } + + // Parse schema. + // + SemanticGraph::Path path (argv[i], boost::filesystem::native); + + Parser parser (true, false, true); + Evptr tu (parser.parse (path)); + + // + // + if (anon) + { + try + { + AnonymousNameTranslator transl; + Transformations::Anonymous transf (transl); + transf.transform (*tu, path, true); + } + catch (Transformations::Anonymous::Failed const&) + { + // Diagnostics has already been issued. + // + return 1; + } + } + + // + // + if (enum_synth) + { + Transformations::EnumSynthesis transf; + transf.transform (*tu, path); + } + + // + // + Schema schema; + Uses uses; + + schema >> uses >> schema; + + Traversal::Names schema_names; + Namespace ns; + Traversal::Names ns_names; + + schema >> schema_names >> ns >> ns_names; + + // + // + List list; + Union union_; + Complex complex; + Enumeration enumeration; + GlobalElement global_element; + GlobalAttribute global_attribute; + + Traversal::Names complex_names; + Traversal::Names enumeration_names; + ContainsCompositor contains_compositor; + + ns_names >> list; + ns_names >> union_; + ns_names >> complex; + ns_names >> enumeration; + ns_names >> global_attribute; + ns_names >> global_element; + + complex >> complex_names; + complex >> contains_compositor; + + enumeration >> enumeration_names; + + // + // + Compositor compositor; + ContainsParticle contains_particle; + + contains_compositor >> compositor; + compositor >> contains_particle >> compositor; + + // + // + Any any; + AnyFlat any_flat; + Element element; + ElementFlat element_flat; + Attribute attribute; + AnyAttribute any_attribute; + Traversal::Belongs belongs; + + element >> belongs; + attribute >> belongs; + + global_element >> belongs; + global_attribute >> belongs; + + complex_names >> attribute; + complex_names >> any_attribute; + complex_names >> any_flat; + complex_names >> element_flat; + + contains_particle >> any; + contains_particle >> element; + + belongs >> list; + belongs >> union_; + belongs >> complex; + belongs >> enumeration; + + // + // + Traversal::Argumented argumented; + list >> argumented; + union_ >> argumented; + + argumented >> list; + argumented >> union_; + argumented >> complex; + argumented >> enumeration; + + // + // + Enumerator enumerator; + enumeration_names >> enumerator; + + // + // + if (tu->annotated_p ()) + wcout << ind << "<" << tu->annotation ().documentation () << ">" + << endl; + + wcout << ind << "primary" << endl; + tu->context ().set ("seen", true); + schema.dispatch (*tu); + + return 0; + } + catch (InvalidSchema const&) + { + // Diagnostic has already been issued. + } + catch (SemanticGraph::InvalidPath const&) + { + wcerr << argv[0] << ": error: '" << argv[1] << "' is not a valid " + << "filesystem path" << endl; + } + + return 1; +} diff --git a/libxsd-frontend/tests/dump/makefile b/libxsd-frontend/tests/dump/makefile new file mode 100644 index 0000000..c51e72e --- /dev/null +++ b/libxsd-frontend/tests/dump/makefile @@ -0,0 +1,56 @@ +# file : tests/dump/makefile +# author : Boris Kolpackov +# copyright : Copyright (c) 2006-2010 Code Synthesis Tools CC +# license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +include $(dir $(lastword $(MAKEFILE_LIST)))../../build/bootstrap.make + +cxx_tun := driver.cxx +cxx_obj := $(addprefix $(out_base)/,$(cxx_tun:.cxx=.o)) +cxx_od := $(cxx_obj:.o=.o.d) + +xsd-fe.l := $(out_root)/xsd-frontend/xsd-frontend.l +xsd-fe.l.cpp-options := $(out_root)/xsd-frontend/xsd-frontend.l.cpp-options + +driver := $(out_base)/driver +clean := $(out_base)/.clean + +# Build. +# +$(driver): $(cxx_obj) $(xsd-fe.l) + +$(cxx_obj) $(cxx_od): $(xsd-fe.l.cpp-options) + +$(call include-dep,$(cxx_od)) + +# Convenience alias for default target. +# +$(out_base)/: $(driver) + +# Clean. +# +$(clean): $(driver).o.clean \ + $(addsuffix .cxx.clean,$(cxx_obj)) \ + $(addsuffix .cxx.clean,$(cxx_od)) + +# Generated .gitignore. +# +ifeq ($(out_base),$(src_base)) +$(driver): | $(out_base)/.gitignore + +$(out_base)/.gitignore: files := driver +$(clean): $(out_base)/.gitignore.clean + +$(call include,$(bld_root)/git/gitignore.make) +endif + +# How to. +# +$(call include,$(bld_root)/cxx/o-e.make) +$(call include,$(bld_root)/cxx/cxx-o.make) +$(call include,$(bld_root)/cxx/cxx-d.make) + + +# Dependencies. +# +$(call import,$(src_root)/xsd-frontend/makefile) diff --git a/libxsd-frontend/tests/makefile b/libxsd-frontend/tests/makefile new file mode 100644 index 0000000..6b794d6 --- /dev/null +++ b/libxsd-frontend/tests/makefile @@ -0,0 +1,17 @@ +# file : tests/makefile +# author : Boris Kolpackov +# copyright : Copyright (c) 2006-2010 Code Synthesis Tools CC +# license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +include $(dir $(lastword $(MAKEFILE_LIST)))../build/bootstrap.make + +default := $(out_base)/ +test := $(out_base)/.test +clean := $(out_base)/.clean + +$(default): $(out_base)/dump/ $(out_base)/schema/ +$(test): $(out_base)/schema/.test +$(clean): $(out_base)/dump/.clean $(out_base)/schema/.clean + +$(call import,$(src_base)/dump/makefile) +$(call import,$(src_base)/schema/makefile) diff --git a/libxsd-frontend/tests/schema/annotation/makefile b/libxsd-frontend/tests/schema/annotation/makefile new file mode 100644 index 0000000..97f578b --- /dev/null +++ b/libxsd-frontend/tests/schema/annotation/makefile @@ -0,0 +1,35 @@ +# file : tests/schema/annotation/makefile +# author : Boris Kolpackov +# copyright : Copyright (c) 2006-2010 Code Synthesis Tools CC +# license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +include $(dir $(lastword $(MAKEFILE_LIST)))../../../build/bootstrap.make + +tests := 000 001 + +driver := $(out_root)/tests/dump/driver +test := $(out_base)/.test +clean := $(out_base)/.clean + +# Convenience alias for default target. +# +$(out_base)/: $(driver) + +# Test. +# +test_targets := $(addprefix $(out_base)/.test-,$(tests)) + +$(test): $(test_targets) +$(test_targets): driver := $(driver) + +.PHONY: $(out_base)/.test-% +$(out_base)/.test-%: $(driver) $(src_base)/test-%.xsd $(src_base)/test-%.std + $(call message,test $(out_base)/$*,$(driver) $(src_base)/test-$*.xsd | diff -u $(src_base)/test-$*.std -) + +# Clean. +# +$(clean): + +# Dependencies. +# +$(call import,$(src_root)/tests/dump/makefile) diff --git a/libxsd-frontend/tests/schema/annotation/test-000.std b/libxsd-frontend/tests/schema/annotation/test-000.std new file mode 100644 index 0000000..15f3e89 --- /dev/null +++ b/libxsd-frontend/tests/schema/annotation/test-000.std @@ -0,0 +1,67 @@ + +primary +{ + namespace test + { + + list list http://www.w3.org/2001/XMLSchema#string + + union union http://www.w3.org/2001/XMLSchema#int http://www.w3.org/2001/XMLSchema#string + + enumeration enum: http://www.w3.org/2001/XMLSchema#string + { + + enumerator male + + enumerator female + } + + complex type + { + + element efoo + + element ebar + + element ebaz + + any 'any #0' + + optional attribute afoo http://www.w3.org/2001/XMLSchema#string + + optional attribute abar + { + + list http://www.w3.org/2001/XMLSchema#string + } + + optional attribute abaz http://www.w3.org/2001/XMLSchema#string + + any-attribute 'any-attribute #0' + [1, 1] sequence + { + [1, 1] element efoo http://www.w3.org/2001/XMLSchema#string + [1, 1] element ebar + { + complex + { + + element efoo + + optional attribute afoo http://www.w3.org/2001/XMLSchema#string + [1, 1] sequence + { + [1, 1] element efoo http://www.w3.org/2001/XMLSchema#string + } + } + } + [1, 1] element ebaz http://www.w3.org/2001/XMLSchema#string + [1, 1] any 'any #0' + } + } + + element ebaz http://www.w3.org/2001/XMLSchema#string + + attribute abaz http://www.w3.org/2001/XMLSchema#string + } +} diff --git a/libxsd-frontend/tests/schema/annotation/test-000.xsd b/libxsd-frontend/tests/schema/annotation/test-000.xsd new file mode 100644 index 0000000..f768b45 --- /dev/null +++ b/libxsd-frontend/tests/schema/annotation/test-000.xsd @@ -0,0 +1,120 @@ + + + + + schema documentation + + + + + list type documentation + + + + + + + union type documentation + + + + + + + enumeration type documentation + + + + + enumerator documentation (male) + + + + + enumerator documentation (female) + + + + + + + + complex type documentation + + + + + local element efoo documentation + + + + + local element ebar documentation + + + + + + nested local element efoo documentation + + + + + + nested local attribute afoo documentation + + + + + + + local element ebaz documentation + + + + + any documentation + + + + + + local attribute afoo documentation + + + + + local attribute abar documentation + + + + list type documentation + + + + + + + local attribute abaz documentation + + + + + anyAttribute documentation + + + + + + + global element documentation + + + + + + global attribute documentation + + + + diff --git a/libxsd-frontend/tests/schema/annotation/test-001.std b/libxsd-frontend/tests/schema/annotation/test-001.std new file mode 100644 index 0000000..9e2c99a --- /dev/null +++ b/libxsd-frontend/tests/schema/annotation/test-001.std @@ -0,0 +1,36 @@ +primary +{ + namespace test + { + complex type + { + + element ebar + + element efoo + + element ebar + + optional attribute abar http://www.w3.org/2001/XMLSchema#string + + optional attribute afoo http://www.w3.org/2001/XMLSchema#string + + optional attribute abaz http://www.w3.org/2001/XMLSchema#string + [1, 1] sequence + { + [1, 1] element ebar http://www.w3.org/2001/XMLSchema#string + [1, 1] choice + { + [1, 1] element efoo http://www.w3.org/2001/XMLSchema#string + [1, 1] element ebar http://www.w3.org/2001/XMLSchema#string + } + } + } + + element ebar http://www.w3.org/2001/XMLSchema#string + + attribute abar http://www.w3.org/2001/XMLSchema#string + + attribute abaz http://www.w3.org/2001/XMLSchema#string + } +} diff --git a/libxsd-frontend/tests/schema/annotation/test-001.xsd b/libxsd-frontend/tests/schema/annotation/test-001.xsd new file mode 100644 index 0000000..286f63a --- /dev/null +++ b/libxsd-frontend/tests/schema/annotation/test-001.xsd @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + group element efoo documentation + + + + + + + + + global element ebar documentation + + + + + + + group attribute afoo documentation + + + + + + + + global attribute abar documentation + + + + + + global attribute abaz documentation + + + + diff --git a/libxsd-frontend/tests/schema/anonymous/makefile b/libxsd-frontend/tests/schema/anonymous/makefile new file mode 100644 index 0000000..950e34b --- /dev/null +++ b/libxsd-frontend/tests/schema/anonymous/makefile @@ -0,0 +1,35 @@ +# file : tests/schema/annotation/makefile +# author : Boris Kolpackov +# copyright : Copyright (c) 2006-2010 Code Synthesis Tools CC +# license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +include $(dir $(lastword $(MAKEFILE_LIST)))../../../build/bootstrap.make + +tests := 000 001 + +driver := $(out_root)/tests/dump/driver +test := $(out_base)/.test +clean := $(out_base)/.clean + +# Convenience alias for default target. +# +$(out_base)/: $(driver) + +# Test. +# +test_targets := $(addprefix $(out_base)/.test-,$(tests)) + +$(test): $(test_targets) +$(test_targets): driver := $(driver) + +.PHONY: $(out_base)/.test-% +$(out_base)/.test-%: $(driver) $(src_base)/test-%.xsd $(src_base)/test-%.std + $(call message,test $(out_base)/$*,$(driver) --anonymous $(src_base)/test-$*.xsd | diff -u $(src_base)/test-$*.std -) + +# Clean. +# +$(clean): + +# Dependencies. +# +$(call import,$(src_root)/tests/dump/makefile) diff --git a/libxsd-frontend/tests/schema/anonymous/test-000.std b/libxsd-frontend/tests/schema/anonymous/test-000.std new file mode 100644 index 0000000..1f33cb0 --- /dev/null +++ b/libxsd-frontend/tests/schema/anonymous/test-000.std @@ -0,0 +1,30 @@ +anonymous: test anon_item anon +anonymous: test anon_nested_item anon_nested +anonymous: test anon_nested_item_base anon_nested_item +primary +{ + namespace test + { + list named http://www.w3.org/2001/XMLSchema#string + enumeration anon_item: http://www.w3.org/2001/XMLSchema#string + { + enumerator male + enumerator female + } + list anon test#anon_item1 + list anon_nested test#anon_nested_item + enumeration anon_item1: http://www.w3.org/2001/XMLSchema#string + { + enumerator male + enumerator female + } + enumeration anon_nested_item: test#anon_nested_item_base + { + enumerator male + enumerator female + } + complex anon_nested_item_base: http://www.w3.org/2001/XMLSchema#string + { + } + } +} diff --git a/libxsd-frontend/tests/schema/anonymous/test-000.xsd b/libxsd-frontend/tests/schema/anonymous/test-000.xsd new file mode 100644 index 0000000..ece8f4a --- /dev/null +++ b/libxsd-frontend/tests/schema/anonymous/test-000.xsd @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libxsd-frontend/tests/schema/anonymous/test-001.std b/libxsd-frontend/tests/schema/anonymous/test-001.std new file mode 100644 index 0000000..cc3f2d1 --- /dev/null +++ b/libxsd-frontend/tests/schema/anonymous/test-001.std @@ -0,0 +1,38 @@ +anonymous: test anon_base anon +anonymous: test anon_nested_base anon_nested +anonymous: test anon_nested_base_base anon_nested_base +primary +{ + namespace test + { + enumeration named: http://www.w3.org/2001/XMLSchema#string + { + enumerator male + enumerator female + } + enumeration anon_base: http://www.w3.org/2001/XMLSchema#string + { + enumerator male + enumerator female + } + enumeration anon: test#anon_base1 + { + enumerator male + enumerator female + } + enumeration anon_nested: test#anon_nested_base + { + enumerator male + enumerator female + } + complex anon_base1: http://www.w3.org/2001/XMLSchema#string + { + } + complex anon_nested_base: test#anon_nested_base_base + { + } + complex anon_nested_base_base: http://www.w3.org/2001/XMLSchema#string + { + } + } +} diff --git a/libxsd-frontend/tests/schema/anonymous/test-001.xsd b/libxsd-frontend/tests/schema/anonymous/test-001.xsd new file mode 100644 index 0000000..4a8414f --- /dev/null +++ b/libxsd-frontend/tests/schema/anonymous/test-001.xsd @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libxsd-frontend/tests/schema/attribute-group/makefile b/libxsd-frontend/tests/schema/attribute-group/makefile new file mode 100644 index 0000000..e96c0c7 --- /dev/null +++ b/libxsd-frontend/tests/schema/attribute-group/makefile @@ -0,0 +1,35 @@ +# file : tests/schema/attribute-group/makefile +# author : Boris Kolpackov +# copyright : Copyright (c) 2006-2010 Code Synthesis Tools CC +# license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +include $(dir $(lastword $(MAKEFILE_LIST)))../../../build/bootstrap.make + +tests := 000 001 + +driver := $(out_root)/tests/dump/driver +test := $(out_base)/.test +clean := $(out_base)/.clean + +# Convenience alias for default target. +# +$(out_base)/: $(driver) + +# Test. +# +test_targets := $(addprefix $(out_base)/.test-,$(tests)) + +$(test): $(test_targets) +$(test_targets): driver := $(driver) + +.PHONY: $(out_base)/.test-% +$(out_base)/.test-%: $(driver) $(src_base)/test-%.xsd $(src_base)/test-%.std + $(call message,test $(out_base)/$*,$(driver) $(src_base)/test-$*.xsd | diff -u $(src_base)/test-$*.std -) + +# Clean. +# +$(clean): + +# Dependencies. +# +$(call import,$(src_root)/tests/dump/makefile) diff --git a/libxsd-frontend/tests/schema/attribute-group/test-000.std b/libxsd-frontend/tests/schema/attribute-group/test-000.std new file mode 100644 index 0000000..61ad802 --- /dev/null +++ b/libxsd-frontend/tests/schema/attribute-group/test-000.std @@ -0,0 +1,17 @@ +primary +{ + namespace test + { + complex type + { + optional attribute foo2 http://www.w3.org/2001/XMLSchema#string + required attribute bar2 http://www.w3.org/2001/XMLSchema#string + optional attribute foo3 http://www.w3.org/2001/XMLSchema#string + required attribute bar3 http://www.w3.org/2001/XMLSchema#string + } + attribute foo2 http://www.w3.org/2001/XMLSchema#string + attribute bar2 http://www.w3.org/2001/XMLSchema#string + attribute foo3 http://www.w3.org/2001/XMLSchema#string + attribute bar3 http://www.w3.org/2001/XMLSchema#string + } +} diff --git a/libxsd-frontend/tests/schema/attribute-group/test-000.xsd b/libxsd-frontend/tests/schema/attribute-group/test-000.xsd new file mode 100644 index 0000000..9087a2b --- /dev/null +++ b/libxsd-frontend/tests/schema/attribute-group/test-000.xsd @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libxsd-frontend/tests/schema/attribute-group/test-001.std b/libxsd-frontend/tests/schema/attribute-group/test-001.std new file mode 100644 index 0000000..54a1e96 --- /dev/null +++ b/libxsd-frontend/tests/schema/attribute-group/test-001.std @@ -0,0 +1,12 @@ +primary +{ + namespace test + { + complex type + { + any-attribute 'any-attribute #1' + optional attribute foo http://www.w3.org/2001/XMLSchema#string + any-attribute 'any-attribute #0' + } + } +} diff --git a/libxsd-frontend/tests/schema/attribute-group/test-001.xsd b/libxsd-frontend/tests/schema/attribute-group/test-001.xsd new file mode 100644 index 0000000..dc44a70 --- /dev/null +++ b/libxsd-frontend/tests/schema/attribute-group/test-001.xsd @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/libxsd-frontend/tests/schema/default/makefile b/libxsd-frontend/tests/schema/default/makefile new file mode 100644 index 0000000..dbb5fa9 --- /dev/null +++ b/libxsd-frontend/tests/schema/default/makefile @@ -0,0 +1,35 @@ +# file : tests/schema/default/makefile +# author : Boris Kolpackov +# copyright : Copyright (c) 2006-2010 Code Synthesis Tools CC +# license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +include $(dir $(lastword $(MAKEFILE_LIST)))../../../build/bootstrap.make + +tests := 000 001 + +driver := $(out_root)/tests/dump/driver +test := $(out_base)/.test +clean := $(out_base)/.clean + +# Convenience alias for default target. +# +$(out_base)/: $(driver) + +# Test. +# +test_targets := $(addprefix $(out_base)/.test-,$(tests)) + +$(test): $(test_targets) +$(test_targets): driver := $(driver) + +.PHONY: $(out_base)/.test-% +$(out_base)/.test-%: $(driver) $(src_base)/test-%.xsd $(src_base)/test-%.std + $(call message,test $(out_base)/$*,$(driver) --anonymous $(src_base)/test-$*.xsd | diff -u $(src_base)/test-$*.std -) + +# Clean. +# +$(clean): + +# Dependencies. +# +$(call import,$(src_root)/tests/dump/makefile) diff --git a/libxsd-frontend/tests/schema/default/test-000.std b/libxsd-frontend/tests/schema/default/test-000.std new file mode 100644 index 0000000..efa1140 --- /dev/null +++ b/libxsd-frontend/tests/schema/default/test-000.std @@ -0,0 +1,28 @@ +primary +{ + namespace test + { + complex type + { + element e1=123 + element e2==456 + element e3=unqual + element e4==test#t:foo + element e5=foo#x:bar + optional attribute a1=123 http://www.w3.org/2001/XMLSchema#int + optional attribute a2==456 http://www.w3.org/2001/XMLSchema#int + optional attribute a3=foo#x:bar test#qname + [1, 1] sequence + { + [1, 1] element e1=123 http://www.w3.org/2001/XMLSchema#int + [1, 1] element e2==456 http://www.w3.org/2001/XMLSchema#int + [1, 1] element e3=unqual http://www.w3.org/2001/XMLSchema#QName + [1, 1] element e4==test#t:foo http://www.w3.org/2001/XMLSchema#QName + [1, 1] element e5=foo#x:bar http://www.w3.org/2001/XMLSchema#QName + } + } + complex qname: http://www.w3.org/2001/XMLSchema#QName + { + } + } +} diff --git a/libxsd-frontend/tests/schema/default/test-000.xsd b/libxsd-frontend/tests/schema/default/test-000.xsd new file mode 100644 index 0000000..bfaedc5 --- /dev/null +++ b/libxsd-frontend/tests/schema/default/test-000.xsd @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libxsd-frontend/tests/schema/default/test-001.std b/libxsd-frontend/tests/schema/default/test-001.std new file mode 100644 index 0000000..1b84a07 --- /dev/null +++ b/libxsd-frontend/tests/schema/default/test-001.std @@ -0,0 +1,15 @@ +primary +{ + namespace test + { + complex type + { + element e=foo#unqual + optional attribute a=foo#unqual http://www.w3.org/2001/XMLSchema#QName + [1, 1] sequence + { + [1, 1] element e=foo#unqual http://www.w3.org/2001/XMLSchema#QName + } + } + } +} diff --git a/libxsd-frontend/tests/schema/default/test-001.xsd b/libxsd-frontend/tests/schema/default/test-001.xsd new file mode 100644 index 0000000..5ee0507 --- /dev/null +++ b/libxsd-frontend/tests/schema/default/test-001.xsd @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/libxsd-frontend/tests/schema/element-group/makefile b/libxsd-frontend/tests/schema/element-group/makefile new file mode 100644 index 0000000..8a4ad89 --- /dev/null +++ b/libxsd-frontend/tests/schema/element-group/makefile @@ -0,0 +1,35 @@ +# file : tests/schema/element-group/makefile +# author : Boris Kolpackov +# copyright : Copyright (c) 2006-2010 Code Synthesis Tools CC +# license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +include $(dir $(lastword $(MAKEFILE_LIST)))../../../build/bootstrap.make + +tests := 000 001 002 + +driver := $(out_root)/tests/dump/driver +test := $(out_base)/.test +clean := $(out_base)/.clean + +# Convenience alias for default target. +# +$(out_base)/: $(driver) + +# Test. +# +test_targets := $(addprefix $(out_base)/.test-,$(tests)) + +$(test): $(test_targets) +$(test_targets): driver := $(driver) + +.PHONY: $(out_base)/.test-% +$(out_base)/.test-%: $(driver) $(src_base)/test-%.xsd $(src_base)/test-%.std + $(call message,test $(out_base)/$*,$(driver) $(src_base)/test-$*.xsd | diff -u $(src_base)/test-$*.std -) + +# Clean. +# +$(clean): + +# Dependencies. +# +$(call import,$(src_root)/tests/dump/makefile) diff --git a/libxsd-frontend/tests/schema/element-group/test-000.std b/libxsd-frontend/tests/schema/element-group/test-000.std new file mode 100644 index 0000000..1652b68 --- /dev/null +++ b/libxsd-frontend/tests/schema/element-group/test-000.std @@ -0,0 +1,33 @@ +primary +{ + namespace test + { + complex type + { + element foo2 + element bar2 + element foo3 + element bar3 + [1, 1] sequence + { + [0, unbounded] choice + { + [0, 1] choice + { + [1, 1] element foo2 http://www.w3.org/2001/XMLSchema#string + [0, 1] element bar2 http://www.w3.org/2001/XMLSchema#string + } + [1, unbounded] choice + { + [1, unbounded] element foo3 http://www.w3.org/2001/XMLSchema#string + [0, unbounded] element bar3 http://www.w3.org/2001/XMLSchema#string + } + } + } + } + element foo2 http://www.w3.org/2001/XMLSchema#string + element bar2 http://www.w3.org/2001/XMLSchema#string + element foo3 http://www.w3.org/2001/XMLSchema#string + element bar3 http://www.w3.org/2001/XMLSchema#string + } +} diff --git a/libxsd-frontend/tests/schema/element-group/test-000.xsd b/libxsd-frontend/tests/schema/element-group/test-000.xsd new file mode 100644 index 0000000..1864b28 --- /dev/null +++ b/libxsd-frontend/tests/schema/element-group/test-000.xsd @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libxsd-frontend/tests/schema/element-group/test-001.std b/libxsd-frontend/tests/schema/element-group/test-001.std new file mode 100644 index 0000000..ae8c1fc --- /dev/null +++ b/libxsd-frontend/tests/schema/element-group/test-001.std @@ -0,0 +1,137 @@ +primary +{ + namespace test + { + complex type + { + element foo + element bar + [1, 1] sequence + { + [1, 1] choice + { + [1, 1] element foo + { + complex + { + element foo + element bar + [1, 1] sequence + { + [1, 1] choice + { + [1, 1] element foo + { + complex + } + [1, 1] element bar + { + complex + { + element foo + element bar + [1, 1] sequence + { + [1, 1] choice + { + [1, 1] element foo + { + complex + } + [1, 1] element bar + { + complex + } + } + } + } + } + } + } + } + } + [1, 1] element bar + { + complex + { + element foo + element bar + [1, 1] sequence + { + [1, 1] choice + { + [1, 1] element foo + { + complex + { + element foo + element bar + [1, 1] sequence + { + [1, 1] choice + { + [1, 1] element foo + { + complex + } + [1, 1] element bar + { + complex + } + } + } + } + } + [1, 1] element bar + { + complex + } + } + } + } + } + } + } + } + element bar + { + complex + { + element foo + element bar + [1, 1] sequence + { + [1, 1] choice + { + [1, 1] element foo + { + complex + { + element foo + element bar + [1, 1] sequence + { + [1, 1] choice + { + [1, 1] element foo + { + complex + } + [1, 1] element bar + { + complex + } + } + } + } + } + [1, 1] element bar + { + complex + } + } + } + } + } + } +} diff --git a/libxsd-frontend/tests/schema/element-group/test-001.xsd b/libxsd-frontend/tests/schema/element-group/test-001.xsd new file mode 100644 index 0000000..c6059af --- /dev/null +++ b/libxsd-frontend/tests/schema/element-group/test-001.xsd @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libxsd-frontend/tests/schema/element-group/test-002.std b/libxsd-frontend/tests/schema/element-group/test-002.std new file mode 100644 index 0000000..d2c60fe --- /dev/null +++ b/libxsd-frontend/tests/schema/element-group/test-002.std @@ -0,0 +1,24 @@ +primary +{ + namespace test + { + complex type + { + any 'any #1' + element foo + any 'any #0' + [1, 1] sequence + { + [0, unbounded] sequence + { + [1, 1] any 'any #1' + } + [0, unbounded] sequence + { + [1, 1] element foo http://www.w3.org/2001/XMLSchema#int + [1, 1] any 'any #0' + } + } + } + } +} diff --git a/libxsd-frontend/tests/schema/element-group/test-002.xsd b/libxsd-frontend/tests/schema/element-group/test-002.xsd new file mode 100644 index 0000000..bc1bd70 --- /dev/null +++ b/libxsd-frontend/tests/schema/element-group/test-002.xsd @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libxsd-frontend/tests/schema/enumeration/makefile b/libxsd-frontend/tests/schema/enumeration/makefile new file mode 100644 index 0000000..d958178 --- /dev/null +++ b/libxsd-frontend/tests/schema/enumeration/makefile @@ -0,0 +1,35 @@ +# file : tests/schema/enumeration/makefile +# author : Boris Kolpackov +# copyright : Copyright (c) 2006-2010 Code Synthesis Tools CC +# license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +include $(dir $(lastword $(MAKEFILE_LIST)))../../../build/bootstrap.make + +tests := 000 + +driver := $(out_root)/tests/dump/driver +test := $(out_base)/.test +clean := $(out_base)/.clean + +# Convenience alias for default target. +# +$(out_base)/: $(driver) + +# Test. +# +test_targets := $(addprefix $(out_base)/.test-,$(tests)) + +$(test): $(test_targets) +$(test_targets): driver := $(driver) + +.PHONY: $(out_base)/.test-% +$(out_base)/.test-%: $(driver) $(src_base)/test-%.xsd $(src_base)/test-%.std + $(call message,test $(out_base)/$*,$(driver) --enum-synthesis $(src_base)/test-$*.xsd | diff -u $(src_base)/test-$*.std -) + +# Clean. +# +$(clean): + +# Dependencies. +# +$(call import,$(src_root)/tests/dump/makefile) diff --git a/libxsd-frontend/tests/schema/enumeration/test-000.std b/libxsd-frontend/tests/schema/enumeration/test-000.std new file mode 100644 index 0000000..64e3065 --- /dev/null +++ b/libxsd-frontend/tests/schema/enumeration/test-000.std @@ -0,0 +1,62 @@ +primary +{ + namespace test + { + complex common-base: http://www.w3.org/2001/XMLSchema#string + { + } + complex base: test#common-base + { + } + enumeration one: test#base + { + + enumerator romance + enumerator fiction + enumerator horror + } + enumeration two: test#common-base + { + enumerator horror + enumerator history + enumerator philosophy + } + enumeration three: http://www.w3.org/2001/XMLSchema#anyURI + { + enumerator foo + enumerator bar + } + enumeration union0: test#common-base + { + + enumerator romance + enumerator fiction + enumerator horror + enumerator history + enumerator philosophy + } + + enumeration union1: test#common-base + { + + enumerator romance + enumerator fiction + enumerator horror + enumerator history + enumerator philosophy + } + union union2 test#one test#union1 test#common-base + union union3 test#one test#three + complex complex1 + { + element a + [1, 1] sequence + { + [1, 1] element a test#union1 + } + } + complex complex2: test#union1 + { + } + } +} diff --git a/libxsd-frontend/tests/schema/enumeration/test-000.xsd b/libxsd-frontend/tests/schema/enumeration/test-000.xsd new file mode 100644 index 0000000..08539bf --- /dev/null +++ b/libxsd-frontend/tests/schema/enumeration/test-000.xsd @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + romance documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + union1 documentation + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libxsd-frontend/tests/schema/makefile b/libxsd-frontend/tests/schema/makefile new file mode 100644 index 0000000..fde5482 --- /dev/null +++ b/libxsd-frontend/tests/schema/makefile @@ -0,0 +1,25 @@ +# file : tests/schema +# author : Boris Kolpackov +# copyright : Copyright (c) 2006-2010 Code Synthesis Tools CC +# license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +include $(dir $(lastword $(MAKEFILE_LIST)))../../build/bootstrap.make + +tests := \ +annotation \ +anonymous \ +attribute-group \ +default \ +element-group \ +enumeration \ +union + +default := $(out_base)/ +test := $(out_base)/.test +clean := $(out_base)/.clean + +$(default): $(addprefix $(out_base)/,$(addsuffix /,$(tests))) +$(test): $(addprefix $(out_base)/,$(addsuffix /.test,$(tests))) +$(clean): $(addprefix $(out_base)/,$(addsuffix /.clean,$(tests))) + +$(foreach t,$(tests),$(call import,$(src_base)/$t/makefile)) diff --git a/libxsd-frontend/tests/schema/union/makefile b/libxsd-frontend/tests/schema/union/makefile new file mode 100644 index 0000000..7f01070 --- /dev/null +++ b/libxsd-frontend/tests/schema/union/makefile @@ -0,0 +1,35 @@ +# file : tests/schema/union/makefile +# author : Boris Kolpackov +# copyright : Copyright (c) 2006-2010 Code Synthesis Tools CC +# license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +include $(dir $(lastword $(MAKEFILE_LIST)))../../../build/bootstrap.make + +tests := 000 001 + +driver := $(out_root)/tests/dump/driver +test := $(out_base)/.test +clean := $(out_base)/.clean + +# Convenience alias for default target. +# +$(out_base)/: $(driver) + +# Test. +# +test_targets := $(addprefix $(out_base)/.test-,$(tests)) + +$(test): $(test_targets) +$(test_targets): driver := $(driver) + +.PHONY: $(out_base)/.test-% +$(out_base)/.test-%: $(driver) $(src_base)/test-%.xsd $(src_base)/test-%.std + $(call message,test $(out_base)/$*,$(driver) $(src_base)/test-$*.xsd | diff -u $(src_base)/test-$*.std -) + +# Clean. +# +$(clean): + +# Dependencies. +# +$(call import,$(src_root)/tests/dump/makefile) diff --git a/libxsd-frontend/tests/schema/union/test-000.std b/libxsd-frontend/tests/schema/union/test-000.std new file mode 100644 index 0000000..6f95b0c --- /dev/null +++ b/libxsd-frontend/tests/schema/union/test-000.std @@ -0,0 +1,37 @@ +primary +{ + namespace test + { + union u1 http://www.w3.org/2001/XMLSchema#int http://www.w3.org/2001/XMLSchema#string + union u2 + { + enumeration : http://www.w3.org/2001/XMLSchema#token + { + enumerator one + } + } + + { + enumeration : http://www.w3.org/2001/XMLSchema#string + { + enumerator two + } + } + + union u3 http://www.w3.org/2001/XMLSchema#int test#u1 + { + enumeration : http://www.w3.org/2001/XMLSchema#token + { + enumerator one + } + } + + { + enumeration : http://www.w3.org/2001/XMLSchema#string + { + enumerator two + } + } + + } +} diff --git a/libxsd-frontend/tests/schema/union/test-000.xsd b/libxsd-frontend/tests/schema/union/test-000.xsd new file mode 100644 index 0000000..99535de --- /dev/null +++ b/libxsd-frontend/tests/schema/union/test-000.xsd @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libxsd-frontend/tests/schema/union/test-001.std b/libxsd-frontend/tests/schema/union/test-001.std new file mode 100644 index 0000000..f407b30 --- /dev/null +++ b/libxsd-frontend/tests/schema/union/test-001.std @@ -0,0 +1,15 @@ +primary +{ + namespace test + { + list list + { + union http://www.w3.org/2001/XMLSchema#int test#enum + } + enumeration enum: http://www.w3.org/2001/XMLSchema#string + { + enumerator male + enumerator female + } + } +} diff --git a/libxsd-frontend/tests/schema/union/test-001.xsd b/libxsd-frontend/tests/schema/union/test-001.xsd new file mode 100644 index 0000000..00fd8ce --- /dev/null +++ b/libxsd-frontend/tests/schema/union/test-001.xsd @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/libxsd-frontend/version b/libxsd-frontend/version new file mode 100644 index 0000000..092afa1 --- /dev/null +++ b/libxsd-frontend/version @@ -0,0 +1 @@ +1.17.0 diff --git a/libxsd-frontend/xsd-frontend/makefile b/libxsd-frontend/xsd-frontend/makefile new file mode 100644 index 0000000..abf6565 --- /dev/null +++ b/libxsd-frontend/xsd-frontend/makefile @@ -0,0 +1,126 @@ +# file : xsd-frontend/makefile +# author : Boris Kolpackov +# copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +# license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +include $(dir $(lastword $(MAKEFILE_LIST)))../build/bootstrap.make + +cxx_tun := semantic-graph/annotation.cxx \ + semantic-graph/any.cxx \ + semantic-graph/any-attribute.cxx \ + semantic-graph/attribute.cxx \ + semantic-graph/attribute-group.cxx \ + semantic-graph/complex.cxx \ + semantic-graph/compositors.cxx \ + semantic-graph/element.cxx \ + semantic-graph/element-group.cxx \ + semantic-graph/elements.cxx \ + semantic-graph/enumeration.cxx \ + semantic-graph/fundamental.cxx \ + semantic-graph/list.cxx \ + semantic-graph/namespace.cxx \ + semantic-graph/particle.cxx \ + semantic-graph/schema.cxx \ + semantic-graph/union.cxx + +cxx_tun += traversal/attribute.cxx \ + traversal/attribute-group.cxx \ + traversal/complex.cxx \ + traversal/compositors.cxx \ + traversal/element.cxx \ + traversal/element-group.cxx \ + traversal/elements.cxx \ + traversal/enumeration.cxx \ + traversal/fundamental.cxx \ + traversal/list.cxx \ + traversal/namespace.cxx \ + traversal/particle.cxx \ + traversal/schema.cxx \ + traversal/union.cxx + +cxx_tun += transformations/anonymous.cxx \ + transformations/enum-synthesis.cxx \ + transformations/restriction.cxx \ + transformations/schema-per-type.cxx \ + transformations/simplifier.cxx + +cxx_tun += parser.cxx schema-dom-parser.cxx + + +cxx_obj := $(addprefix $(out_base)/,$(cxx_tun:.cxx=.o)) +cxx_od := $(cxx_obj:.o=.o.d) +m4_cxx := $(out_base)/semantic-graph/fundamental.hxx \ + $(out_base)/semantic-graph/fundamental.cxx + +xsd_frontend.l := $(out_base)/xsd-frontend.l +xsd_frontend.l.cpp-options := $(out_base)/xsd-frontend.l.cpp-options + +clean := $(out_base)/.clean + +# Import. +# +$(call import,\ + $(scf_root)/import/libboost/filesystem/stub.make,\ + l: fs.l,cpp-options: fs.l.cpp-options) + +$(call import,\ + $(scf_root)/import/libxerces-c/stub.make,\ + l: xerces_c.l,cpp-options: xerces_c.l.cpp-options) + +$(call import,\ + $(scf_root)/import/libcult/stub.make,\ + l: cult.l,cpp-options: cult.l.cpp-options) + +$(call import,\ + $(scf_root)/import/libfrontend-elements/stub.make,\ + l: fe.l,cpp-options: fe.l.cpp-options) + +# what to build +# +$(xsd_frontend.l): $(cxx_obj) $(fe.l) $(cult.l) $(xerces_c.l) $(fs.l) + +$(xsd_frontend.l.cpp-options): prefix := xsd-frontend/ $(out_root)/ +$(xsd_frontend.l.cpp-options): value := -I$(src_root) -I$(out_root) +$(xsd_frontend.l.cpp-options): \ + $(fs.l.cpp-options) \ + $(fe.l.cpp-options) \ + $(cult.l.cpp-options) + +#@@ This can be further optimized since only parser depends on xerces. +# +$(cxx_obj) $(cxx_od): $(xsd_frontend.l.cpp-options) $(xerces_c.l.cpp-options) + +$(m4_cxx): $(src_base)/semantic-graph/fundamental.m4 +$(m4_cxx): m4_options := -I $(src_base)/semantic-graph + +$(call include-dep,$(cxx_od)) + +# Alias for default target. +# +$(out_base)/: $(xsd_frontend.l) + +# Clean +# +$(clean): $(xsd_frontend.l).o.clean \ + $(xsd_frontend.l.cpp-options).clean \ + $(addsuffix .cxx.clean,$(cxx_obj)) \ + $(addsuffix .cxx.clean,$(cxx_od)) \ + $(addsuffix .m4.clean,$(m4_cxx)) + +# Generated .gitignore. +# +ifeq ($(out_base),$(src_base)) +$(xsd_frontend.l): | $(out_base)/.gitignore + +$(out_base)/.gitignore: files := semantic-graph/fundamental.hxx semantic-graph/fundamental.cxx +$(clean): $(out_base)/.gitignore.clean + +$(call include,$(bld_root)/git/gitignore.make) +endif + +# How to. +# +$(call include,$(bld_root)/cxx/o-l.make) +$(call include,$(bld_root)/cxx/cxx-o.make) +$(call include,$(bld_root)/cxx/cxx-d.make) +$(call include,$(bld_root)/m4/m4.make) diff --git a/libxsd-frontend/xsd-frontend/parser.cxx b/libxsd-frontend/xsd-frontend/parser.cxx new file mode 100644 index 0000000..901a8d3 --- /dev/null +++ b/libxsd-frontend/xsd-frontend/parser.cxx @@ -0,0 +1,5126 @@ +// file : xsd-frontend/parser.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +//@@ Do i need this? +// +#include + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include +#include +#include // std::auto_ptr + +using std::wcout; +using std::wcerr; +using std::endl; + +using Cult::RTTI::TypeId; + +namespace XSDFrontend +{ + namespace Xerces = XML::Xerces; + using namespace SemanticGraph; + + //@@ Port to tracing facility. + // + Boolean trace_ = false; + + String const xsd = L"http://www.w3.org/2001/XMLSchema"; + String const xse = L"http://www.codesynthesis.com/xmlns/xml-schema-extension"; + + namespace + { + // + // Exceptions. + // + + struct NotNamespace + { + NotNamespace (String const& ns) + : ns_ (ns) + { + } + + String const& + ns () const + { + return ns_; + } + + private: + String ns_; + }; + + struct NotName + { + NotName (String const& ns, String const& name) + : ns_ (ns), name_ (name) + { + } + + String const& + ns () const + { + return ns_; + } + + String const& + name () const + { + return name_; + } + + private: + String ns_; + String name_; + }; + + + // Name cache. We only support maximum two nodes with the same + // name in the cache (e.g., element and type). For (rare) cases + // where there is three or more names, there will be a cache miss. + // + struct CacheNodes + { + CacheNodes () : first (0), second (0) {} + + Nameable* first; + Nameable* second; + }; + + typedef Cult::Containers::Map NodeMap; + typedef Cult::Containers::Map NamespaceMap; + typedef Cult::Containers::Vector DefaultValues; + + template + X& + resolve (String const& ns_name, + String const& uq_name, + Schema& s_, + NamespaceMap& cache) + { + // First check the cache. + // + NamespaceMap::Iterator i (cache.find (ns_name)); + + if (i != cache.end ()) + { + NodeMap::Iterator j (i->second.find (uq_name)); + + if (j != i->second.end ()) + { + X* x; + + if ((x = dynamic_cast (j->second.first)) || + (x = dynamic_cast (j->second.second))) + return *x; + } + } + + Scope::NamesIteratorPair nss (s_.find (ns_name)); + + if (nss.first == nss.second) + throw NotNamespace (ns_name); + + for (; nss.first != nss.second; ++nss.first) + { + Namespace& ns (dynamic_cast (nss.first->named ())); + + Scope::NamesIteratorPair types (ns.find (uq_name)); + + for (; types.first != types.second; ++types.first) + { + if (X* x = dynamic_cast (&types.first->named ())) + { + if (trace_) + wcout << "successfully resolved '" << ns_name << '#' << uq_name + << "'" << endl; + + // Add to the cache if there are free slots. + // + NodeMap& m (i != cache.end () ? i->second : cache[ns_name]); + CacheNodes& n (m[uq_name]); + + if (n.first == 0) + n.first = x; + else if (n.second == 0) + n.second = x; + + return *x; + } + } + } + + throw NotName (ns_name, uq_name); + } + + // + // + typedef Cult::Containers::Map Facets; + + Void + copy_facets (Restricts& r, Facets const& f) + { + for (Facets::ConstIterator i (f.begin ()), e (f.end ()); i != e; ++i) + r.facet_insert (i->first, i->second); + } + + // + // + struct UnionMemberType + { + UnionMemberType (String const& ns, String const& uq) + : ns_name (ns), uq_name (uq) + { + } + + String ns_name; + String uq_name; + }; + + typedef Cult::Containers::Vector UnionMemberTypes; + + // + // + struct ElementGroupRef + { + ElementGroupRef (String const& uq_name_, String const& ns_name_, + UnsignedLong min_, UnsignedLong max_, + Compositor& compositor, Scope& scope) + : uq_name (uq_name_), ns_name (ns_name_), + min (min_), max (max_) + { + contains_pos = compositor.contains_end (); + if (compositor.contains_begin () != contains_pos) + --contains_pos; + + names_pos = scope.names_end (); + if (scope.names_begin () != names_pos) + --names_pos; + } + + ElementGroupRef (String const& uq_name_, String const& ns_name_, + UnsignedLong min_, UnsignedLong max_, + Scope& scope) + : uq_name (uq_name_), ns_name (ns_name_), + min (min_), max (max_) + { + names_pos = scope.names_end (); + if (scope.names_begin () != names_pos) + --names_pos; + } + + String uq_name; + String ns_name; + UnsignedLong min, max; + Compositor::ContainsIterator contains_pos; + Scope::NamesIterator names_pos; + }; + + typedef Cult::Containers::Vector ElementGroupRefs; + + + // + // + struct AttributeGroupRef + { + AttributeGroupRef (String const& uq_name_, + String const& ns_name_, + Scope& scope) + : uq_name (uq_name_), ns_name (ns_name_) + { + names_pos = scope.names_end (); + if (scope.names_begin () != names_pos) + --names_pos; + } + + String uq_name; + String ns_name; + Scope::NamesIterator names_pos; + }; + + typedef Cult::Containers::Vector AttributeGroupRefs; + + + // + // + template + struct NodeArgs + { + NodeArgs (N& node, A arg) + : node_ (node), arg_ (arg) + { + } + + operator N& () const + { + return node_; + } + + template + Void + add_edge_left (E& e) + { + node_.add_edge_left (e, arg_); + } + + template + Void + add_edge_right (E& e) + { + node_.add_edge_right (e, arg_); + } + + private: + N& node_; + A arg_; + }; + + + // + // + struct Resolver : Traversal::Element, + Traversal::Attribute, + Traversal::Fundamental::IdRef, + Traversal::Fundamental::IdRefs, + Traversal::List, + Traversal::Union, + Traversal::Complex, + Traversal::Enumeration, + Traversal::ElementGroup, + Traversal::AttributeGroup, + Traversal::Compositor + { + Resolver (Schema& s, + Boolean& valid, + NamespaceMap& cache, + DefaultValues& default_values) + : s_ (s), + valid_ (valid), + cache_ (cache), + default_values_ (default_values) + { + *this >> contains_compositor >> *this; + } + + Void + traverse (SemanticGraph::Attribute& a) + { + // Avoid traversing attribute more than once. + // + if (!a.context ().count ("attribute-traversed")) + { + a.context ().set ("attribute-traversed", true); + SemanticGraph::Member& m (a); + resolve_member (m); + } + } + + Void + traverse (SemanticGraph::Element& e) + { + resolve_element (e); + } + + Void + resolve_element (SemanticGraph::Element& e) + { + // Avoid resolving element more than once. + // + if (e.context ().count ("element-resolved")) + return; + + e.context ().set ("element-resolved", true); + + { + SemanticGraph::Member& m (e); + resolve_member (m); + } + + if (e.context ().count ("substitution-ns-name")) + { + String ns_name (e.context ().get ("substitution-ns-name")); + String uq_name (e.context ().get ("substitution-uq-name")); + + e.context ().remove ("substitution-ns-name"); + e.context ().remove ("substitution-uq-name"); + + try + { + SemanticGraph::Element& root ( + resolve (ns_name, uq_name, s_, cache_)); + + s_.new_edge (e, root); + } + catch (NotNamespace const& ex) + { + if (valid_) + { + wcerr << "ice: unable to resolve namespace '" << ex.ns () << "'" + << endl; + abort (); + } + } + catch (NotName const& ex) + { + if (valid_) + { + wcerr << "ice: unable to resolve name '" << ex.name () + << "' inside namespace '" << ex.ns () << "'" < ("type-ns-name"); + uq_name = m.context ().get ("type-uq-name"); + + m.context ().remove ("type-ns-name"); + m.context ().remove ("type-uq-name"); + m.context ().remove ("edge-type-id"); + + s_.new_edge ( + m, resolve (ns_name, uq_name, s_, cache_)); + } + else if (m.context ().count ("instance-ns-name")) + { + ns_name = m.context ().get ("instance-ns-name"); + uq_name = m.context ().get ("instance-uq-name"); + + m.context ().remove ("instance-ns-name"); + m.context ().remove ("instance-uq-name"); + + + Member& ref (resolve (ns_name, uq_name, s_, cache_)); + + // Make sure the referenced member is fully resolved. + // @@ Substitutes edge won't be resolved. + // + resolve_member (ref); + + + // Substitution group info. We have to test for both resolved + // and unresolved cases since we don't know whether it was + // resolved or not. + // + if (ref.is_a ()) + { + Element& m_e (dynamic_cast (m)); + Element& ref_e (dynamic_cast (ref)); + + if (ref_e.substitutes_p ()) + { + s_.new_edge (m_e, ref_e.substitutes ().root ()); + } + else if (ref_e.context ().count ("substitution-ns-name")) + { + m_e.context ().set ( + "substitution-ns-name", + ref_e.context ().get ("substitution-ns-name")); + + m_e.context ().set ( + "substitution-uq-name", + ref_e.context ().get ("substitution-uq-name")); + } + } + + // + // + s_.new_edge (m, ref.namespace_ ()); + + // Transfer default and fixed values if we haven't already + // gotten them. + // + if (!m.default_p ()) + { + if (ref.fixed_p ()) + m.fixed (ref.value ()); + else if (ref.default_p ()) + { + // Default value applies only if the attribute is optional. + // + if (Attribute* a = dynamic_cast (&m)) + { + if (a->optional_p ()) + m.default_ (ref.value ()); + } + else + m.default_ (ref.value ()); + } + + if (m.default_p ()) + { + m.context ().set ( + "dom-node", + ref.context ().get ("dom-node")); + default_values_.push_back (&m); + } + } + + // Transfer annotation if we haven't already gotten it. + // + if (!m.annotated_p () && ref.annotated_p ()) + s_.new_edge (ref.annotation (), m); + + // Type info. + // + if (ref.typed_p ()) + s_.new_edge (m, ref.type ()); + else + { + if (valid_) + { + wcerr << "ice: referenced instance '" << ns_name << "#" + << uq_name << "' is not typed" << endl; + abort (); + } + } + } + } + catch (NotNamespace const& ex) + { + if (valid_) + { + wcerr << "ice: unable to resolve namespace '" << ex.ns () << "'" + << endl; + abort (); + } + } + catch (NotName const& ex) + { + if (valid_) + { + wcerr << "ice: unable to resolve name '" << ex.name () + << "' inside namespace '" << ex.ns () << "'" < ("type-ns-name")); + String uq_name (s.context ().get ("type-uq-name")); + + s.context ().remove ("type-ns-name"); + s.context ().remove ("type-uq-name"); + s.context ().remove ("edge-type-id"); + + try + { + s_.new_edge ( + resolve (ns_name, uq_name, s_, cache_), s); + } + catch (NotName const& ex) + { + wcerr << s.file () << ":" << s.line () << ":" << s.column () << ": " + << "error: unable to resolve type '" << uq_name << "' " + << "in namespace '" << ns_name << "'" << endl; + + valid_ = false; + } + } + } + + Void + traverse (SemanticGraph::List& l) + { + if (l.context ().count ("type-ns-name")) + { + String ns_name (l.context ().get ("type-ns-name")); + String uq_name (l.context ().get ("type-uq-name")); + + l.context ().remove ("type-ns-name"); + l.context ().remove ("type-uq-name"); + l.context ().remove ("edge-type-id"); + + try + { + s_.new_edge ( + resolve (ns_name, uq_name, s_, cache_), l); + } + catch (NotName const& ex) + { + wcerr << l.file () << ":" << l.line () << ":" << l.column () << ": " + << "error: unable to resolve item type '" << uq_name << "' " + << "in namespace '" << ns_name << "'" << endl; + + valid_ = false; + } + } + + Traversal::List::traverse (l); + } + + Void + traverse (SemanticGraph::Union& u) + { + using SemanticGraph::Union; + + if (u.context ().count ("union-member-types")) + { + UnionMemberTypes const& m ( + u.context ().get ("union-member-types")); + + // Process it backwards so that we can just insert each + // edge in the front. + // + for (UnionMemberTypes::ConstReverseIterator i (m.rbegin ()); + i != m.rend (); i++) + { + try + { + NodeArgs na ( + u, u.argumented_begin ()); + + s_.new_edge ( + resolve ( + i->ns_name, i->uq_name, s_, cache_), na); + } + catch (NotName const& ex) + { + wcerr << u.file () << ":" << u.line () << ":" << u.column () << ": " + << "error: unable to resolve item type '" << i->uq_name << "' " + << "in namespace '" << i->ns_name << "'" << endl; + + valid_ = false; + } + } + + u.context ().remove ("union-member-types"); + } + + Traversal::Union::traverse (u); + } + + Void + traverse (SemanticGraph::Complex& c) + { + // Avoid traversing complex type more than once. + // + if (c.context ().count ("complex-type-resolved")) + return; + + c.context ().set ("complex-type-resolved", true); + + // Resolve base type if any. + // + if (c.context ().count ("type-ns-name")) + { + using Cult::RTTI::TypeId; + + String ns_name (c.context ().get ("type-ns-name")); + String uq_name (c.context ().get ("type-uq-name")); + TypeId edge_id (c.context ().get ("edge-type-id")); + + c.context ().remove ("type-ns-name"); + c.context ().remove ("type-uq-name"); + c.context ().remove ("edge-type-id"); + + try + { + if (edge_id == typeid (Extends)) + { + s_.new_edge ( + c, resolve ( + ns_name, uq_name, s_, cache_)); + } + else if (edge_id == typeid (Restricts)) + { + Restricts& r ( + s_.new_edge ( + c, resolve ( + ns_name, uq_name, s_, cache_))); + + if (c.context ().count ("facets")) + { + Facets const& f (c.context ().get ("facets")); + copy_facets (r, f); + c.context ().remove ("facets"); + } + } + else + assert (false); + } + catch (NotName const& ex) + { + wcerr << c.file () << ":" << c.line () << ":" << c.column () << ": " + << "error: unable to resolve base type '" << uq_name << "' " + << "in namespace '" << ns_name << "'" << endl; + + valid_ = false; + } + } + + // Resolve attribute-group-refs. Do it before element-group-refs + // so that if the scope was empty they end up at the end. + // + if (c.context ().count ("attribute-group-refs")) + { + AttributeGroupRefs& refs ( + c.context ().get ("attribute-group-refs")); + + // Handle refs from last to first so that multiple insertions + // to an empty list (always front) end up in proper order. + // + for (AttributeGroupRefs::ReverseIterator i (refs.rbegin ()); + i != refs.rend (); ++i) + { + clone_attribute_group_content (*i, c); + } + + c.context ().remove ("attribute-group-refs"); + } + + // Resolve element-group-ref if any. + // + if (c.context ().count ("element-group-ref")) + { + using SemanticGraph::Compositor; + + ElementGroupRef& ref ( + c.context ().get ("element-group-ref")); + + Compositor* comp (clone_element_group_content (c, ref)); + + // Create ContainsCompositor edge. + // + if (comp) + s_.new_edge (c, *comp, ref.min, ref.max); + + c.context ().remove ("element-group-ref"); + } + + Traversal::Complex::traverse (c); + } + + Void + traverse (SemanticGraph::Enumeration& e) + { + // Resolve base type if any. + // + if (e.context ().count ("type-ns-name")) + { + String ns_name (e.context ().get ("type-ns-name")); + String uq_name (e.context ().get ("type-uq-name")); + + e.context ().remove ("type-ns-name"); + e.context ().remove ("type-uq-name"); + e.context ().remove ("edge-type-id"); + + try + { + Restricts& r ( + s_.new_edge ( + e, resolve ( + ns_name, uq_name, s_, cache_))); + + if (e.context ().count ("facets")) + { + Facets const& f (e.context ().get ("facets")); + copy_facets (r, f); + e.context ().remove ("facets"); + } + } + catch (NotName const& ex) + { + wcerr << e.file () << ":" << e.line () << ":" << e.column () << ": " + << "error: unable to resolve base type '" << uq_name << "' " + << "in namespace '" << ns_name << "'" << endl; + + valid_ = false; + } + } + + Traversal::Enumeration::traverse (e); + } + + Void + traverse (SemanticGraph::ElementGroup& g) + { + // Avoid traversing groups more than once. + // + if (!g.context ().count ("element-group-traversed")) + { + g.context ().set ("element-group-traversed", true); + Traversal::ElementGroup::traverse (g); + + // Note that setting element-group-resolved after traversing + // the group allows for a recursive shallow resolution using + // resolve_element_group. + // + g.context ().set ("element-group-resolved", true); + } + } + + // We need a "shallow" resolve to break possible recursing: + // group->element->complexType->group. + // + Void + resolve_element_group (SemanticGraph::ElementGroup& g) + { + using SemanticGraph::Scope; + using SemanticGraph::Element; + + // Avoid resolving groups more than once. + // + if (!g.context ().count ("element-group-resolved")) + { + g.context ().set ("element-group-resolved", true); + + for (Scope::NamesIterator i (g.names_begin ()); + i != g.names_end (); ++i) + { + if (Element* e = dynamic_cast (&i->named ())) + resolve_element (*e); + } + + traverse (g.contains_compositor ().compositor ()); + } + } + + Void + traverse (SemanticGraph::AttributeGroup& g) + { + // Avoid traversing groups more than once. + // + if (g.context ().count ("attribute-group-resolved")) + return; + + g.context ().set ("attribute-group-resolved", true); + + // Resolve attribute-group-refs. + // + if (g.context ().count ("attribute-group-refs")) + { + AttributeGroupRefs& refs ( + g.context ().get ("attribute-group-refs")); + + // Handle refs from last to first so that multiple insertions + // to an empty list (always front) end up in proper order. + // + for (AttributeGroupRefs::ReverseIterator i (refs.rbegin ()); + i != refs.rend (); ++i) + { + clone_attribute_group_content (*i, g); + } + + g.context ().remove ("attribute-group-refs"); + } + + Traversal::AttributeGroup::traverse (g); + } + + Void + traverse (SemanticGraph::Compositor& c) + { + using SemanticGraph::Compositor; + + // Resolve element-group-refs if any. + // + if (c.context ().count ("element-group-refs")) + { + using SemanticGraph::Scope; + + ElementGroupRefs& refs ( + c.context ().get ("element-group-refs")); + + // Handle refs from last to first so that multiple insertions + // to an empty list (always front) end up in proper order. + // + for (ElementGroupRefs::ReverseIterator i (refs.rbegin ()); + i != refs.rend (); ++i) + { + // Find our scope. + // + Compositor* j (&c); + + while(!j->contained_compositor_p ()) + j = &j->contained_particle ().compositor (); + + Compositor* comp ( + clone_element_group_content ( + dynamic_cast (j->contained_compositor ().container ()), + *i)); + + // Create ContainsParticle edge. + // + if (comp) + { + NodeArgs na ( + c, i->contains_pos); + s_.new_edge (na, *comp, i->min, i->max); + } + } + + c.context ().remove ("element-group-refs"); + } + + // Traverse recursively but only particles that are compositors. + // This way we won't trigger anonymous type traversal (via member) + // and therefore can call this functions from resolve_element_group + // to completely resolve a group. + // + for (Compositor::ContainsIterator i (c.contains_begin ()), + e (c.contains_end ()); i != e; ++i) + { + SemanticGraph::Particle& p (i->particle ()); + + if (p.is_a ()) + dispatch (p); + } + + // Traversal::Compositor::traverse (c); + } + + SemanticGraph::Compositor* + clone_element_group_content (SemanticGraph::Scope& s, + ElementGroupRef const& ref) + { + using SemanticGraph::Scope; + using SemanticGraph::Compositor; + using SemanticGraph::ElementGroup; + + try + { + ElementGroup& g ( + resolve (ref.ns_name, ref.uq_name, s_, cache_)); + + // Make sure the group and all its content are fully resolved. + // + resolve_element_group (g); + + Scope::NamesIterator pos (ref.names_pos); + Compositor& root (g.contains_compositor ().compositor ()); + Compositor& copy (clone_compositor (root, s, pos)); + + return © + } + catch (NotNamespace const& ex) + { + if (valid_) + { + wcerr << "ice: unable to resolve namespace '" << ex.ns () << "'" + << endl; + abort (); + } + } + catch (NotName const& ex) + { + if (valid_) + { + wcerr << "ice: unable to resolve name '" << ex.name () + << "' inside namespace '" << ex.ns () << "'" << endl; + abort (); + } + } + + return 0; + } + + SemanticGraph::Compositor& + clone_compositor (SemanticGraph::Compositor& c, + SemanticGraph::Scope& scope, + SemanticGraph::Scope::NamesIterator& pos) + { + using SemanticGraph::Any; + using SemanticGraph::Element; + using SemanticGraph::Particle; + using SemanticGraph::Compositor; + + Compositor* tmp (0); + + if (c.is_a ()) + tmp = &s_.new_node (c.file (), c.line (), c.column ()); + else if (c.is_a ()) + tmp = &s_.new_node (c.file (), c.line (), c.column ()); + else if (c.is_a ()) + tmp = &s_.new_node (c.file (), c.line (), c.column ()); + else + assert (false); + + Compositor& copy (*tmp); + + // Copy annotation. + // + if (c.annotated_p ()) + s_.new_edge (c.annotation (), copy); + + for (Compositor::ContainsIterator i (c.contains_begin ()); + i != c.contains_end (); ++i) + { + Particle& p (i->particle ()); + + if (p.is_a ()) + { + Compositor& c (dynamic_cast (p)); + Compositor& cc (clone_compositor (c, scope, pos)); + + s_.new_edge (copy, cc, i->min (), i->max ()); + } + else if (p.is_a ()) + { + Element& e (dynamic_cast (p)); + Element& ec (clone_element (e)); + + s_.new_edge (copy, ec, i->min (), i->max ()); + + NodeArgs na (scope, pos); + s_.new_edge (na, ec, e.name ()); + ++pos; + } + else if (p.is_a ()) + { + Any& a (dynamic_cast (p)); + Any& ac ( + s_.new_node (a.file (), a.line (), a.column (), + a.namespace_begin (), a.namespace_end ())); + + ac.prototype (a); + + s_.new_edge (copy, ac, i->min (), i->max ()); + + // Transfer annotation. + // + if (a.annotated_p ()) + s_.new_edge (a.annotation (), ac); + + // Any has no name so we have to come up with a fake one in + // order to put it into the scope. Note that we cannot reuse + // the name from the prototype. + + UnsignedLong count; + FrontendElements::Context& ctx (scope.context ()); + + if (!ctx.count ("any-name-count")) + { + count = 0; + ctx.set ("any-name-count", count); + } + else + count = ++(ctx.get ("any-name-count")); + + std::basic_ostringstream os; + os << "any #" << count; + + NodeArgs na (scope, pos); + s_.new_edge (na, ac, os.str ()); + ++pos; + } + else + assert (false); + } + + return copy; + } + + // Clone a fully-resolved element. Note that it cannot be used as + // is to clone ref'ed element (default/fixed value, etc). + // + SemanticGraph::Element& + clone_element (SemanticGraph::Element& e) + { + using SemanticGraph::Element; + + Element& copy ( + s_.new_node ( + e.file (), e.line (), e.column (), e.global_p (), e.qualified_p ())); + + if (e.qualified_p ()) + s_.new_edge (copy, e.namespace_ ()); + + // Transfer default and fixed values. + // + if (e.fixed_p ()) + copy.fixed (e.value ()); + else if (e.default_p ()) + copy.default_ (e.value ()); + + if (copy.default_p ()) + { + copy.context ().set ( + "dom-node", + e.context ().get ("dom-node")); + default_values_.push_back (©); + } + + // Transfer annotation. + // + if (e.annotated_p ()) + s_.new_edge (e.annotation (), copy); + + // Belongs edge. + // + if (e.typed_p ()) + s_.new_edge (copy, e.type ()); + else + assert (!valid_); + + // Substitutes edge. + // + if (e.substitutes_p ()) + s_.new_edge (copy, e.substitutes ().root ()); + + return copy; + } + + Void + clone_attribute_group_content (AttributeGroupRef& ref, + SemanticGraph::Scope& s) + { + using SemanticGraph::Scope; + using SemanticGraph::Attribute; + using SemanticGraph::AttributeGroup; + + try + { + AttributeGroup& g ( + resolve (ref.ns_name, ref.uq_name, s_, cache_)); + + // Make sure the group and all its content are fully resolved. + // + traverse (g); + + Scope::NamesIterator pos (ref.names_pos); + + for (Scope::NamesIterator i (g.names_begin ()); + i != g.names_end (); ++i) + { + if (Attribute* p = dynamic_cast (&i->named ())) + { + Attribute& a ( + s_.new_node (p->file (), + p->line (), + p->column (), + p->optional_p (), + p->global_p (), + p->qualified_p ())); + + NodeArgs na (s, pos); + s_.new_edge (na, a, p->name ()); + ++pos; + + if (p->qualified_p ()) + s_.new_edge (a, p->namespace_ ()); + + // Transfer default and fixed values if any. + // + if (p->fixed_p ()) + a.fixed (p->value ()); + else if (p->default_p ()) + a.default_ (p->value ()); + + if (a.default_p ()) + { + a.context ().set ( + "dom-node", + p->context ().get ("dom-node")); + default_values_.push_back (&a); + } + + // Transfer annotation. + // + if (p->annotated_p ()) + s_.new_edge (p->annotation (), a); + + // Belongs edge. + // + if (p->typed_p ()) + s_.new_edge (a, p->type ()); + else + assert (!valid_); + } + else if ( + AnyAttribute* p = dynamic_cast (&i->named ())) + { + AnyAttribute& any ( + s_.new_node (p->file (), + p->line (), + p->column (), + p->namespace_begin (), + p->namespace_end ())); + + any.prototype (*p); + + // Transfer annotation. + // + if (p->annotated_p ()) + s_.new_edge (p->annotation (), any); + + // AnyAttribute has no name so we have to come up with a fake + // one in order to put it into the scope. Note that we cannot + // reuse the name from the attribute group. + + UnsignedLong count; + FrontendElements::Context& ctx (s.context ()); + + if (!ctx.count ("any-attribute-name-count")) + { + count = 0; + ctx.set ("any-attribute-name-count", count); + } + else + count = ++(ctx.get ("any-attribute-name-count")); + + std::basic_ostringstream os; + os << "any-attribute #" << count; + + NodeArgs na (s, pos); + s_.new_edge (na, any, os.str ()); + ++pos; + } + } + } + catch (NotNamespace const& ex) + { + if (valid_) + { + wcerr << "ice: unable to resolve namespace '" << ex.ns () << "'" + << endl; + abort (); + } + } + catch (NotName const& ex) + { + if (valid_) + { + wcerr << "ice: unable to resolve attribute group name '" + << ex.name () << "' inside namespace '" << ex.ns () << "'" + << endl; + abort (); + } + } + } + + private: + Schema& s_; + Boolean& valid_; + NamespaceMap& cache_; + DefaultValues& default_values_; + + private: + //Traversal::ContainsParticle contains_particle; + Traversal::ContainsCompositor contains_compositor; + }; + } + + // + // + struct FilePathComparator + { + Boolean + operator () (SemanticGraph::Path const& x, + SemanticGraph::Path const& y) const + { +#if !defined(BOOST_FILESYSTEM_VERSION) || BOOST_FILESYSTEM_VERSION == 2 + return x.native_file_string () < y.native_file_string (); +#else + return x.string () < y.string (); +#endif + } + }; + + // Parser::Impl + // + + class Parser::Impl: public NonCopyable + { + public: + ~Impl (); + + Impl (Boolean proper_restriction, + Boolean multiple_imports, + Boolean full_schema_check, + LocationTranslator*, + const WarningSet*); + + Evptr + parse (Path const&); + + Evptr + parse (Paths const&); + + Evptr + xml_schema (Path const&); + + private: + Void + fill_xml_schema (Schema&, Path const&); + + private: + XML::AutoPtr + dom (SemanticGraph::Path const&, Boolean validate); + + Void + schema (XML::Element const&); + + SemanticGraph::Annotation* + annotation (Boolean process); + + Void + import (XML::Element const&); + + Void + include (XML::Element const&); + + Void + element_group (XML::Element const&, Boolean in_compositor); + + SemanticGraph::Type* + simple_type (XML::Element const&); + + SemanticGraph::Type* + list (XML::Element const& l, XML::Element const& type); + + SemanticGraph::Type* + union_ (XML::Element const& u, XML::Element const& type); + + SemanticGraph::Type* + restriction (XML::Element const& r, XML::Element const& type); + + Void + enumeration (XML::Element const&); + + SemanticGraph::Type* + complex_type (XML::Element const&); + + All* + all (XML::Element const&); + + Choice* + choice (XML::Element const&, Boolean in_compositor); + + Sequence* + sequence (XML::Element const&, Boolean in_compositor); + + Void + simple_content (XML::Element const&); + + Void + complex_content (XML::Element const&, Complex&); + + Void + simple_content_extension (XML::Element const&); + + Void + simple_content_restriction (XML::Element const&); + + Void + complex_content_extension (XML::Element const&, Complex&); + + Void + complex_content_restriction (XML::Element const&, Complex&); + + Void + element (XML::Element const&, Boolean global); + + Void + attribute (XML::Element const&, Boolean global); + + Void + attribute_group (XML::Element const&); + + Void + any (XML::Element const&); + + Void + any_attribute (XML::Element const&); + + private: + Boolean + is_disabled (Char const* warning) + { + return disabled_warnings_all_ || + (disabled_warnings_ && + disabled_warnings_->find (warning) != disabled_warnings_->end ()); + } + + private: + Boolean + more () const + { + Iterator const& it (iteration_state_.top ()); + + return it.l_->getLength () > it.i_; + } + + XML::Element + next () + { + Iterator& it (iteration_state_.top ()); + + return XML::Element ( + dynamic_cast (it.l_->item (it.i_++))); + } + + Void + prev () + { + Iterator& it (iteration_state_.top ()); + + if (it.i_) + --it.i_; + } + + Void + push (XML::Element const& e) + { + iteration_state_.push (e.dom_element ()); + } + + Void + pop () + { + iteration_state_.pop (); + } + + private: + Void + push_scope (SemanticGraph::Scope& s) + { + scope_stack_.push (&s); + } + + Void + pop_scope () + { + scope_stack_.pop (); + } + + SemanticGraph::Scope& + scope () const + { + return *(scope_stack_.top ()); + } + + private: + Void + push_compositor (SemanticGraph::Compositor& c) + { + compositor_stack_.push (&c); + } + + Void + pop_compositor () + { + assert (!compositor_stack_.empty ()); + compositor_stack_.pop (); + } + + SemanticGraph::Compositor& + compositor () const + { + assert (!compositor_stack_.empty ()); + return *(compositor_stack_.top ()); + } + + private: + UnsignedLong + parse_min (String const& m) + { + if (m.empty ()) + return 1; + + UnsignedLong v; + std::basic_istringstream is (m); + + is >> v; + return v; + } + + UnsignedLong + parse_max (String const& m) + { + if (m.empty ()) + return 1; + + if (m == L"unbounded") + return 0; + + UnsignedLong v; + std::basic_istringstream is (m); + + is >> v; + return v; + } + + private: + SemanticGraph::Namespace& + cur_ns () const + { + // Here I am using the fact that each Schema Names only one + // Namespace. + // + return dynamic_cast (cur_->names_begin ()->named ()); + } + + private: + String + unqualified_name (String const& n) + { + return XML::uq_name (n); + } + + String + namespace_name (XML::Element const& e, String const& n) + { + try + { + String p (XML::prefix (n)); + + // If we are currently handling a chameleon-included schema then + // the empty prefix is logically translated into acquired target + // namespace. + // + if (cur_chameleon_ && p.empty ()) + return cur_ns ().name (); + + // We have to try to resolve even the empty prefix since it can + // be assigned to a namespace (which takes precedence over names + // without a namespace). + // + return XML::ns_name (e.dom_element (), p); + } + catch (XML::NoMapping const& ex) + { + if (ex.prefix ().empty ()) + return String (); + else + throw; + } + } + + SemanticGraph::Type& + ultimate_base (SemanticGraph::Type& t) + { + using namespace SemanticGraph; + + Complex* c = dynamic_cast (&t); + + if (c != 0 && c->inherits_p ()) + { + Type* b (&c->inherits ().base ()); + + while (true) + { + Complex* cb (dynamic_cast (b)); + + if (cb != 0 && cb->inherits_p ()) + { + b = &cb->inherits ().base (); + continue; + } + + break; + } + + return *b; + } + else + return t; + } + + private: + template + Edge* + set_type (String const& type, XML::Element const& e, Node& node); + + private: + XML::PtrVector* dom_docs_; + + struct Iterator + { + Iterator (Xerces::DOMElement* e) + : l_ (e->getChildNodes ()), i_ (0) + { + } + + Xerces::DOMNodeList* l_; + Size i_; + }; + + Cult::Containers::Stack iteration_state_; + SemanticGraph::Schema* s_; // root schema file + SemanticGraph::Schema* cur_; // current schema file + Boolean cur_chameleon_; // whethere cur_ is chameleon + + SemanticGraph::Schema* xml_schema_; // XML Schema file + SemanticGraph::Path xml_schema_path_; + + // + // + Cult::Containers::Stack scope_stack_; + + // + // + Cult::Containers::Stack compositor_stack_; + + + // Map of absolute file path and namespace pair to a Schema node. + // + struct SchemaId + { + SchemaId (SemanticGraph::Path const& path, String const& ns) + : path_ (path), ns_ (ns) + { + } + + + friend Boolean + operator< (SchemaId const& x, SchemaId const& y) + { +#if !defined(BOOST_FILESYSTEM_VERSION) || BOOST_FILESYSTEM_VERSION == 2 + return x.path_.native_file_string () < y.path_.native_file_string () + || (x.path_.native_file_string () == y.path_.native_file_string () + && x.ns_ < y.ns_); +#else + return x.path_.string () < y.path_.string () + || (x.path_.string () == y.path_.string () + && x.ns_ < y.ns_); +#endif + } + + private: + SemanticGraph::Path path_; + String ns_; + }; + + + typedef + Cult::Containers::Map + SchemaMap; + + SchemaMap schema_map_; + + // Path stack for diagnostic. + // + Cult::Containers::Stack file_stack_; + + SemanticGraph::Path const& + file () + { + return file_stack_.top (); + } + + // Members with default/fixed values (needed for QName handling). + // + DefaultValues default_values_; + + private: + Boolean qualify_attribute_; + Boolean qualify_element_; + + Boolean valid_; + + Boolean proper_restriction_; + Boolean multiple_imports_; + Boolean full_schema_check_; + LocationTranslator* loc_translator_; + const WarningSet* disabled_warnings_; + Boolean disabled_warnings_all_; + + NamespaceMap* cache_; + }; + + + Parser::Impl:: + Impl (Boolean proper_restriction, + Boolean multiple_imports, + Boolean full_schema_check, + LocationTranslator* t, + const WarningSet* dw) + : s_ (0), + cur_ (0), + cur_chameleon_ (false), + xml_schema_path_ ("XMLSchema.xsd"), + qualify_attribute_ (false), + qualify_element_ (false), + proper_restriction_ (proper_restriction), + multiple_imports_ (multiple_imports), + full_schema_check_ (full_schema_check), + loc_translator_ (t), + disabled_warnings_ (dw), + disabled_warnings_all_ (false) + { + if (dw && dw->find ("all") != dw->end ()) + disabled_warnings_all_ = true; + + // Initialize the Xerces-C++ runtime. + // + Xerces::XMLPlatformUtils::Initialize (); + } + + Parser::Impl:: + ~Impl () + { + // Terminate the Xerces-C++ runtime. + // + Xerces::XMLPlatformUtils::Terminate (); + } + + template T& + add_type (Schema& s, Namespace& ns, String name) + { + Path path ("XMLSchema.xsd"); + T& node (s.new_node (path, 0, 0)); + s.new_edge (ns, node, name); + + return node; + } + + Void Parser::Impl:: + fill_xml_schema (Schema& s, Path const& path) + { + Namespace& ns (s.new_node (path, 1, 1)); + s.new_edge (s, ns, xsd); + + // anyType and & anySimpleType + // + AnyType& any_type ( + add_type (s, ns, L"anyType")); + add_type (s, ns, L"anySimpleType"); + + // Integers. + // + add_type (s, ns, L"byte"); + add_type (s, ns, L"unsignedByte"); + add_type (s, ns, L"short"); + add_type (s, ns, L"unsignedShort"); + add_type (s, ns, L"int"); + add_type (s, ns, L"unsignedInt"); + add_type (s, ns, L"long"); + add_type (s, ns, L"unsignedLong"); + add_type (s, ns, L"integer"); + add_type (s, ns, L"nonPositiveInteger"); + add_type (s, ns, L"nonNegativeInteger"); + add_type (s, ns, L"positiveInteger"); + add_type (s, ns, L"negativeInteger"); + + // Boolean. + // + add_type (s, ns, L"boolean"); + + // Floats. + // + add_type (s, ns, L"float"); + add_type (s, ns, L"double"); + add_type (s, ns, L"decimal"); + + // Strings + // + add_type (s, ns, L"string"); + add_type (s, ns, L"normalizedString"); + add_type (s, ns, L"token"); + add_type (s, ns, L"Name"); + add_type (s, ns, L"NMTOKEN"); + add_type (s, ns, L"NMTOKENS"); + add_type (s, ns, L"NCName"); + add_type (s, ns, L"language"); + + // ID/IDREF. + // + add_type (s, ns, L"ID"); + + Fundamental::IdRef& id_ref ( + s.new_node (path, 0, 0)); + s.new_edge (ns, id_ref, L"IDREF"); + s.new_edge (any_type, id_ref); + + Fundamental::IdRefs& id_refs ( + s.new_node (path, 0, 0)); + s.new_edge (ns, id_refs, L"IDREFS"); + s.new_edge (any_type, id_refs); + + // URI. + // + add_type (s, ns, L"anyURI"); + + // Qualified name. + // + add_type (s, ns, L"QName"); + + // Binary. + // + add_type (s, ns, L"base64Binary"); + add_type (s, ns, L"hexBinary"); + + // Date/time. + // + add_type (s, ns, L"date"); + add_type (s, ns, L"dateTime"); + add_type (s, ns, L"duration"); + add_type (s, ns, L"gDay"); + add_type (s, ns, L"gMonth"); + add_type (s, ns, L"gMonthDay"); + add_type (s, ns, L"gYear"); + add_type (s, ns, L"gYearMonth"); + add_type (s, ns, L"time"); + + // Entity. + // + add_type (s, ns, L"ENTITY"); + add_type (s, ns, L"ENTITIES"); + + // Notation. + // + add_type (s, ns, L"NOTATION"); + } + + + Evptr Parser::Impl:: + xml_schema (Path const& tu) + { + valid_ = true; + + Evptr rs (new Schema (tu, 1, 1)); + fill_xml_schema (*rs, tu); + + if (!valid_) + throw InvalidSchema (); + + return rs; + } + Evptr Parser::Impl:: + parse (Path const& tu) + { + valid_ = true; + schema_map_.clear (); + default_values_.clear (); + + XML::PtrVector dom_docs; + dom_docs_ = &dom_docs; + + NamespaceMap cache; + cache_ = &cache; + + XML::AutoPtr d (dom (tu, true)); + + if (!d) + throw InvalidSchema (); + + XML::Element root (d->getDocumentElement ()); + String ns (root["targetNamespace"]); + + if (trace_) + wcout << "target namespace: " << ns << endl; + + Evptr rs (new Schema (tu, root.line (), root.column ())); + + // Implied schema with fundamental types. + // + xml_schema_ = &rs->new_node (xml_schema_path_, 1, 1); + rs->new_edge (*rs, *xml_schema_, xml_schema_path_); + + fill_xml_schema (*xml_schema_, xml_schema_path_); + + // Parse. + // + { + // Enter the file into schema_map_. + // + Path abs_path (system_complete (tu)); + abs_path.normalize (); + schema_map_[SchemaId (abs_path, ns)] = rs.get (); + rs->context ().set ("absolute-path", abs_path); + + s_ = cur_ = rs.get (); + { + file_stack_.push (tu); + + { + push_scope ( + s_->new_node ( + file (), root.line (), root.column ())); + s_->new_edge (*cur_, scope (), ns); + + { + schema (root); + } + + pop_scope (); + } + + file_stack_.pop (); + } + + s_ = cur_ = 0; + } + + dom_docs_->push_back (d); + + // Second pass to resolve forward references to types, elements, + // attributes and groups. + // + if (valid_) + { + Traversal::Schema schema; + + struct Uses: Traversal::Uses + { + virtual Void + traverse (Type& u) + { + Schema& s (u.schema ()); + + if (!s.context ().count ("schema-resolved")) + { + s.context ().set ("schema-resolved", true); + Traversal::Uses::traverse (u); + } + } + } uses; + + Traversal::Names schema_names; + Traversal::Namespace ns; + Traversal::Names ns_names; + + schema >> uses >> schema; + schema >> schema_names >> ns >> ns_names; + + Resolver resolver (*rs, valid_, *cache_, default_values_); + + struct AnonymousMember: Traversal::Attribute, + Traversal::Element, + Traversal::Member + { + AnonymousMember (Traversal::NodeDispatcherBase& d) + { + belongs_.node_traverser (d); + } + + virtual Void + traverse (SemanticGraph::Attribute& a) + { + traverse_member (a); + } + + virtual Void + traverse (SemanticGraph::Element& e) + { + traverse_member (e); + } + + Void + traverse_member (SemanticGraph::Member& m) + { + if (m.typed_p () && + !m.type ().named_p () && + !m.type ().context ().count ("seen")) + { + m.type().context ().set ("seen", true); + + Traversal::Member::belongs (m, belongs_); + + m.type ().context ().remove ("seen"); + } + } + + private: + Traversal::Belongs belongs_; + } anonymous_member (resolver); + + struct AnonymousBase: Traversal::Type + { + AnonymousBase (Traversal::NodeDispatcherBase& d) + : base_ (d) + { + } + + virtual Void + traverse (SemanticGraph::Type& t) + { + if (!t.named_p ()) + base_.dispatch (t); + } + + private: + Traversal::NodeDispatcherBase& base_; + } anonymous_base (resolver); + + ns_names >> resolver; + ns_names >> anonymous_member; + + Traversal::Names names; + Traversal::Inherits inherits; + Traversal::Argumented argumented; + resolver >> names >> resolver; + names >> anonymous_member; + resolver >> inherits >> anonymous_base; + resolver >> argumented >> anonymous_base; + + if (trace_) + wcout << "starting resolution pass" << endl; + + schema.dispatch (*rs); + } + + // Resolve default/fixed values of QName type. + // + if (valid_) + { + for (DefaultValues::ConstIterator i (default_values_.begin ()), + e (default_values_.end ()); i != e; ++i) + { + SemanticGraph::Member& m (**i); + SemanticGraph::Type& t (m.type ()); + SemanticGraph::Context& c (m.context ()); + + if (ultimate_base (t).is_a ()) + { + String v (m.value ()); + Xerces::DOMElement* e (c.get ("dom-node")); + + try + { + // We have to try to resolve even the empty prefix since it can + // be assigned to a namespace (which takes precedence over names + // without a namespace). + // + String ns (XML::ns_name (e, XML::prefix (v))); + + if (m.fixed_p ()) + m.fixed (ns + L'#' + v); + else + m.default_ (ns + L'#' + v); + } + catch (XML::NoMapping const& ex) + { + if (!ex.prefix ().empty ()) + { + wcerr << m.file () << ":" << m.line () << ":" << m.column () + << ": error: unable to resolve namespace for prefix '" + << ex.prefix () << "'" << endl; + + valid_ = false; + } + } + } + + c.remove ("dom-node"); + } + } + + if (!valid_) + throw InvalidSchema (); + + return rs; + } + + Evptr Parser::Impl:: + parse (Paths const& paths) + { + valid_ = true; + schema_map_.clear (); + default_values_.clear (); + + XML::PtrVector dom_docs; + dom_docs_ = &dom_docs; + + NamespaceMap cache; + cache_ = &cache; + + Evptr rs (new Schema ("", 0, 0)); + + // Implied schema with fundamental types. + // + xml_schema_ = &rs->new_node (xml_schema_path_, 1, 1); + rs->new_edge (*rs, *xml_schema_, xml_schema_path_); + + fill_xml_schema (*xml_schema_, xml_schema_path_); + + // Parse individual schemas. + // + s_ = rs.get (); + + for (Paths::ConstIterator i (paths.begin ()); i != paths.end (); ++i) + { + Path const& tu (*i); + XML::AutoPtr d (dom (tu, true)); + + if (!d) + throw InvalidSchema (); + + XML::Element root (d->getDocumentElement ()); + String ns (root["targetNamespace"]); + + if (trace_) + wcout << "target namespace: " << ns << endl; + + // Check if we already have this schema. + // + Path abs_path (system_complete (tu)); + abs_path.normalize (); + SchemaId schema_id (abs_path, ns); + + if (schema_map_.find (schema_id) != schema_map_.end ()) + continue; + + Schema& s (s_->new_node (tu, root.line (), root.column ())); + s_->new_edge (s, *xml_schema_, xml_schema_path_); + s_->new_edge (*s_, s, tu); + + // Enter the file into schema_map_. + // + schema_map_[schema_id] = &s; + s.context ().set ("absolute-path", abs_path); + + cur_ = &s; + + { + file_stack_.push (tu); + + { + push_scope ( + s_->new_node ( + file (), root.line (), root.column ())); + s_->new_edge (*cur_, scope (), ns); + + { + schema (root); + } + + pop_scope (); + } + + file_stack_.pop (); + } + + cur_ = 0; + + dom_docs_->push_back (d); + + if (!valid_) + break; + } + + s_ = 0; + + // Second pass to resolve forward references to types, elements, + // attributes and groups. + // + if (valid_) + { + Traversal::Schema schema; + + struct Uses: Traversal::Uses + { + virtual Void + traverse (Type& u) + { + Schema& s (u.schema ()); + + if (!s.context ().count ("schema-resolved")) + { + s.context ().set ("schema-resolved", true); + Traversal::Uses::traverse (u); + } + } + } uses; + + Traversal::Names schema_names; + Traversal::Namespace ns; + Traversal::Names ns_names; + + schema >> uses >> schema; + schema >> schema_names >> ns >> ns_names; + + Resolver resolver (*rs, valid_, *cache_, default_values_); + + struct AnonymousMember: Traversal::Attribute, + Traversal::Element, + Traversal::Member + { + AnonymousMember (Traversal::NodeDispatcherBase& d) + { + belongs_.node_traverser (d); + } + + virtual Void + traverse (SemanticGraph::Attribute& a) + { + traverse_member (a); + } + + virtual Void + traverse (SemanticGraph::Element& e) + { + traverse_member (e); + } + + virtual Void + traverse_member (SemanticGraph::Member& m) + { + if (m.typed_p () && + !m.type ().named_p () && + !m.type ().context ().count ("seen")) + { + m.type().context ().set ("seen", true); + + Traversal::Member::belongs (m, belongs_); + + m.type ().context ().remove ("seen"); + } + } + + private: + Traversal::Belongs belongs_; + } anonymous_member (resolver); + + struct AnonymousBase: Traversal::Type + { + AnonymousBase (Traversal::NodeDispatcherBase& d) + : base_ (d) + { + } + + virtual Void + traverse (SemanticGraph::Type& t) + { + if (!t.named_p ()) + base_.dispatch (t); + } + + private: + Traversal::NodeDispatcherBase& base_; + } anonymous_base (resolver); + + ns_names >> resolver; + ns_names >> anonymous_member; + + Traversal::Names names; + Traversal::Inherits inherits; + Traversal::Argumented argumented; + resolver >> names >> resolver; + names >> anonymous_member; + resolver >> inherits >> anonymous_base; + resolver >> argumented >> anonymous_base; + + if (trace_) + wcout << "starting resolution pass" << endl; + + schema.dispatch (*rs); + } + + // Resolve default/fixed values of QName type. + // + if (valid_) + { + for (DefaultValues::ConstIterator i (default_values_.begin ()), + e (default_values_.end ()); i != e; ++i) + { + SemanticGraph::Member& m (**i); + SemanticGraph::Type& t (m.type ()); + SemanticGraph::Context& c (m.context ()); + + if (ultimate_base (t).is_a ()) + { + String v (m.value ()); + Xerces::DOMElement* e (c.get ("dom-node")); + + try + { + // We have to try to resolve even the empty prefix since it can + // be assigned to a namespace (which takes precedence over names + // without a namespace). + // + String ns (XML::ns_name (e, XML::prefix (v))); + + if (m.fixed_p ()) + m.fixed (ns + L'#' + v); + else + m.default_ (ns + L'#' + v); + } + catch (XML::NoMapping const& ex) + { + if (!ex.prefix ().empty ()) + { + wcerr << m.file () << ":" << m.line () << ":" << m.column () + << ": error: unable to resolve namespace for prefix '" + << ex.prefix () << "'" << endl; + + valid_ = false; + } + } + } + + c.remove ("dom-node"); + } + } + + if (!valid_) + throw InvalidSchema (); + + return rs; + } + + Void Parser::Impl:: + schema (XML::Element const& s) + { + Boolean old_qa (qualify_attribute_); + Boolean old_qe (qualify_element_); + + if (String af = s["attributeFormDefault"]) + qualify_attribute_ = af == L"qualified"; + + if (String ef = s["elementFormDefault"]) + qualify_element_ = ef == L"qualified"; + + push (s); + + // Parse leading annotation if any and add it as an annotation for + // this schema. + // + if (Annotation* a = annotation (true)) + s_->new_edge (*a, *cur_); + + while (more ()) + { + XML::Element e (next ()); + String name (e.name ()); + + if (trace_) + wcout << name << endl; + + if (name == L"import") import (e); else + if (name == L"include") include (e); else + if (name == L"element") element (e, true); else + if (name == L"attribute") attribute (e, true); else + if (name == L"simpleType") simple_type (e); else + if (name == L"annotation"); else + if (name == L"complexType") complex_type (e); else + if (name == L"group") element_group (e, false); else + if (name == L"attributeGroup") attribute_group (e); else + { + wcerr << file () << ":" << e.line () << ":" << e.column () << ": " + << "error: unexpected top-level element: '" << name << "'" + << endl; + + valid_ = false; + } + } + + pop (); + + qualify_attribute_ = old_qa; + qualify_element_ = old_qe; + } + + Void Parser::Impl:: + import (XML::Element const& i) + { + NarrowString loc ( + XML::transcode_to_narrow ( + i.dom_element ()->getAttribute ( + XML::XMLChString ("schemaLocation").c_str ()))); + + if (loc_translator_) + loc = loc_translator_->translate (loc); + + // Ignore empty . + // + if (!loc && !i["namespace"]) + return; + + Path path, rel_path, abs_path; + try + { +#if !defined(BOOST_FILESYSTEM_VERSION) || BOOST_FILESYSTEM_VERSION == 2 + try + { + path = Path (loc); + } + catch (InvalidPath const&) + { + // Retry as a native path. + // + path = Path (loc, boost::filesystem::native); + } +#else + // The new ABI does not have a fallback native representation + path = Path (loc.c_str()); +#endif + + if (path.is_complete ()) + { + abs_path = rel_path = path; + } + else + { + rel_path = file ().branch_path () / path; + abs_path = system_complete (rel_path); + } + + abs_path.normalize (); + } + catch (InvalidPath const&) + { + wcerr << file () << ":" << i.line () << ":" << i.column () << ": " + << "error: '" << loc.c_str () << "' is not a valid " + << "filesystem path" << endl; + + valid_ = false; + return; + } + + SchemaId schema_id (abs_path, i["namespace"]); + + if (schema_map_.find (schema_id) != schema_map_.end ()) + { + s_->new_edge (*cur_, *schema_map_[schema_id], path); + return; + } + + if (trace_) + wcout << "importing " << rel_path << endl; + + if (XML::AutoPtr d = dom (abs_path, false)) + { + XML::Element r (d->getDocumentElement ()); + String ns (r["targetNamespace"]); + + if (trace_) + wcout << "target namespace: " << ns << endl; + + Schema& s (s_->new_node (rel_path, r.line (), r.column ())); + s_->new_edge (s, *xml_schema_, xml_schema_path_); + s_->new_edge (*cur_, s, path); + + schema_map_[schema_id] = &s; + s.context ().set ("absolute-path", abs_path); + + Schema* old_cur (cur_); + Boolean old_cur_chameleon (cur_chameleon_); + cur_ = &s; + cur_chameleon_ = false; + + { + file_stack_.push (rel_path); + + { + push_scope ( + s_->new_node (file (), r.line (), r.column ())); + s_->new_edge (*cur_, scope (), ns); + + { + schema (r); + } + + pop_scope (); + } + + file_stack_.pop (); + } + + cur_chameleon_ = old_cur_chameleon; + cur_ = old_cur; + + dom_docs_->push_back (d); + } + } + + Void Parser::Impl:: + include (XML::Element const& i) + { + NarrowString loc ( + XML::transcode_to_narrow ( + i.dom_element ()->getAttribute ( + XML::XMLChString ("schemaLocation").c_str ()))); + + if (loc_translator_) + loc = loc_translator_->translate (loc); + + Path path, rel_path, abs_path; + try + { +#if !defined(BOOST_FILESYSTEM_VERSION) || BOOST_FILESYSTEM_VERSION == 2 + try + { + path = Path (loc); + } + catch (InvalidPath const&) + { + // Retry as a native path. + // + path = Path (loc, boost::filesystem::native); + } +#else + // The new API does not have a fallback native representation. + path = Path (loc.c_str()); +#endif + + if (path.is_complete ()) + { + abs_path = rel_path = path; + } + else + { + rel_path = file ().branch_path () / path; + abs_path = system_complete (rel_path); + } + + abs_path.normalize (); + } + catch (InvalidPath const&) + { + wcerr << file () << ":" << i.line () << ":" << i.column () << ": " + << "error: '" << loc.c_str () << "' is not a valid " + << "filesystem path" << endl; + + valid_ = false; + return; + } + + // Included schema should have the same namespace as ours. + // + SchemaId schema_id (abs_path, cur_ns ().name ()); + + if (schema_map_.find (schema_id) != schema_map_.end ()) + { + Schema& s (*schema_map_[schema_id]); + + // Chemeleon inclusion results in a new Schema node for every + // namespace. As a result, such a Schema node can only be + // Source'ed. I use this property to decide which edge to use. + // + + if (s.used_p () && s.used_begin ()->is_a ()) + s_->new_edge (*cur_, s, path); + else + s_->new_edge (*cur_, s, path); + + return; + } + + if (trace_) + wcout << "including " << rel_path << endl; + + if (XML::AutoPtr d = dom (abs_path, false)) + { + XML::Element r (d->getDocumentElement ()); + String ns (r["targetNamespace"]), cur_ns; + + Schema& s (s_->new_node (rel_path, r.line (), r.column ())); + s_->new_edge (s, *xml_schema_, xml_schema_path_); + + schema_map_[schema_id] = &s; + s.context ().set ("absolute-path", abs_path); + + Boolean chameleon (false); + + if (ns.empty () && !(cur_ns = (cur_->names_begin ())->name ()).empty ()) + { + // Chameleon. + // + ns = cur_ns; + s_->new_edge (*cur_, s, path); + chameleon = true; + + if (trace_) + wcout << "handling chameleon schema" << endl; + } + else + s_->new_edge (*cur_, s, path); + + if (trace_) + wcout << "target namespace: " << ns << endl; + + Schema* old_cur (cur_); + Boolean old_cur_chameleon (cur_chameleon_); + cur_ = &s; + cur_chameleon_ = chameleon; + + { + file_stack_.push (rel_path); + + { + push_scope ( + s_->new_node (file (), r.line (), r.column ())); + s_->new_edge (*cur_, scope (), ns); + + { + schema (r); + } + + pop_scope (); + } + + file_stack_.pop (); + } + + cur_chameleon_ = old_cur_chameleon; + cur_ = old_cur; + + dom_docs_->push_back (d); + } + } + + Void Parser::Impl:: + element_group (XML::Element const& g, Boolean in_compositor) + { + if (String name = g["name"]) + { + ElementGroup& group ( + s_->new_node (file (), g.line (), g.column ())); + + s_->new_edge (scope (), group, name); + + push_scope (group); + push (g); + + annotation (false); + + XML::Element e (next ()); + + name = e.name (); + + if (trace_) + wcout << name << endl; + + Compositor* c (0); + + if (name == L"all") c = all (e); else + if (name == L"choice") c = choice (e, false); else + if (name == L"sequence") c = sequence (e, false); else + { + wcerr << file () << ":" << e.line () << ":" << e.column () << ": " + << "error: expected 'all', 'choice' or 'sequence' " + << "instead of '" << name << "'" << endl; + + valid_ = false; + } + + // Group's immediate compositor always has cardinality 1,1. + // + if (c) + s_->new_edge (group, *c, 1, 1); + + pop (); + pop_scope (); + } + else if (String ref = g["ref"]) + { + if (trace_) + wcout << "element-group-ref " << ref << endl; + + try + { + String uq_name (unqualified_name (ref)); + String ns_name (namespace_name (g, ref)); + + // In order to avoid code duplication we are going to let the + // resolver handle this case. + // + if (trace_) + wcout << "deferring resolution of group name '" << uq_name + << "' inside namespace '" << ns_name << "'" + << " until later" << endl; + + if (in_compositor) + { + Compositor& c (compositor ()); + + ElementGroupRef ref ( + uq_name, ns_name, + parse_min (g["minOccurs"]), parse_max (g["maxOccurs"]), + c, scope ()); + + if (!c.context ().count ("element-group-refs")) + c.context ().set ("element-group-refs", ElementGroupRefs ()); + + c.context ().get ( + "element-group-refs").push_back (ref); + } + else + { + // This is a group-ref directly in complexType. + // + + Scope& s (scope ()); + + ElementGroupRef ref ( + uq_name, ns_name, + parse_min (g["minOccurs"]), parse_max (g["maxOccurs"]), + s); + + s.context ().set ("element-group-ref", ref); + } + } + catch (NotNamespace const& ex) + { + if (valid_) + { + wcerr << file () << ":" << g.line () << ":" << g.column () << ": " + << "ice: unable to resolve namespace '" << ex.ns () << "'" + << endl; + + abort (); + } + } + catch (XML::NoMapping const& ex) + { + wcerr << file () << ":" << g.line () << ":" << g.column () << ": " + << "error: unable to resolve namespace prefix '" << ex.prefix () + << "' in '" << ref << "'" << endl; + + valid_ = false; + } + } + else + { + wcerr << file () << ":" << g.line () << ":" << g.column () << ": " + << "error: 'name' or 'ref' attribute is missing in group " + << "declaration" << endl; + + valid_ = false; + + return; + } + } + + //@@ Need RAII for push/pop. + // + + Type* Parser::Impl:: + simple_type (XML::Element const& t) + { + Type* r (0); + + push (t); + + Annotation* a (annotation (true)); + + XML::Element e (next ()); + + String name (e.name ()); + + if (name == L"list") r = list (e, t); else + if (name == L"union") r = union_ (e, t); else + if (name == L"restriction") r = restriction (e, t); else + { + wcerr << file () << ":" << e.line () << ":" << e.column () << ": " + << "error: expected 'list', 'union', or 'restriction' " + << "instead of '" << name << "'" << endl; + + valid_ = false; + } + + if (r != 0 && a != 0) + s_->new_edge (*a, *r); + + pop (); + + return r; + } + + SemanticGraph::Type* Parser::Impl:: + list (XML::Element const& l, XML::Element const& t) + { + if (trace_) + wcout << "list" << endl; + + List& node (s_->new_node (file (), t.line (), t.column ())); + + if (String item_type = l["itemType"]) + { + if (trace_) + wcout << "item type: " << fq_name (l, item_type) << endl; + + set_type (item_type, l, node); + } + else + { + // Anonymous list item type. + // + push (l); + + annotation (false); + + if (more ()) + { + XML::Element e (next ()); + + String name (e.name ()); + + if (trace_) + wcout << name << endl; + + Type* t (0); + + if (name == L"simpleType") t = simple_type (e); else + { + wcerr << file () << ":" << e.line () << ":" << e.column () << ": " + << "error: expected 'simpleType' instead of " + << "'" << e.name () << "'" << endl; + + valid_ = false; + } + + if (t) + s_->new_edge (*t, node); + } + else + { + wcerr << file () << ":" << l.line () << ":" << l.column () << ": " + << "error: expected 'itemType' attribute or 'simpleType' " + << "nested element" << endl; + + valid_ = false; + } + + pop (); + } + + if (String name = t["name"]) + s_->new_edge (scope (), node, name); + + return &node; + } + + namespace + { + // + // List parsing utility functions. + // + + // Find first non-space character. + // + Size + find_ns (const WideChar* s, Size size, Size pos) + { + while (pos < size && + (s[pos] == 0x20 || // space + s[pos] == 0x0D || // carriage return + s[pos] == 0x09 || // tab + s[pos] == 0x0A)) + ++pos; + + return pos < size ? pos : String::npos; + } + + // Find first space character. + // + Size + find_s (const WideChar* s, Size size, Size pos) + { + while (pos < size && + s[pos] != 0x20 && // space + s[pos] != 0x0D && // carriage return + s[pos] != 0x09 && // tab + s[pos] != 0x0A) + ++pos; + + return pos < size ? pos : String::npos; + } + } + + SemanticGraph::Type* Parser::Impl:: + union_ (XML::Element const& u, XML::Element const& t) + { + if (trace_) + wcout << "union" << endl; + + Union& node (s_->new_node (file (), t.line (), t.column ())); + + Boolean has_members (false); + + if (String members = u["memberTypes"]) + { + // Don't bother trying to resolve member types at this point + // since the order is important so we would have to insert + // the late resolutions into specific places. It is simpler + // to just do the whole resolution later. + // + const WideChar* data (members.c_str ()); + Size size (members.size ()); + + UnionMemberTypes* m (0); + + // Traverse the type list while logically collapsing spaces. + // + for (Size i (find_ns (data, size, 0)); i != String::npos;) + { + String s; + Size j (find_s (data, size, i)); + + if (j != String::npos) + { + s = String (data + i, j - i); + i = find_ns (data, size, j); + } + else + { + // Last item. + // + s = String (data + i, size - i); + i = String::npos; + } + + if (trace_) + wcout << "member type: " << fq_name (u, s) << endl; + + if (m == 0) + { + node.context ().set ("union-member-types", UnionMemberTypes ()); + m = &node.context ().get ("union-member-types"); + } + + try + { + m->push_back ( + UnionMemberType ( + namespace_name (u, s), unqualified_name (s))); + } + catch (XML::NoMapping const& ex) + { + wcerr << file () << ":" << u.line () << ":" << u.column () << ": " + << "error: unable to resolve namespace prefix " + << "'" << ex.prefix () << "' in '" << s << "'" << endl; + + valid_ = false; + } + } + + has_members = (m != 0); + } + + // Handle anonymous members. + // + push (u); + + annotation (false); + + while (more ()) + { + XML::Element e (next ()); + String name (e.name ()); + + if (trace_) + wcout << name << endl; + + Type* t (0); + + if (name == L"simpleType") t = simple_type (e); else + { + wcerr << file () << ":" << e.line () << ":" << e.column () << ": " + << "error: expected 'simpleType' instead of " + << "'" << e.name () << "'" << endl; + + valid_ = false; + } + + if (t) + s_->new_edge (*t, node); + } + + pop (); + + if (node.argumented_begin () == node.argumented_end () && !has_members) + { + wcerr << file () << ":" << u.line () << ":" << u.column () << ": " + << "error: expected 'memberTypes' attribute or 'simpleType' " + << "nested element" << endl; + + valid_ = false; + } + + if (String name = t["name"]) + s_->new_edge (scope (), node, name); + + return &node; + } + + Type* Parser::Impl:: + restriction (XML::Element const& r, XML::Element const& t) + { + String base (r["base"]); + Type* base_type (0); + + if (base) + { + if (trace_) + wcout << "restriction base: " << fq_name (r, base) << endl; + } + + Type* rv (0); + + push (r); + + annotation (false); + + Boolean enum_ (false); + + if (!base) + { + // Anonymous base type. + // + if (more ()) + { + XML::Element e (next ()); + + String name (e.name ()); + + if (trace_) + wcout << name << endl; + + if (name == L"simpleType") base_type = simple_type (e); else + { + wcerr << file () << ":" << e.line () << ":" << e.column () << ": " + << "error: expected 'simpleType' instead of " + << "'" << e.name () << "'" << endl; + + valid_ = false; + } + } + else + { + wcerr << file () << ":" << r.line () << ":" << r.column () << ": " + << "error: expected 'base' attribute or 'simpleType' " + << "nested element" << endl; + + valid_ = false; + } + + if (!valid_) + { + pop (); + return 0; + } + } + + Facets facets; + Restricts* restricts (0); + + while (more ()) + { + XML::Element e (next ()); + String name (e.name ()); + + if (name == L"enumeration") + { + // Enumeration + // + if (enum_) + enumeration (e); + else + { + // First + // + enum_ = true; + + Enumeration& node ( + s_->new_node (file (), t.line (), t.column ())); + + if (base_type) + restricts = &s_->new_edge (node, *base_type); + else + restricts = set_type (base, r, node); + + if (String name = t["name"]) + s_->new_edge (scope (), static_cast (node), name); + + rv = &node; + push_scope (node); + enumeration (e); + } + } + else if (name == L"minExclusive" || + name == L"minInclusive" || + name == L"maxExclusive" || + name == L"maxInclusive" || + name == L"totalDigits" || + name == L"fractionDigits" || + name == L"length" || + name == L"minLength" || + name == L"maxLength" || + name == L"whiteSpace" || + name == L"pattern") + { + facets[name] = e["value"]; + } + else + { + wcerr << file () << ":" << e.line () << ":" << e.column () << ": " + << "error: unexpected element '" << name << "' in " + << "simple type restriction" << endl; + + valid_ = false; + } + } + + if (enum_) + pop_scope (); + else + { + Complex& node (s_->new_node (file (), t.line (), t.column ())); + + if (base_type) + restricts = &s_->new_edge (node, *base_type); + else + restricts = set_type (base, r, node); + + if (String name = t["name"]) + s_->new_edge (scope (), node, name); + + rv = &node; + } + + if (!facets.empty ()) + { + if (restricts) + copy_facets (*restricts, facets); + else + rv->context ().set ("facets", facets); + } + + pop (); + + return rv; + } + + Void Parser::Impl:: + enumeration (XML::Element const& e) + { + String value (e["value"]); + + if (trace_) + wcout << "enumeration value: " << value << endl; + + push (e); + Annotation* a (annotation (true)); + pop (); + + Enumerator& node ( + s_->new_node (file (), e.line (), e.column ())); + + s_->new_edge (scope (), node, value); + s_->new_edge (node, dynamic_cast(scope ())); + + if (a != 0) + s_->new_edge (*a, node); + + } + + Type* Parser::Impl:: + complex_type (XML::Element const& t) + { + Type* r (0); + + Complex& node (s_->new_node (file (), t.line (), t.column ())); + + node.mixed_p (t["mixed"] == L"true" || t["mixed"] == L"1"); + + if (String name = t["name"]) + s_->new_edge (scope (), node, name); + + r = &node; + + push_scope (node); + push (t); + + if (Annotation* a = annotation (true)) + s_->new_edge (*a, node); + + if (more ()) + { + XML::Element e (next ()); + + String name (e.name ()); + + if (trace_) + wcout << name << endl; + + if (name == L"simpleContent") simple_content (e); else + if (name == L"complexContent") complex_content (e, node); else + { + Compositor* c (0); + + if (name == L"all") c = all (e); else + if (name == L"choice") c = choice (e, false); else + if (name == L"sequence") c = sequence (e, false); else + if (name == L"attribute") attribute (e, false); else + if (name == L"anyAttribute") any_attribute (e); else + if (name == L"group") element_group (e, false); else + if (name == L"attributeGroup") attribute_group (e); else + { + wcerr << file () << ":" << e.line () << ":" << e.column () << ": " + << "error: unexpected element '" << name << "'" << endl; + + valid_ = false; + } + + if (c) + s_->new_edge ( + node, *c, parse_min (e["minOccurs"]), parse_max (e["maxOccurs"])); + + while (more ()) + { + XML::Element e (next ()); + String name (e.name ()); + + if (name == L"attribute") attribute (e, false); else + if (name == L"anyAttribute") any_attribute (e); else + if (name == L"attributeGroup") attribute_group (e); else + { + wcerr << file () << ":" << e.line () << ":" << e.column () << ": " + << "error: expected 'attribute', 'anyAttribute', or " + << "'attributeGroup' instead of '" << name << "'" << endl; + + valid_ = false; + } + } + } + } + + pop (); + pop_scope (); + + return r; + } + + All* Parser::Impl:: + all (XML::Element const& a) + { + // 'all' cannot be nested inside 'choice' or 'sequence', nor + // can it contain any of those. The only valid cardinality + // values for 'all' are min=0,1 and max=1. + // + All& node (s_->new_node (file (), a.line (), a.column ())); + + push_compositor (node); + push (a); + + if (Annotation* a = annotation (true)) + s_->new_edge (*a, node); + + while (more ()) + { + XML::Element e (next ()); + + String name (e.name ()); + + if (name == L"element") element (e, false); else + { + wcerr << file () << ":" << e.line () << ":" << e.column () << ": " + << "error: expected 'element' " + << "instead of '" << name << "'" << endl; + + valid_ = false; + } + } + + pop (); + pop_compositor (); + + return &node; + } + + Choice* Parser::Impl:: + choice (XML::Element const& c, Boolean in_compositor) + { + Choice& node (s_->new_node (file (), c.line (), c.column ())); + + if (in_compositor) + { + s_->new_edge ( + compositor (), node, + parse_min (c["minOccurs"]), parse_max (c["maxOccurs"])); + } + + push_compositor (node); + push (c); + + if (Annotation* a = annotation (true)) + s_->new_edge (*a, node); + + while (more ()) + { + XML::Element e (next ()); + + String name (e.name ()); + + if (name == L"any") any (e); else + if (name == L"choice") choice (e, true); else + if (name == L"element") element (e, false); else + if (name == L"sequence") sequence (e, true); else + if (name == L"group") element_group (e, true); else + { + wcerr << file () << ":" << e.line () << ":" << e.column () << ": " + << "error: expected 'any', 'group', 'choice', 'sequence', " + << "or 'element' instead of '" << name << "'" << endl; + + valid_ = false; + } + } + + pop (); + pop_compositor (); + + return &node; + } + + Sequence* Parser::Impl:: + sequence (XML::Element const& s, Boolean in_compositor) + { + Sequence& node (s_->new_node (file (), s.line (), s.column ())); + + if (in_compositor) + { + s_->new_edge ( + compositor (), node, + parse_min (s["minOccurs"]), parse_max (s["maxOccurs"])); + } + + push_compositor (node); + push (s); + + if (Annotation* a = annotation (true)) + s_->new_edge (*a, node); + + while (more ()) + { + XML::Element e (next ()); + + String name (e.name ()); + + if (name == L"any") any (e); else + if (name == L"choice") choice (e, true); else + if (name == L"element") element (e, false); else + if (name == L"sequence") sequence (e, true); else + if (name == L"group") element_group (e, true); else + { + wcerr << file () << ":" << e.line () << ":" << e.column () << ": " + << "error: expected 'any', 'group', 'choice', 'sequence', " + << "or 'element' instead of '" << name << "'" << endl; + + valid_ = false; + } + } + + pop (); + pop_compositor (); + + return &node; + } + + Void Parser::Impl:: + simple_content (XML::Element const& c) + { + push (c); + + annotation (false); + + XML::Element e (next ()); + String name (e.name ()); + + if (name == L"extension") simple_content_extension (e); else + if (name == L"restriction") simple_content_restriction (e); else + { + wcerr << file () << ":" << e.line () << ":" << e.column () << ": " + << "error: expected 'extension' or 'restriction' instead of " + << "'" << name << "'" << endl; + + valid_ = false; + } + + pop (); + } + + Void Parser::Impl:: + complex_content (XML::Element const& c, Complex& type) + { + if (c.attribute_p ("mixed")) + { + type.mixed_p (c["mixed"] == L"true" || c["mixed"] == L"1"); + } + + push (c); + + annotation (false); + + XML::Element e (next ()); + String name (e.name ()); + + if (name == L"extension") complex_content_extension (e, type); else + if (name == L"restriction") complex_content_restriction (e, type); else + { + wcerr << file () << ":" << e.line () << ":" << e.column () << ": " + << "error: expected 'extension' or 'restriction' instead of " + << "'" << name << "'" << endl; + + valid_ = false; + } + + pop (); + } + + Void Parser::Impl:: + simple_content_extension (XML::Element const& e) + { + if (trace_) + wcout << "extension base: " << fq_name (e, e["base"]) << endl; + + set_type (e["base"], e, dynamic_cast (scope ())); + + push (e); + + annotation (false); + + while (more ()) + { + XML::Element e (next ()); + String name (e.name ()); + + if (name == L"attribute") attribute (e, false); else + if (name == L"anyAttribute") any_attribute (e); else + if (name == L"attributeGroup") attribute_group (e); else + { + wcerr << file () << ":" << e.line () << ":" << e.column () << ": " + << "error: expected 'attribute', 'anyAttribute', or " + << "'attributeGroup' instead of '" << name << "'" << endl; + + valid_ = false; + } + } + + pop (); + } + + Void Parser::Impl:: + simple_content_restriction (XML::Element const& r) + { + String base (r["base"]); + Type* base_type (0); + + if (trace_ && base) + wcout << "restriction base: " << fq_name (r, base) << endl; + + push (r); + annotation (false); + + if (!base) + { + // Anonymous base type. + // + if (more ()) + { + XML::Element e (next ()); + String name (e.name ()); + + if (trace_) + wcout << name << endl; + + if (name == L"simpleType") base_type = simple_type (e); else + { + wcerr << file () << ":" << e.line () << ":" << e.column () << ": " + << "error: expected 'simpleType' instead of " + << "'" << e.name () << "'" << endl; + + valid_ = false; + } + } + else + { + wcerr << file () << ":" << r.line () << ":" << r.column () << ": " + << "error: expected 'base' attribute or 'simpleType' " + << "nested element" << endl; + + valid_ = false; + } + + if (!valid_) + { + pop (); + return; + } + } + + Facets facets; + + while (more ()) + { + XML::Element e (next ()); + String name (e.name ()); + + if (name == L"simpleType") + { + // This is a "superimposed" restriction where the base + // content is restricted by specifying another simple + // type. The attributes are restricted in the ussual + // way. So in effect we have kind of two base classes. + // I guess the way to handle this one day would be to + // copy all the facets from the base-to-this-type + // part of the hierarchy (will need to "know" facets + // for the built-in type restrictions as well). For + // now just ignore it. + // + } + else if (name == L"enumeration") + { + // Right now our sementic graph cannot represent enumerations + // with attributes so we are going to ignore enumerators for + // now. + // + } + else if (name == L"minExclusive" || + name == L"minInclusive" || + name == L"maxExclusive" || + name == L"maxInclusive" || + name == L"totalDigits" || + name == L"fractionDigits" || + name == L"length" || + name == L"minLength" || + name == L"maxLength" || + name == L"whiteSpace" || + name == L"pattern") + { + facets[name] = e["value"]; + } + else if (name == L"attribute") + { + if (proper_restriction_) + attribute (e, false); + } + else if (name == L"anyAttribute") + { + if (proper_restriction_) + any_attribute (e); + } + else if (name == L"attributeGroup") + { + if (proper_restriction_) + attribute_group (e); + } + else + { + wcerr << file () << ":" << e.line () << ":" << e.column () << ": " + << "error: unexpected element '" << name << "' in " + << "simple content restriction" << endl; + + valid_ = false; + } + } + + Complex& type (dynamic_cast (scope ())); + Restricts* restricts = set_type (base, r, type); + + if (!facets.empty ()) + { + if (restricts) + copy_facets (*restricts, facets); + else + type.context ().set ("facets", facets); + } + + pop (); + } + + Void Parser::Impl:: + complex_content_extension (XML::Element const& e, Complex& type) + { + if (trace_) + wcout << "extension base: " << fq_name (e, e["base"]) << endl; + + set_type (e["base"], e, dynamic_cast (scope ())); + + push (e); + + annotation (false); + + if (more ()) + { + XML::Element e (next ()); + String name (e.name ()); + Compositor* c (0); + + if (name == L"all") c = all (e); else + if (name == L"choice") c = choice (e, false); else + if (name == L"sequence") c = sequence (e, false); else + if (name == L"attribute") attribute (e, false); else + if (name == L"anyAttribute") any_attribute (e); else + if (name == L"group") element_group (e, false); else + if (name == L"attributeGroup") attribute_group (e); else + { + wcerr << file () << ":" << e.line () << ":" << e.column () << ": " + << "error: unexpected element '" << name << "'" << endl; + + valid_ = false; + } + + if (c) + s_->new_edge ( + type, *c, parse_min (e["minOccurs"]), parse_max (e["maxOccurs"])); + + while (more ()) + { + XML::Element e (next ()); + String name (e.name ()); + + if (name == L"attribute") attribute (e, false); else + if (name == L"anyAttribute") any_attribute (e); else + if (name == L"attributeGroup") attribute_group (e); else + { + wcerr << file () << ":" << e.line () << ":" << e.column () << ": " + << "error: expected 'attribute', 'anyAttribute', or " + << "'attributeGroup' instead of '" << name << "'" << endl; + + valid_ = false; + } + } + } + + pop (); + } + + Void Parser::Impl:: + complex_content_restriction (XML::Element const& e, Complex& type) + { + if (trace_) + wcout << "restriction base: " << fq_name (e, e["base"]) << endl; + + set_type (e["base"], e, dynamic_cast (scope ())); + + // @@ + // For now we simply skip the contents unless the base is anyType + // (or a trivial alias thereof). Checking for the trivial alias + // is further complicated by the fact that it might not be defined + // at this stage (forward inheritnace) so we will ignore that case + // as well for now. + // + if (!proper_restriction_) + { + String base (e["base"]); + String uq_name (unqualified_name (base)); + String ns_name (namespace_name (e, base)); + + if (ns_name != xsd || uq_name != L"anyType") + return; + } + + push (e); + + annotation (false); + + if (more ()) + { + XML::Element e (next ()); + String name (e.name ()); + Compositor* c (0); + + if (name == L"all") c = all (e); else + if (name == L"choice") c = choice (e, false); else + if (name == L"sequence") c = sequence (e, false); else + if (name == L"attribute") attribute (e, false); else + if (name == L"anyAttribute") any_attribute (e); else + if (name == L"group") element_group (e, false); else + if (name == L"attributeGroup") attribute_group (e); else + { + wcerr << file () << ":" << e.line () << ":" << e.column () << ": " + << "error: unexpected element '" << name << "'" << endl; + + valid_ = false; + } + + if (c) + s_->new_edge ( + type, *c, parse_min (e["minOccurs"]), parse_max (e["maxOccurs"])); + + while (more ()) + { + XML::Element e (next ()); + String name (e.name ()); + + if (name == L"attribute") attribute (e, false); else + if (name == L"anyAttribute") any_attribute (e); else + if (name == L"attributeGroup") attribute_group (e); else + { + wcerr << file () << ":" << e.line () << ":" << e.column () << ": " + << "error: expected 'attribute', 'anyAttribute', or " + << "'attributeGroup' instead of '" << name << "'" << endl; + + valid_ = false; + } + } + } + + pop (); + } + + Void Parser::Impl:: + element (XML::Element const& e, Boolean global) + { + Boolean qualified (global ? true : qualify_element_); + + if (String form = e["form"]) + qualified = form == L"qualified"; + + if (trace_) + wcout << "element qualified: " << qualified << endl; + + if (String name = e["name"]) + { + if (trace_) + wcout << "element name '" << name << "'" << endl; + + Element& node ( + s_->new_node ( + file (), e.line (), e.column (), global, qualified)); + + s_->new_edge (scope (), node, name); + + if (qualified) + s_->new_edge (node, cur_ns ()); + + if (!global) + { + s_->new_edge ( + compositor (), node, + parse_min (e["minOccurs"]), parse_max (e["maxOccurs"])); + } + + // Default and fixed values are mutually exclusive. + // + if (e.attribute_p ("fixed")) + node.fixed (e.attribute ("fixed")); + else if (e.attribute_p ("default")) + node.default_ (e.attribute ("default")); + + if (node.default_p ()) + { + node.context ().set ("dom-node", e.dom_element ()); + default_values_.push_back (&node); + } + + if (global) + { + if (String sg = e["substitutionGroup"]) + { + if (trace_) + wcout << "substitutes " << sg << endl; + + try + { + String uq_name (unqualified_name (sg)); + String ns_name (namespace_name (e, sg)); + + node.context ().set ("substitution-ns-name", ns_name); + node.context ().set ("substitution-uq-name", uq_name); + } + catch (XML::NoMapping const& ex) + { + wcerr << file () << ":" << e.line () << ":" << e.column () << ": " + << "error: unable to resolve namespace prefix '" + << ex.prefix () << "' in '" << sg << "'" << endl; + + valid_ = false; + } + } + } + + if (String type = e["type"]) + { + if (trace_) + wcout << "element type " << fq_name (e, type) << endl; + + set_type (type, e, node); + + // Parse annotation. + // + push (e); + + if (Annotation* a = annotation (true)) + s_->new_edge (*a, node); + + pop (); + } + else + { + // Looks like an anonymous type. + // + push (e); + + if (Annotation* a = annotation (true)) + s_->new_edge (*a, node); + + if (more ()) + { + XML::Element e (next ()); + + String name (e.name ()); + + if (trace_) + wcout << name << endl; + + Type* t (0); + + if (name == L"simpleType") t = simple_type (e); else + if (name == L"complexType") t = complex_type (e); else + { + wcerr << file () << ":" << e.line () << ":" << e.column () << ": " + << "error: expected 'simpleType' or 'complexType' " + << "instead of '" << e.name () << "'" << endl; + + valid_ = false; + } + + if (t) + s_->new_edge (node, *t); + } + else + { + // anyType + // + if (!is_disabled ("F001")) + { + wcerr << file () << ":" << e.line () << ":" << e.column () << ": " + << "warning F001: element '" << name << "' is implicitly " + << "of anyType" << endl; + + wcerr << file () << ":" << e.line () << ":" << e.column () << ": " + << "info: did you forget to specify 'type' attribute?" + << endl; + } + + String prefix (ns_prefix (e, xsd)); + type = prefix + (prefix.empty () ? L"" : L":") + L"anyType"; + + set_type (type, e, node); + } + + pop (); + } + } + else if (String ref = e["ref"]) + { + Element& node ( + s_->new_node ( + file (), e.line (), e.column (), true, true)); + + // Ref can only be in compositor. + // + s_->new_edge ( + compositor (), node, + parse_min (e["minOccurs"]), parse_max (e["maxOccurs"])); + + + // Default and fixed values are mutually exclusive. + // + if (e.attribute_p ("fixed")) + node.fixed (e.attribute ("fixed")); + else if (e.attribute_p ("default")) + node.default_ (e.attribute ("default")); + + if (node.default_p ()) + { + node.context ().set ("dom-node", e.dom_element ()); + default_values_.push_back (&node); + } + + // Parse annotation. + // + push (e); + + if (Annotation* a = annotation (true)) + s_->new_edge (*a, node); + + pop (); + + // Try to resolve the prototype. + // + try + { + String uq_name (unqualified_name (ref)); + String ns_name (namespace_name (e, ref)); + + s_->new_edge (scope (), node, uq_name); + + Element& prot (resolve (ns_name, uq_name, *s_, *cache_)); + s_->new_edge (node, prot.namespace_ ()); + + // Copy substitution group information if any. + // + if (prot.context ().count ("substitution-ns-name")) + { + node.context ().set ( + "substitution-ns-name", + prot.context ().get ("substitution-ns-name")); + + node.context ().set ( + "substitution-uq-name", + prot.context ().get ("substitution-uq-name")); + } + + // Transfer default and fixed values if the ref declaration hasn't + // defined its own. + // + if (!node.default_p ()) + { + if (prot.fixed_p ()) + node.fixed (prot.value ()); + else if (prot.default_p ()) + node.default_ (prot.value ()); + + if (node.default_p ()) + { + node.context ().set ( + "dom-node", + prot.context ().get ("dom-node")); + default_values_.push_back (&node); + } + } + + // Transfer annotation if the ref declaration hasn't defined its own. + // + if (!node.annotated_p () && prot.annotated_p ()) + s_->new_edge (prot.annotation (), node); + + // Set type information. + // + if (prot.typed_p ()) + { + s_->new_edge (node, prot.type ()); + } + else if (prot.context ().count ("type-ns-name")) + { + String ns_name (prot.context ().get ("type-ns-name")); + String uq_name (prot.context ().get ("type-uq-name")); + + node.context ().set ("type-ns-name", ns_name); + node.context ().set ("type-uq-name", uq_name); + node.context ().set ("edge-type-id", TypeId (typeid (Belongs))); + + if (trace_) + wcout << "element '" << ref << "' is not typed" << endl + << "deferring resolution until later" << endl; + } + else + { + // This could be a recursive reference to an element who's + // (anonymous) type is being defined. We are going to let + // resolver sort out this case. + // + node.context ().set ("instance-ns-name", ns_name); + node.context ().set ("instance-uq-name", uq_name); + + if (trace_) + wcout << "looks like a recursive reference to an element '" + << ns_name << "#" << uq_name << "' which is being " + << "defined" << endl + << "deferring resolution until later" << endl; + } + } + catch (NotNamespace const& ex) + { + if (valid_) + { + wcerr << file () << ":" << e.line () << ":" << e.column () << ": " + << "ice: unable to resolve namespace '" << ex.ns () << "'" + << endl; + + abort (); + } + } + catch (NotName const& ex) + { + node.context ().set ("instance-ns-name", ex.ns ()); + node.context ().set ("instance-uq-name", ex.name ()); + + if (trace_) + wcout << "unable to resolve name '" << ex.name () + << "' inside namespace '" << ex.ns () << "'" << endl + << "deferring resolution until later" << endl; + } + catch (XML::NoMapping const& ex) + { + wcerr << file () << ":" << e.line () << ":" << e.column () << ": " + << "error: unable to resolve namespace prefix '" + << ex.prefix () << "' in '" << ref << "'" << endl; + + valid_ = false; + } + } + else + { + if (valid_) + { + wcerr << file () << ":" << e.line () << ":" << e.column () << ": " + << "error: 'name' or 'ref' attribute is missing in element " + << "declaration" << endl; + } + } + } + + SemanticGraph::Annotation* Parser::Impl:: + annotation (Boolean process) + { + Annotation* r (0); + + if (more ()) + { + XML::Element e (next ()); + + if (e.name () == L"annotation") + { + if (process) + { + push (e); + + while (more ()) + { + XML::Element doc (next ()); + + if (doc.name () == L"documentation") + { + using Xerces::DOMNode; + using Xerces::DOMText; + using Xerces::DOMElement; + + // Use first non-structured (text only) documentation element. + // + String text; + Boolean struc (false); + DOMElement* de (doc.dom_element()); + + for (DOMNode* n (de->getFirstChild ()); + n != 0 && !struc; + n = n->getNextSibling ()) + { + switch (n->getNodeType ()) + { + case DOMNode::TEXT_NODE: + case DOMNode::CDATA_SECTION_NODE: + { + DOMText* t (static_cast (n)); + text += XML::transcode (t->getData ()); + break; + } + case DOMNode::ELEMENT_NODE: + { + struc = true; + break; + } + default: + break; // ignore + } + } + + if (struc) + continue; + + r = &s_->new_node ( + file (), e.line (), e.column (), text); + break; + } + } + + pop (); + } + } + else + prev (); + } + + return r; + } + + + Void Parser::Impl:: + attribute (XML::Element const& a, Boolean global) + { + Boolean optional (true); + + String use (a["use"]); + + if (use == L"prohibited") + return; + else if (use == L"required") + optional = false; + + Boolean qualified (global ? true : qualify_attribute_); + + if (String form = a["form"]) + qualified = form == L"qualified"; + + if (String name = a["name"]) + { + if (trace_) + wcout << "attribute '" << name << "'" << endl; + + Attribute& node ( + s_->new_node ( + file (), a.line (), a.column (), optional, global, qualified)); + + s_->new_edge (scope (), node, name); + + if (qualified) + s_->new_edge (node, cur_ns ()); + + + // Default and fixed values are mutually exclusive. + // + if (a.attribute_p ("fixed")) + node.fixed (a.attribute ("fixed")); + else if (a.attribute_p ("default")) + node.default_ (a.attribute ("default")); + + if (node.default_p ()) + { + node.context ().set ("dom-node", a.dom_element ()); + default_values_.push_back (&node); + } + + if (String type = a["type"]) + { + if (trace_) + wcout << "attribute type: '" << fq_name (a, type) << "'" << endl; + + set_type (type, a, node); + + // Parse annotation. + // + push (a); + + if (Annotation* ann = annotation (true)) + s_->new_edge (*ann, node); + + pop (); + } + else + { + // Looks like an anonymous type. + // + push (a); + + if (Annotation* ann = annotation (true)) + s_->new_edge (*ann, node); + + if (more ()) + { + XML::Element e (next ()); + + String name (e.name ()); + + if (trace_) + wcout << name << endl; + + Type* t (0); + + if (name == L"simpleType") t = simple_type (e); else + { + wcerr << file () << ":" << a.line () << ":" << a.column () << ": " + << "error: expected 'simpleType' instead of '" << e.name () + << "'" << endl; + + valid_ = false; + } + + if (t) + s_->new_edge (node, *t); + } + else + { + if (!is_disabled ("F002")) + { + wcerr << file () << ":" << a.line () << ":" << a.column () << ": " + << "warning F002: attribute '" << name << "' is implicitly " + << "of anySimpleType" << endl; + + wcerr << file () << ":" << a.line () << ":" << a.column () << ": " + << "info: did you forget to specify 'type' attribute?" + << endl; + } + + // anySimpleType + // + String prefix (ns_prefix (a, xsd)); + type = prefix + (prefix.empty () ? L"" : L":") + L"anySimpleType"; + + set_type (type, a, node); + } + + pop (); + } + } + else if (String ref = a["ref"]) + { + Attribute& node ( + s_->new_node ( + file (), a.line (), a.column (), optional, true, true)); + + + // Default and fixed values are mutually exclusive. + // + if (a.attribute_p ("fixed")) + node.fixed (a.attribute ("fixed")); + else if (a.attribute_p ("default")) + node.default_ (a.attribute ("default")); + + if (node.default_p ()) + { + node.context ().set ("dom-node", a.dom_element ()); + default_values_.push_back (&node); + } + + // Parse annotation. + // + push (a); + + if (Annotation* ann = annotation (true)) + s_->new_edge (*ann, node); + + pop (); + + try + { + String uq_name (unqualified_name (ref)); + String ns_name (namespace_name (a, ref)); + + s_->new_edge (scope (), node, uq_name); + + Attribute& prot (resolve (ns_name, uq_name, *s_, *cache_)); + s_->new_edge (node, prot.namespace_ ()); + + // Transfer default and fixed values if the ref declaration hasn't + // defined its own. + // + if (!node.default_p ()) + { + // Default value applies only if this attribute is optional. + // + if (prot.fixed_p ()) + node.fixed (prot.value ()); + else if (optional && prot.default_p ()) + node.default_ (prot.value ()); + + if (node.default_p ()) + { + node.context ().set ( + "dom-node", + prot.context ().get ("dom-node")); + default_values_.push_back (&node); + } + } + + // Transfer annotation if the ref declaration hasn't defined its own. + // + if (!node.annotated_p () && prot.annotated_p ()) + s_->new_edge (prot.annotation (), node); + + // Set type. + // + if (prot.typed_p ()) + { + s_->new_edge (node, prot.type ()); + } + else if (prot.context ().count ("type-ns-name")) + { + String ns_name (prot.context ().get ("type-ns-name")); + String uq_name (prot.context ().get ("type-uq-name")); + + node.context ().set ("type-ns-name", ns_name); + node.context ().set ("type-uq-name", uq_name); + node.context ().set ("edge-type-id", TypeId (typeid (Belongs))); + + if (trace_) + wcout << "attribute '" << ref << "' is not typed" << endl + << "deferring resolution until later" << endl; + } + else + { + // This could be a recursive reference to an attribute who's + // (anonymous) type is being defined. We are going to let + // resolver sort out this case. + // + node.context ().set ("instance-ns-name", ns_name); + node.context ().set ("instance-uq-name", uq_name); + + if (trace_) + wcout << "looks like a recursive reference to an attribute '" + << ns_name << "#" << uq_name << "' which is being " + << "defined" << endl + << "deferring resolution until later" << endl; + } + } + catch (NotNamespace const& ex) + { + if (valid_) + { + wcerr << file () << ":" << a.line () << ":" << a.column () << ": " + << "ice: unable to resolve namespace '" << ex.ns () << "'" + << endl; + abort (); + } + } + catch (NotName const& ex) + { + node.context ().set ("instance-ns-name", ex.ns ()); + node.context ().set ("instance-uq-name", ex.name ()); + + if (trace_) + wcout << "unable to resolve name '" << ex.name () + << "' inside namespace '" << ex.ns () << "'" << endl + << "deferring resolution until later" << endl; + } + catch (XML::NoMapping const& ex) + { + wcerr << file () << ":" << a.line () << ":" << a.column () << ": " + << "error: unable to resolve namespace prefix '" + << ex.prefix () << "' in '" << ref << "'" << endl; + + valid_ = false; + } + } + else + { + if (valid_) + { + wcerr << file () << ":" << a.line () << ":" << a.column () << ": " + << "error: 'name' or 'ref' attribute is missing in attribute " + << "declaration" << endl; + } + } + } + + Void Parser::Impl:: + attribute_group (XML::Element const& g) + { + if (String name = g["name"]) + { + // Global definition. + // + if (trace_) + wcout << "attributeGroup '" << name << "'" << endl; + + AttributeGroup& group ( + s_->new_node (file (), g.line (), g.column ())); + s_->new_edge (scope (), group, name); + + push_scope (group); + push (g); + + annotation (false); + + while (more ()) + { + XML::Element e (next ()); + String name (e.name ()); + + if (trace_) + wcout << name << endl; + + if (name == L"attribute") attribute (e, false); else + if (name == L"anyAttribute") any_attribute (e); else + if (name == L"attributeGroup") attribute_group (e); else + { + wcerr << file () << ":" << e.line () << ":" << e.column () << ": " + << "error: expected 'attribute', 'anyAttribute', or " + << "'attributeGroup' instead of '" << name << "'" << endl; + + valid_ = false; + } + } + + pop (); + pop_scope (); + } + else if (String ref = g["ref"]) + { + if (trace_) + wcout << "attribute-group-ref " << ref << endl; + + try + { + String uq_name (unqualified_name (ref)); + String ns_name (namespace_name (g, ref)); + + // In order to avoid code duplication we are going to let the + // resolver handle this case. + // + if (trace_) + wcout << "deferring resolution of group name '" << uq_name + << "' inside namespace '" << ns_name << "'" + << " until later" << endl; + + Scope& s (scope ()); + AttributeGroupRef ref (uq_name, ns_name, s); + + if (!s.context ().count ("attribute-group-refs")) + s.context ().set ("attribute-group-refs", AttributeGroupRefs ()); + + s.context ().get ( + "attribute-group-refs").push_back (ref); + } + catch (NotNamespace const& ex) + { + if (valid_) + { + wcerr << file () << ":" << g.line () << ":" << g.column () << ": " + << "ice: unable to resolve namespace '" << ex.ns () << "'" + << endl; + abort (); + } + } + catch (XML::NoMapping const& ex) + { + wcerr << file () << ":" << g.line () << ":" << g.column () << ": " + << "error: unable to resolve namespace prefix '" + << ex.prefix () << "' in '" << ref << "'" << endl; + + valid_ = false; + } + } + else + { + wcerr << file () << ":" << g.line () << ":" << g.column () << ": " + << "error: 'name' or 'ref' attribute is missing in " + << "attributeGroup declaration" << endl; + + valid_ = false; + return; + } + } + + Void Parser::Impl:: + any (XML::Element const& a) + { + if (trace_) + wcout << "any" << endl; + + String namespaces (a["namespace"] ? a["namespace"] : L"##any"); + + Any& any ( + s_->new_node (file (), a.line (), a.column (), namespaces)); + + s_->new_edge ( + compositor (), any, + parse_min (a["minOccurs"]), parse_max (a["maxOccurs"])); + + // Parse annotation. + // + push (a); + + if (Annotation* ann = annotation (true)) + s_->new_edge (*ann, any); + + pop (); + + // Any has no name so we have to come up with a fake one in order to + // put it into the scope. + // + UnsignedLong count; + FrontendElements::Context& ctx (scope ().context ()); + + if (!ctx.count ("any-name-count")) + { + count = 0; + ctx.set ("any-name-count", count); + } + else + count = ++(ctx.get ("any-name-count")); + + std::basic_ostringstream os; + os << "any #" << count; + + s_->new_edge (scope (), any, os.str ()); + } + + Void Parser::Impl:: + any_attribute (XML::Element const& a) + { + if (trace_) + wcout << "anyAttribute" << endl; + + String namespaces (a["namespace"] ? a["namespace"] : L"##any"); + + AnyAttribute& any ( + s_->new_node ( + file (), a.line (), a.column (), namespaces)); + + // Parse annotation. + // + push (a); + + if (Annotation* ann = annotation (true)) + s_->new_edge (*ann, any); + + pop (); + + // AnyAttribute has no name so we have to come up with a fake one + // in order to put it into the scope. + // + + UnsignedLong count; + FrontendElements::Context& ctx (scope ().context ()); + + if (!ctx.count ("any-attribute-name-count")) + { + count = 0; + ctx.set ("any-attribute-name-count", count); + } + else + count = ++(ctx.get ("any-attribute-name-count")); + + std::basic_ostringstream os; + os << "any-attribute #" << count; + + s_->new_edge (scope (), any, os.str ()); + } + + // Some specializations to get edge orientations right. + // + + template + struct Orientation + { + static Edge& + set_edge (Schema& s, Node& node, Type& type) + { + // By default it is node->edge + // + return s.template new_edge (node, type); + } + }; + + template + struct Orientation + { + static Arguments& + set_edge (Schema& s, Node& node, Type& type) + { + // For Arguments it is type->node. + // + return s.template new_edge (type, node); + } + }; + + template + Edge* Parser::Impl:: + set_type (String const& type, XML::Element const& e, Node& node) + { + Edge* r (0); + + try + { + String uq_name (unqualified_name (type)); + String ns_name (namespace_name (e, type)); + + Type& t (resolve (ns_name, uq_name, *s_, *cache_)); + + // See if it is an IDREF specialization. + // + if (ns_name == xsd && (uq_name == L"IDREF" || uq_name == L"IDREFS")) + { + // See if we've got 'xse:refType' attribute. + // + if (String ref_type = e.attribute (xse, "refType")) + { + if (trace_) + wcout << "found refType attribute '" << ref_type << "'" << endl; + + //@@ It is a bit wasteful to create a new spcialization for + // each refType. Instead we could lookup the target type + // and then navigate through Arguments edges to see if this + // type already arguments specialization that we are intersted + // in. But for now I will simplify the logic by creating a new + // specialization every time. + // + + Specialization* spec (0); + + if (uq_name == L"IDREF") + spec = &s_->new_node ( + file (), e.line (), e.column ()); + else + spec = &s_->new_node ( + file (), e.line (), e.column ()); + + r = &Orientation::set_edge (*s_, node, *spec); + + set_type (ref_type, e, *spec); + } + else + r = &Orientation::set_edge (*s_, node, t); + } + else + r = &Orientation::set_edge (*s_, node, t); + } + catch (NotNamespace const& ex) + { + wcerr << file () << ":" << e.line () << ":" << e.column () << ": " + << "error: unable to resolve namespace '" << ex.ns () << "'" + << endl; + + valid_ = false; + + } + catch (NotName const& ex) + { + node.context ().set ("type-ns-name", ex.ns ()); + node.context ().set ("type-uq-name", ex.name ()); + node.context ().set ("edge-type-id", TypeId (typeid (Edge))); + + if (trace_) + wcout << "unable to resolve name '" << ex.name () + << "' inside namespace '" << ex.ns () << "'" << endl + << "deferring resolution until later" << endl; + } + catch (XML::NoMapping const& ex) + { + wcerr << file () << ":" << e.line () << ":" << e.column () << ": " + << "error: unable to resolve namespace prefix " + << "'" << ex.prefix () << "' in '" << type << "'" << endl; + + valid_ = false; + } + + return r; + } + + // Xerces has a provision to associate a public id with input streams + // that can later be used in diagnostics. Unfortunately, it doesn't + // work. So we will have to keep our own track. + // + struct Context: public NonCopyable + { + // File map for diagnostic. + // + Path const& + file (Path const& abs) const + { + FileMap::ConstIterator i (file_map_.find (abs)); + + if (i != file_map_.end ()) + { + return i->second; + } + else + { + return abs; + } + } + + Void + map_file (Path const& abs, Path const& rel) + { + file_map_[abs] = rel; + } + + private: + typedef Cult::Containers::Map FileMap; + FileMap file_map_; + }; + + // + // + class ErrorHandler : public Xerces::DOMErrorHandler + { + public: + ErrorHandler (Boolean& valid, XSDFrontend::Context const& ctx) + : valid_ (valid), + ctx_ (ctx) + { + } + + virtual Boolean + handleError (Xerces::DOMError const& e) + { + // Xerces likes to say "Fatal error encountered during schema scan". + // We don't need this junk. + // + if (!valid_ + && e.getLocation ()->getLineNumber () == 0 + && e.getLocation ()->getColumnNumber () == 0) + return true; + + +#if !defined(BOOST_FILESYSTEM_VERSION) || BOOST_FILESYSTEM_VERSION == 2 + XSDFrontend::SemanticGraph::Path abs_path ( + XML::transcode_to_narrow (e.getLocation ()->getURI ()), + boost::filesystem::native); +#else + XSDFrontend::SemanticGraph::Path abs_path ( + XML::transcode_to_narrow (e.getLocation ()->getURI ()).c_str()); +#endif + + XSDFrontend::SemanticGraph::Path rel_path (ctx_.file (abs_path)); + + wcerr << rel_path << ':' + << e.getLocation ()->getLineNumber () << ':' + << e.getLocation ()->getColumnNumber () << ": "; + + switch (e.getSeverity ()) + { + case Xerces::DOMError::DOM_SEVERITY_WARNING: + { + wcerr << "warning: "; + break; + } + default: + { + wcerr << "error: "; + valid_ = false; + break; + } + } + + wcerr << e.getMessage () << endl; + + return true; + } + + private: + Boolean& valid_; + XSDFrontend::Context const& ctx_; + }; + + + // Failed to open resource. + // + struct Open {}; + + class InputSource: public Xerces::InputSource + { + public: + InputSource ( + Path const& abs, + Path const& rel, + Path const& base, + XSDFrontend::Context const& ctx, + Xerces::MemoryManager* mm = Xerces::XMLPlatformUtils::fgMemoryManager) + : Xerces::InputSource (mm), + abs_ (abs), + rel_ (rel), + base_ (base), + ctx_ (ctx) + { +#if !defined(BOOST_FILESYSTEM_VERSION) || BOOST_FILESYSTEM_VERSION == 2 + setSystemId (XML::XMLChString ( + String (abs_.native_file_string ())).c_str ()); +#else + setSystemId (XML::XMLChString (String (abs_.string ())).c_str ()); +#endif + } + + virtual Xerces::BinInputStream* + makeStream () const + { + using namespace Xerces; + + BinFileInputStream* is ( + new (getMemoryManager ()) + BinFileInputStream (getSystemId (), getMemoryManager ())); + + if (!is->getIsOpen ()) + { + delete is; + + wcerr << ctx_.file (base_) << ": error: " + << "'" << rel_ << "': unable to open in read mode" + << endl; + + throw Open (); + } + + return is; + } + + private: + Path abs_; + Path rel_; + Path base_; + XSDFrontend::Context const& ctx_; + }; + + + class EntityResolver: public Xerces::XMemory, +#if _XERCES_VERSION >= 30000 + public Xerces::DOMLSResourceResolver +#else + public Xerces::DOMEntityResolver +#endif + { + public: + EntityResolver (XSDFrontend::Context& ctx, LocationTranslator* t) + : ctx_ (ctx), loc_translator_ (t) + { + } + +#if _XERCES_VERSION >= 30000 + virtual Xerces::DOMLSInput* + resolveResource(XMLCh const* const, + XMLCh const* const, + XMLCh const* const /*pub_id*/, + XMLCh const* const prv_id, + XMLCh const* const base_uri) +#else + virtual Xerces::DOMInputSource* + resolveEntity (XMLCh const* const /*pub_id*/, + XMLCh const* const prv_id, + XMLCh const* const base_uri) +#endif + { + /* + XMLCh empty[1]; + empty[0] = 0; + + wcerr << "resolve entity:" << endl + << " pub_id " << (pub_id ? pub_id : empty) << endl + << " prv_id " << (prv_id ? prv_id : empty) << endl + << " uri " << (base_uri ? base_uri : empty) << endl; + */ + + // base_uri should be a valid path by now. + // +#if !defined(BOOST_FILESYSTEM_VERSION) || BOOST_FILESYSTEM_VERSION == 2 + Path base (XML::transcode_to_narrow (base_uri), + boost::filesystem::native); +#else + Path base (XML::transcode_to_narrow (base_uri).c_str()); +#endif + + if (prv_id == 0) + { + //@@ How can I get the line/column numbers for this? + // + wcerr << ctx_.file (base) << ": error: " + << "unable to guess which schema to open" + << endl; + + wcerr << ctx_.file (base) << ": info: " + << "did you forget to specify schemaLocation for import/include?" + << endl; + + throw Open (); + } + + NarrowString path_str (XML::transcode_to_narrow (prv_id)); + + if (loc_translator_) + path_str = loc_translator_->translate (path_str); + + try + { + Path path; + +#if !defined(BOOST_FILESYSTEM_VERSION) || BOOST_FILESYSTEM_VERSION == 2 + try + { + path = Path (path_str); + } + catch (InvalidPath const&) + { + // Retry as a native path. + // + path = Path (path_str, boost::filesystem::native); + } +#else + // The new ABI does not have a fallback native representation + path = Path (path_str.c_str()); +#endif + + Path base_dir (base.branch_path ()); + + Path abs_path, rel_path; + + if (path.is_complete ()) + { + abs_path = rel_path = path; + } + else + { + abs_path = base_dir / path; + rel_path = ctx_.file (base).branch_path () / path; + } + + abs_path.normalize (); + + ctx_.map_file (abs_path, rel_path); + + using namespace Xerces; + + InputSource* is ( + new (XMLPlatformUtils::fgMemoryManager) + InputSource (abs_path, rel_path, base, ctx_)); + + // Note that I can't use XMLPlatformUtils::fgMemoryManager here + // since Wrapper4InputSource is-not-an XMemory. + // + return new Wrapper4InputSource (is); + } + catch (InvalidPath const&) + { + wcerr << ctx_.file (base) << ": error: " + << "'" << path_str.c_str () << "' is not a valid filesystem path" + << endl; + throw; + } + + // Will never reach. + // + return 0; + } + + private: + XSDFrontend::Context& ctx_; + LocationTranslator* loc_translator_; + }; + + + XML::AutoPtr Parser::Impl:: + dom (Path const& tu, Boolean validate) + { + using namespace Xerces; + + try + { + XSDFrontend::Context ctx; + + Path abs_path (system_complete (tu)); + abs_path.normalize (); + ctx.map_file (abs_path, tu); + + InputSource input_source (abs_path, tu, abs_path, ctx); + + // First validate the schema with Xerces. + // + if (validate) + { + // Instantiate the DOM parser. + // + XMLCh const gLS[] = {chLatin_L, chLatin_S, chNull }; + + // Get an implementation of the Load-Store (LS) interface. + // + DOMImplementationLS* impl ( + static_cast ( + DOMImplementationRegistry::getDOMImplementation (gLS))); + + // Create a DOMBuilder. + // +#if _XERCES_VERSION >= 30000 + XML::AutoPtr parser ( + impl->createLSParser (DOMImplementationLS::MODE_SYNCHRONOUS, 0)); + + DOMConfiguration* conf (parser->getDomConfig ()); + + conf->setParameter (XMLUni::fgDOMComments, false); + conf->setParameter (XMLUni::fgDOMDatatypeNormalization, true); + conf->setParameter (XMLUni::fgDOMEntities, false); + conf->setParameter (XMLUni::fgDOMNamespaces, true); + conf->setParameter (XMLUni::fgDOMValidate, true); + conf->setParameter (XMLUni::fgDOMElementContentWhitespace, false); + conf->setParameter (XMLUni::fgXercesSchema, true); + + // Xerces-C++ 3.1.0 is the first version with working multi import + // support. + // +#if _XERCES_VERSION >= 30100 + conf->setParameter (XMLUni::fgXercesHandleMultipleImports, multiple_imports_); +#endif + + conf->setParameter (XMLUni::fgXercesSchemaFullChecking, full_schema_check_); + conf->setParameter (XMLUni::fgXercesValidationErrorAsFatal, true); + + ErrorHandler eh (valid_, ctx); + conf->setParameter (XMLUni::fgDOMErrorHandler, &eh); + + EntityResolver er (ctx, loc_translator_); + conf->setParameter (XMLUni::fgDOMResourceResolver, &er); + + Wrapper4InputSource wrap (&input_source, false); + parser->loadGrammar (&wrap, Grammar::SchemaGrammarType); +#else + XML::AutoPtr parser ( + impl->createDOMBuilder (DOMImplementationLS::MODE_SYNCHRONOUS, 0)); + + parser->setFeature (XMLUni::fgDOMComments, false); + parser->setFeature (XMLUni::fgDOMDatatypeNormalization, true); + parser->setFeature (XMLUni::fgDOMEntities, false); + parser->setFeature (XMLUni::fgDOMNamespaces, true); + parser->setFeature (XMLUni::fgDOMValidation, true); + parser->setFeature (XMLUni::fgDOMWhitespaceInElementContent, false); + parser->setFeature (XMLUni::fgXercesSchema, true); + parser->setFeature (XMLUni::fgXercesSchemaFullChecking, full_schema_check_); + parser->setFeature (XMLUni::fgXercesValidationErrorAsFatal, true); + + ErrorHandler eh (valid_, ctx); + parser->setErrorHandler (&eh); + + EntityResolver er (ctx, loc_translator_); + parser->setEntityResolver (&er); + + Wrapper4InputSource wrap (&input_source, false); + parser->loadGrammar (wrap, Grammar::SchemaGrammarType); +#endif + } + + if (!valid_) + return XML::AutoPtr (0); + + // Now do our own parsing. + // + std::auto_ptr xsd_parser ( + new (XMLPlatformUtils::fgMemoryManager) XML::SchemaDOMParser ()); + + xsd_parser->parse (input_source); + + XML::AutoPtr doc (xsd_parser->adoptDocument()); + + return doc; + } + catch (Xerces::XMLException const& e) + { + wcerr << tu << ": ice: Xerces::XMLException: " << e.getMessage () + << endl; + + abort (); + } + catch (Xerces::DOMException const& e) + { + Size const size = 2047; + XMLCh text[size + 1]; + + wcerr << tu << ": ice: Xerces::DOMException: "; + + if (DOMImplementation::loadDOMExceptionMsg (e.code, text, size)) + wcerr << text << endl; + else + wcerr << "no message available, error code: " << e.code << endl; + + abort (); + } + catch (InvalidPath const&) + { + // Diagnostics has already been issued. + // + valid_ = false; + } + catch (Open const&) + { + // Diagnostics has already been issued. + // + valid_ = false; + } + + return XML::AutoPtr (0); + } + + // LocationTranslator + // + LocationTranslator:: + ~LocationTranslator () + { + } + + // Parser + // + Parser:: + ~Parser () + { + } + + Parser:: + Parser (Boolean proper_restriction, + Boolean multiple_imports, + Boolean full_schema_check) + : impl_ (new Impl (proper_restriction, + multiple_imports, + full_schema_check, + 0, + 0)) + { + } + + Parser:: + Parser (Boolean proper_restriction, + Boolean multiple_imports, + Boolean full_schema_check, + LocationTranslator& t, + const WarningSet& d) + : impl_ (new Impl (proper_restriction, + multiple_imports, + full_schema_check, + &t, + &d)) + { + } + + Evptr Parser:: + parse (SemanticGraph::Path const& path) + { + return impl_->parse (path); + } + + Evptr Parser:: + parse (SemanticGraph::Paths const& paths) + { + return impl_->parse (paths); + } + + Evptr Parser:: + xml_schema (SemanticGraph::Path const& path) + { + return impl_->xml_schema (path); + } +} diff --git a/libxsd-frontend/xsd-frontend/parser.hxx b/libxsd-frontend/xsd-frontend/parser.hxx new file mode 100644 index 0000000..ac0ff4d --- /dev/null +++ b/libxsd-frontend/xsd-frontend/parser.hxx @@ -0,0 +1,76 @@ +// file : xsd-frontend/parser.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_FRONTEND_PARSER_HXX +#define XSD_FRONTEND_PARSER_HXX + +#include +#include + +#include + +namespace XSDFrontend +{ + using namespace Cult::Types; + + struct InvalidSchema {}; + + class LocationTranslator + { + public: + virtual + ~LocationTranslator (); + + virtual NarrowString + translate (NarrowString const& location) = 0; + }; + + // Set of disabled warning IDs. Special ID "all" disables all + // warnings. + // + typedef Cult::Containers::Set WarningSet; + + class Parser: public NonCopyable + { + public: + ~Parser (); + + Parser (Boolean proper_restriction, + Boolean multiple_imports, + Boolean full_schema_check); + + Parser (Boolean proper_restriction, + Boolean multiple_imports, + Boolean full_schema_check, + LocationTranslator&, + const WarningSet& disabled); + + public: + // Parse a schema file. Throws InvalidSchema in case of a failure. + // + Evptr + parse (SemanticGraph::Path const&); + + // Parse a number of schema files all into one semantic graph. + // Each schema file is imported from an unnamed root translation + // unit. Throws InvalidSchema in case of a failure. + // + Evptr + parse (SemanticGraph::Paths const&); + + // Returns a schema graph that corresponds to the XML Schema + // namespace with built-in type definitions. The path is fake + // and is only used as a lable. + // + Evptr + xml_schema (SemanticGraph::Path const&); + + private: + class Impl; + Evptr impl_; + }; +} + +#endif // XSD_FRONTEND_PARSER_HXX diff --git a/libxsd-frontend/xsd-frontend/schema-dom-parser.cxx b/libxsd-frontend/xsd-frontend/schema-dom-parser.cxx new file mode 100644 index 0000000..452980c --- /dev/null +++ b/libxsd-frontend/xsd-frontend/schema-dom-parser.cxx @@ -0,0 +1,196 @@ +// file : xsd-frontend/schema-dom-parser.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include + +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include + +namespace XSDFrontend +{ + namespace XML + { + using namespace Xerces; + + const XMLCh line_key[2] = {chLatin_l, chNull}; + const XMLCh column_key[2] = {chLatin_c, chNull}; + + SchemaDOMParser:: + SchemaDOMParser (MemoryManager* mgr) + : XercesDOMParser(0, mgr, 0), + depth_ (-1), + ann_depth_ (-1), + inner_ann_depth_ (-1) + { + error_reporter_.setErrorReporter (this); + setValidationScheme (XercesDOMParser::Val_Never); + setDoNamespaces (true); + } + + void SchemaDOMParser:: + startElement (const XMLElementDecl& decl, + const unsigned int url_id, + const XMLCh* const prefix, + const RefVectorOf& attributes, +#if _XERCES_VERSION >= 30000 + const XMLSize_t attr_count, +#else + const unsigned int attr_count, +#endif + const bool empty, + const bool root) + { + depth_++; + + if (ann_depth_ == -1) + { + if (XMLString::equals(decl.getBaseName(), + SchemaSymbols::fgELT_ANNOTATION) && + XMLString::equals(getURIText(url_id), + SchemaSymbols::fgURI_SCHEMAFORSCHEMA)) + { + ann_depth_ = depth_; + } + } + else if (depth_ == ann_depth_ + 1) + { + inner_ann_depth_ = depth_; + } + + XercesDOMParser::startElement ( + decl, url_id, prefix, attributes, attr_count, false, root); + + // Set the line/column info. + // + ReaderMgr::LastExtEntityInfo info; + ((ReaderMgr*) fScanner->getLocator())->getLastExtEntityInfo(info); + +#if _XERCES_VERSION >= 30000 + unsigned long l (static_cast (info.lineNumber)); + unsigned long c (static_cast (info.colNumber)); +#else + unsigned long l (info.lineNumber == -1 + ? 0UL + : static_cast (info.lineNumber)); + + unsigned long c (info.colNumber == -1 + ? 0UL + : static_cast (info.colNumber)); +#endif + + fCurrentNode->setUserData (line_key, reinterpret_cast (l), 0); + fCurrentNode->setUserData (column_key, reinterpret_cast (c), 0); + + // If an empty element, call the endElement() now. + // + if (empty) + endElement (decl, url_id, root, prefix); + } + + void SchemaDOMParser:: + endElement (const XMLElementDecl& decl, + const unsigned int url_id, + const bool root, + const XMLCh* const prefix) + { + if(ann_depth_ > -1) + { + if (inner_ann_depth_ == depth_) + { + inner_ann_depth_ = -1; + } + else if (ann_depth_ == depth_) + { + ann_depth_ = -1; + } + } + + depth_--; + + XercesDOMParser::endElement (decl, url_id, root, prefix); + } + + void SchemaDOMParser:: + docCharacters (const XMLCh* const s, +#if _XERCES_VERSION >= 30000 + const XMLSize_t length, +#else + const unsigned int length, +#endif + const bool cdata) + { + // Ignore chars outside of content. + // + if (!fWithinElement) + return; + + if (inner_ann_depth_ == -1) + { + if (!((ReaderMgr*) fScanner->getReaderMgr())->getCurrentReader()-> + isAllSpaces(s, length)) + { + ReaderMgr::LastExtEntityInfo lastInfo; + fScanner->getReaderMgr()->getLastExtEntityInfo(lastInfo); + locator_.setValues(lastInfo.systemId, lastInfo.publicId, + lastInfo.lineNumber, lastInfo.colNumber); + error_reporter_.emitError(XMLValid::NonWSContent, + XMLUni::fgValidityDomain, + &locator_); + } + } + else + { + // When it's within either of the 2 annotation sub-elements, + // characters are allowed and we need to store them. + // + XercesDOMParser::docCharacters (s, length, cdata); + } + } + + void SchemaDOMParser:: + docComment (const XMLCh* const) + { + // We don't want any comments. + } + + void SchemaDOMParser:: + startEntityReference (const XMLEntityDecl&) + { + } + + void SchemaDOMParser:: + endEntityReference (const XMLEntityDecl&) + { + } + + void SchemaDOMParser:: + ignorableWhitespace (const XMLCh* const s, +#if _XERCES_VERSION >= 30000 + const XMLSize_t length, +#else + const unsigned int length, +#endif + const bool cdata) + { + // Ignore chars before the root element. + // + if (!fWithinElement || !fIncludeIgnorableWhitespace) + return; + + if (ann_depth_ > -1) + XercesDOMParser::ignorableWhitespace (s, length, cdata); + } + } +} diff --git a/libxsd-frontend/xsd-frontend/schema-dom-parser.hxx b/libxsd-frontend/xsd-frontend/schema-dom-parser.hxx new file mode 100644 index 0000000..7571677 --- /dev/null +++ b/libxsd-frontend/xsd-frontend/schema-dom-parser.hxx @@ -0,0 +1,93 @@ +// file : xsd-frontend/schema-dom-parser.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_FRONTEND_SCHEMA_DOM_PARSER_HXX +#define XSD_FRONTEND_SCHEMA_DOM_PARSER_HXX + +#include + +#include + +#include +#include + +namespace XSDFrontend +{ + namespace XML + { + namespace Xerces = xercesc; + + extern const XMLCh line_key[2]; + extern const XMLCh column_key[2]; + + class SchemaDOMParser: public Xerces::XercesDOMParser + { + public : + SchemaDOMParser ( + Xerces::MemoryManager* = Xerces::XMLPlatformUtils::fgMemoryManager); + + // Callbacks. + // + virtual void + startElement (const Xerces::XMLElementDecl&, + const unsigned int url_id, + const XMLCh* const prefix, + const Xerces::RefVectorOf& attributes, +#if _XERCES_VERSION >= 30000 + const XMLSize_t attribute_count, +#else + const unsigned int attribute_count, +#endif + const bool empty, + const bool root); + + virtual void + endElement (const Xerces::XMLElementDecl&, + const unsigned int url_id, + const bool root, + const XMLCh* const prefix); + + virtual void + docCharacters (const XMLCh* const, +#if _XERCES_VERSION >= 30000 + const XMLSize_t length, +#else + const unsigned int length, +#endif + const bool cdata); + + virtual void + docComment (const XMLCh* const); + + virtual void + startEntityReference (const Xerces::XMLEntityDecl&); + + virtual void + endEntityReference (const Xerces::XMLEntityDecl&); + + virtual void + ignorableWhitespace (const XMLCh* const, +#if _XERCES_VERSION >= 30000 + const XMLSize_t length, +#else + const unsigned int length, +#endif + const bool cdata); + private: + SchemaDOMParser (SchemaDOMParser const&); + SchemaDOMParser& + operator=(SchemaDOMParser const&); + + private: + int depth_; + int ann_depth_; + int inner_ann_depth_; + Xerces::XSDLocator locator_; + Xerces::XSDErrorReporter error_reporter_; + }; + } +} + +#endif // XSD_FRONTEND_SCHEMA_DOM_PARSER_HXX diff --git a/libxsd-frontend/xsd-frontend/semantic-graph.hxx b/libxsd-frontend/xsd-frontend/semantic-graph.hxx new file mode 100644 index 0000000..bee17fc --- /dev/null +++ b/libxsd-frontend/xsd-frontend/semantic-graph.hxx @@ -0,0 +1,27 @@ +// file : xsd-frontend/semantic-graph.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_FRONTEND_SEMANTIC_GRAPH_HXX +#define XSD_FRONTEND_SEMANTIC_GRAPH_HXX + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif // XSD_FRONTEND_SEMANTIC_GRAPH_HXX diff --git a/libxsd-frontend/xsd-frontend/semantic-graph/annotation.cxx b/libxsd-frontend/xsd-frontend/semantic-graph/annotation.cxx new file mode 100644 index 0000000..22793f7 --- /dev/null +++ b/libxsd-frontend/xsd-frontend/semantic-graph/annotation.cxx @@ -0,0 +1,50 @@ +// file : xsd-frontend/semantic-graph/annotation.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2006-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include + +namespace XSDFrontend +{ + namespace SemanticGraph + { + namespace RTTI = Cult::RTTI; + + using RTTI::Access; + using RTTI::TypeInfo; + + + // Annotates + // + namespace + { + struct AnnotatesInit + { + AnnotatesInit () + { + TypeInfo ti (typeid (Annotates)); + ti.add_base (Access::public_, true, typeid (Edge)); + RTTI::insert (ti); + } + + } annotates_init_; + } + + // Annotation + // + namespace + { + struct AnnotationInit + { + AnnotationInit () + { + TypeInfo ti (typeid (Annotation)); + ti.add_base (Access::public_, true, typeid (Node)); + RTTI::insert (ti); + } + + } annotation_init_; + } + } +} diff --git a/libxsd-frontend/xsd-frontend/semantic-graph/annotation.hxx b/libxsd-frontend/xsd-frontend/semantic-graph/annotation.hxx new file mode 100644 index 0000000..661ac72 --- /dev/null +++ b/libxsd-frontend/xsd-frontend/semantic-graph/annotation.hxx @@ -0,0 +1,89 @@ +// file : xsd-frontend/semantic-graph/annotation.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2006-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_FRONTEND_SEMANTIC_GRAPH_ANNOTATION_HXX +#define XSD_FRONTEND_SEMANTIC_GRAPH_ANNOTATION_HXX + +#include + +namespace XSDFrontend +{ + namespace SemanticGraph + { + // + // + class Annotation; + + class Annotates: public virtual Edge + { + public: + Annotation& + annotation () + { + return *annotation_; + } + + protected: + friend class Bits::Graph; + + Annotates () + : annotation_ (0) + { + } + + Void + set_left_node (Annotation& a) + { + annotation_ = &a; + } + + Void + set_right_node (Node&) + { + } + + Void + set_right_node (Edge&) + { + } + + private: + Annotation* annotation_; + }; + + // + // + class Annotation: public virtual Node + { + public: + WideString const& + documentation () const + { + return documentation_; + } + + protected: + friend class Bits::Graph; + + Annotation (Path const& file, + UnsignedLong line, + UnsignedLong column, + WideString const& documentation) + : Node (file, line, column), documentation_ (documentation) + { + } + + Void + add_edge_left (Annotates&) + { + } + + private: + WideString documentation_; + }; + } +} + +#endif // XSD_FRONTEND_SEMANTIC_GRAPH_ANNOTATION_HXX diff --git a/libxsd-frontend/xsd-frontend/semantic-graph/any-attribute.cxx b/libxsd-frontend/xsd-frontend/semantic-graph/any-attribute.cxx new file mode 100644 index 0000000..e25e742 --- /dev/null +++ b/libxsd-frontend/xsd-frontend/semantic-graph/any-attribute.cxx @@ -0,0 +1,114 @@ +// file : xsd-frontend/semantic-graph/any-attribute.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include +#include + +namespace XSDFrontend +{ + namespace SemanticGraph + { + namespace RTTI = Cult::RTTI; + + using RTTI::Access; + using RTTI::TypeInfo; + + namespace + { + struct AnyAttributeInit + { + AnyAttributeInit () + { + TypeInfo ti (typeid (AnyAttribute)); + ti.add_base (Access::public_, true, typeid (Nameable)); + RTTI::insert (ti); + } + + } any_attribute_init_; + } + + AnyAttribute:: + AnyAttribute (Path const& file, + UnsignedLong line, + UnsignedLong column, + WideString const& namespaces) + : Node (file, line, column), + prototype_ (0) + { + // Not sure if the separator is just space or any white-space + // chararcter. + // + + for (Size i (0), j (namespaces.find (L' '));;) + { + if (j != WideString::npos) + { + namespaces_.push_back (WideString (namespaces, i, j - i)); + + i = j + 1; + j = namespaces.find (L' ', i); + } + else + { + // Last element. + // + namespaces_.push_back (WideString (namespaces, i)); + break; + } + } + } + + AnyAttribute:: + AnyAttribute (Path const& file, + UnsignedLong line, + UnsignedLong column, + NamespaceIterator begin, + NamespaceIterator end) + : Node (file, line, column), + prototype_ (0) + { + for (; begin != end; ++begin) + namespaces_.push_back (*begin); + } + + namespace + { + Namespace& + namespace_ (Nameable& n) + { + // The basic idea goes like this: go up Names edges until you + // reach Namespace. There are, however, anonymous types which + // need special handling. In the case of an anonymous type we + // will go up the first Belongs edge (because the first edge + // is where the type was defined. + // + + if (n.named_p ()) + { + Scope& s (n.scope ()); + Namespace* ns (dynamic_cast (&n)); + + return ns ? *ns : namespace_ (s); + } + else + { + Type& t (dynamic_cast (n)); + Belongs& b (*t.classifies_begin ()); + + return namespace_ (b.instance ()); + } + } + } + + Namespace& AnyAttribute:: + definition_namespace () + { + if (prototype_p ()) + return prototype ().definition_namespace (); + + return namespace_ (scope ()); + } + } +} diff --git a/libxsd-frontend/xsd-frontend/semantic-graph/any-attribute.hxx b/libxsd-frontend/xsd-frontend/semantic-graph/any-attribute.hxx new file mode 100644 index 0000000..bc8c512 --- /dev/null +++ b/libxsd-frontend/xsd-frontend/semantic-graph/any-attribute.hxx @@ -0,0 +1,85 @@ +// file : xsd-frontend/semantic-graph/any-attribute.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_FRONTEND_SEMANTIC_GRAPH_ANY_ATTRIBUTE_HXX +#define XSD_FRONTEND_SEMANTIC_GRAPH_ANY_ATTRIBUTE_HXX + +#include + +#include +#include + +namespace XSDFrontend +{ + namespace SemanticGraph + { + class AnyAttribute: public virtual Nameable + { + typedef + Cult::Containers::Vector + Namespaces; + + public: + typedef Namespaces::ConstIterator NamespaceIterator; + + NamespaceIterator + namespace_begin () const + { + return namespaces_.begin (); + } + + NamespaceIterator + namespace_end () const + { + return namespaces_.end (); + } + + public: + Boolean + prototype_p () + { + return prototype_ != 0; + } + + AnyAttribute& + prototype () + { + assert (prototype_ != 0); + return *prototype_; + } + + Void + prototype (AnyAttribute& a) + { + assert (prototype_ == 0); + prototype_ = &a; + } + + public: + Namespace& + definition_namespace (); + + protected: + friend class Bits::Graph; + + AnyAttribute (Path const& file, + UnsignedLong line, + UnsignedLong column, + WideString const& namespaces); + + AnyAttribute (Path const& file, + UnsignedLong line, + UnsignedLong column, + NamespaceIterator begin, + NamespaceIterator end); + + private: + AnyAttribute* prototype_; + Namespaces namespaces_; + }; + } +} + +#endif // XSD_FRONTEND_SEMANTIC_GRAPH_ANY_ATTRIBUTE_HXX diff --git a/libxsd-frontend/xsd-frontend/semantic-graph/any.cxx b/libxsd-frontend/xsd-frontend/semantic-graph/any.cxx new file mode 100644 index 0000000..a6c9e72 --- /dev/null +++ b/libxsd-frontend/xsd-frontend/semantic-graph/any.cxx @@ -0,0 +1,125 @@ +// file : xsd-frontend/semantic-graph/any.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include +#include + +namespace XSDFrontend +{ + namespace SemanticGraph + { + namespace RTTI = Cult::RTTI; + + using RTTI::Access; + using RTTI::TypeInfo; + + namespace + { + struct AnyInit + { + AnyInit () + { + TypeInfo ti (typeid (Any)); + ti.add_base (Access::public_, true, typeid (Nameable)); + ti.add_base (Access::public_, true, typeid (Particle)); + RTTI::insert (ti); + } + + } any_init_; + } + + Any:: + Any (Path const& file, + UnsignedLong line, + UnsignedLong column, + WideString const& namespaces) + : Node (file, line, column), + prototype_ (0) + { + // Not sure if the separator is just space or any white-space + // chararcter. + // + + for (Size i (0), j (namespaces.find (L' '));;) + { + if (j != WideString::npos) + { + namespaces_.push_back (WideString (namespaces, i, j - i)); + + i = j + 1; + j = namespaces.find (L' ', i); + } + else + { + // Last element. + // + namespaces_.push_back (WideString (namespaces, i)); + break; + } + } + } + + Any:: + Any (Path const& file, + UnsignedLong line, + UnsignedLong column, + NamespaceIterator begin, + NamespaceIterator end) + : Node (file, line, column), + prototype_ (0) + { + for (; begin != end; ++begin) + namespaces_.push_back (*begin); + } + + namespace + { + Namespace& + namespace_ (Nameable& n) + { + // The basic idea goes like this: go up Names edges until you + // reach Namespace. There are, however, anonymous types which + // need special handling. In the case of an anonymous type we + // will go up the first Belongs edge (because the first edge + // is where the type was defined. + // + + if (n.named_p ()) + { + Scope& s (n.scope ()); + Namespace* ns (dynamic_cast (&n)); + + return ns ? *ns : namespace_ (s); + } + else + { + Type& t (dynamic_cast (n)); + Belongs& b (*t.classifies_begin ()); + + return namespace_ (b.instance ()); + } + } + } + + Namespace& Any:: + definition_namespace () + { + if (prototype_p ()) + return prototype ().definition_namespace (); + + // Get to our scope. + // + Compositor* c (&contained_particle ().compositor ()); + + while(!c->contained_compositor_p ()) + c = &c->contained_particle ().compositor (); + + Scope& scope ( + dynamic_cast (c->contained_compositor ().container ())); + + return namespace_ (scope); + } + } +} diff --git a/libxsd-frontend/xsd-frontend/semantic-graph/any.hxx b/libxsd-frontend/xsd-frontend/semantic-graph/any.hxx new file mode 100644 index 0000000..ded9bd8 --- /dev/null +++ b/libxsd-frontend/xsd-frontend/semantic-graph/any.hxx @@ -0,0 +1,90 @@ +// file : xsd-frontend/semantic-graph/any.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_FRONTEND_SEMANTIC_GRAPH_ANY_HXX +#define XSD_FRONTEND_SEMANTIC_GRAPH_ANY_HXX + +#include + +#include +#include +#include + +namespace XSDFrontend +{ + namespace SemanticGraph + { + class Any: public virtual Nameable, + public virtual Particle + { + typedef + Cult::Containers::Vector + Namespaces; + + public: + typedef Namespaces::ConstIterator NamespaceIterator; + + NamespaceIterator + namespace_begin () const + { + return namespaces_.begin (); + } + + NamespaceIterator + namespace_end () const + { + return namespaces_.end (); + } + + public: + Boolean + prototype_p () + { + return prototype_ != 0; + } + + Any& + prototype () + { + assert (prototype_ != 0); + return *prototype_; + } + + Void + prototype (Any& a) + { + assert (prototype_ == 0); + prototype_ = &a; + } + + public: + Namespace& + definition_namespace (); + + protected: + friend class Bits::Graph; + + Any (Path const& file, + UnsignedLong line, + UnsignedLong column, + WideString const& namespaces); + + Any (Path const& file, + UnsignedLong line, + UnsignedLong column, + NamespaceIterator begin, + NamespaceIterator end); + + using Nameable::add_edge_right; + using Particle::add_edge_right; + + private: + Any* prototype_; + Namespaces namespaces_; + }; + } +} + +#endif // XSD_FRONTEND_SEMANTIC_GRAPH_ANY_HXX diff --git a/libxsd-frontend/xsd-frontend/semantic-graph/attribute-group.cxx b/libxsd-frontend/xsd-frontend/semantic-graph/attribute-group.cxx new file mode 100644 index 0000000..54bb5df --- /dev/null +++ b/libxsd-frontend/xsd-frontend/semantic-graph/attribute-group.cxx @@ -0,0 +1,39 @@ +// file : xsd-frontend/semantic-graph/attribute-group.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2006-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include + +namespace XSDFrontend +{ + namespace SemanticGraph + { + namespace RTTI = Cult::RTTI; + + using RTTI::Access; + using RTTI::TypeInfo; + + + namespace + { + struct AttributeGroupInit + { + AttributeGroupInit () + { + TypeInfo ti (typeid (AttributeGroup)); + ti.add_base (Access::public_, true, typeid (Scope)); + RTTI::insert (ti); + } + + } attribute_group_init_; + } + + AttributeGroup:: + AttributeGroup (Path const& file, UnsignedLong line, UnsignedLong column) + : Node (file, line, column) + { + } + + } +} diff --git a/libxsd-frontend/xsd-frontend/semantic-graph/attribute-group.hxx b/libxsd-frontend/xsd-frontend/semantic-graph/attribute-group.hxx new file mode 100644 index 0000000..44739f2 --- /dev/null +++ b/libxsd-frontend/xsd-frontend/semantic-graph/attribute-group.hxx @@ -0,0 +1,27 @@ +// file : xsd-frontend/semantic-graph/attribute-group.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2006-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_FRONTEND_SEMANTIC_GRAPH_ATTRIBUTE_GROUP_HXX +#define XSD_FRONTEND_SEMANTIC_GRAPH_ATTRIBUTE_GROUP_HXX + +#include + +namespace XSDFrontend +{ + namespace SemanticGraph + { + class AttributeGroup: public virtual Scope + { + protected: + friend class Bits::Graph; + + AttributeGroup (Path const& file, + UnsignedLong line, + UnsignedLong column); + }; + } +} + +#endif // XSD_FRONTEND_SEMANTIC_GRAPH_ATTRIBUTE_GROUP_HXX diff --git a/libxsd-frontend/xsd-frontend/semantic-graph/attribute.cxx b/libxsd-frontend/xsd-frontend/semantic-graph/attribute.cxx new file mode 100644 index 0000000..2e30d4e --- /dev/null +++ b/libxsd-frontend/xsd-frontend/semantic-graph/attribute.cxx @@ -0,0 +1,44 @@ +// file : xsd-frontend/semantic-graph/attribute.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include + +namespace XSDFrontend +{ + namespace SemanticGraph + { + namespace RTTI = Cult::RTTI; + + using RTTI::Access; + using RTTI::TypeInfo; + + namespace + { + struct AttributeInit + { + AttributeInit () + { + TypeInfo ti (typeid (Attribute)); + ti.add_base (Access::public_, true, typeid (Member)); + RTTI::insert (ti); + } + + } attribute_init_; + } + + Attribute:: + Attribute (Path const& file, + UnsignedLong line, + UnsignedLong column, + Boolean optional, + Boolean global, + Boolean qualified) + : Node (file, line, column), + Member (global, qualified), + optional_ (optional) + { + } + } +} diff --git a/libxsd-frontend/xsd-frontend/semantic-graph/attribute.hxx b/libxsd-frontend/xsd-frontend/semantic-graph/attribute.hxx new file mode 100644 index 0000000..f7a516d --- /dev/null +++ b/libxsd-frontend/xsd-frontend/semantic-graph/attribute.hxx @@ -0,0 +1,39 @@ +// file : xsd-frontend/semantic-graph/attribute.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_FRONTEND_SEMANTIC_GRAPH_ATTRIBUTE_HXX +#define XSD_FRONTEND_SEMANTIC_GRAPH_ATTRIBUTE_HXX + +#include + +namespace XSDFrontend +{ + namespace SemanticGraph + { + class Attribute: public virtual Member + { + public: + Boolean + optional_p () const + { + return optional_; + } + + protected: + friend class Bits::Graph; + + Attribute (Path const& file, + UnsignedLong line, + UnsignedLong column, + Boolean optional, + Boolean global, + Boolean qualified); + private: + Boolean optional_; + }; + } +} + +#endif // XSD_FRONTEND_SEMANTIC_GRAPH_ATTRIBUTE_HXX diff --git a/libxsd-frontend/xsd-frontend/semantic-graph/complex.cxx b/libxsd-frontend/xsd-frontend/semantic-graph/complex.cxx new file mode 100644 index 0000000..0cc265f --- /dev/null +++ b/libxsd-frontend/xsd-frontend/semantic-graph/complex.cxx @@ -0,0 +1,45 @@ +// file : xsd-frontend/semantic-graph/complex.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include + +namespace XSDFrontend +{ + namespace SemanticGraph + { + namespace RTTI = Cult::RTTI; + + using RTTI::Access; + using RTTI::TypeInfo; + + namespace + { + struct ComplexInit + { + ComplexInit () + { + TypeInfo ti (typeid (Complex)); + ti.add_base (Access::public_, true, typeid (Type)); + ti.add_base (Access::public_, true, typeid (Scope)); + RTTI::insert (ti); + } + + } complex_init_; + } + + Complex:: + Complex () + : mixed_ (false), contains_compositor_ (0) + { + } + + Complex:: + Complex (Path const& file, UnsignedLong line, UnsignedLong column) + : Node (file, line, column), + mixed_ (false), contains_compositor_ (0) + { + } + } +} diff --git a/libxsd-frontend/xsd-frontend/semantic-graph/complex.hxx b/libxsd-frontend/xsd-frontend/semantic-graph/complex.hxx new file mode 100644 index 0000000..40327bc --- /dev/null +++ b/libxsd-frontend/xsd-frontend/semantic-graph/complex.hxx @@ -0,0 +1,78 @@ +// file : xsd-frontend/semantic-graph/complex.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_FRONTEND_SEMANTIC_GRAPH_COMPLEX_HXX +#define XSD_FRONTEND_SEMANTIC_GRAPH_COMPLEX_HXX + +#include +#include + +#include + +namespace XSDFrontend +{ + namespace SemanticGraph + { + class Complex: public virtual Type, public virtual Scope + { + public: + Boolean + mixed_p () const + { + return mixed_; + } + + public: + Boolean + contains_compositor_p () + { + return contains_compositor_ != 0; + } + + ContainsCompositor& + contains_compositor () + { + assert (contains_compositor_ != 0); + return *contains_compositor_; + } + + public: + Void + mixed_p (Boolean m) + { + mixed_ = m; + } + + protected: + friend class Bits::Graph; + + Complex (); // Virtual inheritance (Enumeration). + Complex (Path const& file, UnsignedLong line, UnsignedLong column); + + using Type::add_edge_right; + using Type::add_edge_left; + using Scope::add_edge_left; + + Void + add_edge_left (ContainsCompositor& e) + { + contains_compositor_ = &e; + } + + Void + remove_edge_left (ContainsCompositor& e) + { + assert (contains_compositor_ == &e); + contains_compositor_ = 0; + } + + private: + Boolean mixed_; + ContainsCompositor* contains_compositor_; + }; + } +} + +#endif // XSD_FRONTEND_SEMANTIC_GRAPH_COMPLEX_HXX diff --git a/libxsd-frontend/xsd-frontend/semantic-graph/compositors.cxx b/libxsd-frontend/xsd-frontend/semantic-graph/compositors.cxx new file mode 100644 index 0000000..08953bc --- /dev/null +++ b/libxsd-frontend/xsd-frontend/semantic-graph/compositors.cxx @@ -0,0 +1,124 @@ +// file : xsd-frontend/semantic-graph/compositor.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2006-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include + +namespace XSDFrontend +{ + namespace SemanticGraph + { + namespace RTTI = Cult::RTTI; + + using RTTI::Access; + using RTTI::TypeInfo; + + + // ContainsCompositor + // + namespace + { + struct ContainsCompositorInit + { + ContainsCompositorInit () + { + TypeInfo ti (typeid (ContainsCompositor)); + ti.add_base (Access::public_, true, typeid (Edge)); + RTTI::insert (ti); + } + + } contains_compositor_init_; + } + + ContainsCompositor:: + ContainsCompositor (UnsignedLong min, UnsignedLong max) + : compositor_ (0), container_ (0), min_ (min), max_ (max) + { + } + + // Compositor + // + namespace + { + struct CompositorInit + { + CompositorInit () + { + TypeInfo ti (typeid (Compositor)); + ti.add_base (Access::public_, true, typeid (Particle)); + RTTI::insert (ti); + } + + } compositor_init_; + } + + + // All + // + namespace + { + struct AllInit + { + AllInit () + { + TypeInfo ti (typeid (All)); + ti.add_base (Access::public_, true, typeid (Compositor)); + RTTI::insert (ti); + } + + } all_init_; + } + + All:: + All (Path const& file, UnsignedLong line, UnsignedLong column) + : Node (file, line, column) + { + } + + + // Choice + // + namespace + { + struct ChoiceInit + { + ChoiceInit () + { + TypeInfo ti (typeid (Choice)); + ti.add_base (Access::public_, true, typeid (Compositor)); + RTTI::insert (ti); + } + + } choice_init_; + } + + Choice:: + Choice (Path const& file, UnsignedLong line, UnsignedLong column) + : Node (file, line, column) + { + } + + // Sequence + // + namespace + { + struct SequenceInit + { + SequenceInit () + { + TypeInfo ti (typeid (Sequence)); + ti.add_base (Access::public_, true, typeid (Compositor)); + RTTI::insert (ti); + } + + } sequence_init_; + } + + Sequence:: + Sequence (Path const& file, UnsignedLong line, UnsignedLong column) + : Node (file, line, column) + { + } + } +} diff --git a/libxsd-frontend/xsd-frontend/semantic-graph/compositors.hxx b/libxsd-frontend/xsd-frontend/semantic-graph/compositors.hxx new file mode 100644 index 0000000..c82d8a4 --- /dev/null +++ b/libxsd-frontend/xsd-frontend/semantic-graph/compositors.hxx @@ -0,0 +1,263 @@ +// file : xsd-frontend/semantic-graph/compositors.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2006-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_FRONTEND_SEMANTIC_GRAPH_COMPOSITORS_HXX +#define XSD_FRONTEND_SEMANTIC_GRAPH_COMPOSITORS_HXX + +#include + +#include +#include + +namespace XSDFrontend +{ + namespace SemanticGraph + { + // + // + class ContainsCompositor: public virtual Edge + { + public: + Compositor& + compositor () const + { + return *compositor_; + } + + Node& + container () const + { + return *container_; + } + + public: + UnsignedLong + min () const + { + return min_; + } + + UnsignedLong + max () const + { + return max_; + } + + protected: + friend class Bits::Graph; + + ContainsCompositor (UnsignedLong min, UnsignedLong max); + + Void + set_left_node (Node& n) + { + container_ = &n; + } + + Void + set_right_node (Compositor& n) + { + compositor_ = &n; + } + + Void + clear_left_node (Node& n) + { + assert (container_ == &n); + container_ = 0; + } + + Void + clear_right_node (Compositor& n) + { + assert (compositor_ == &n); + compositor_ = 0; + } + + private: + Compositor* compositor_; + Node* container_; + UnsignedLong min_, max_; + }; + + + // + // + class Compositor: public virtual Particle + { + typedef + Cult::Containers::List + ContainsList; + + public: + typedef + Bits::PointerIterator + ContainsIterator; + + typedef + Bits::PointerIterator + ContainsConstIterator; + + ContainsIterator + contains_begin () + { + return contains_.begin (); + } + + ContainsIterator + contains_end () + { + return contains_.end (); + } + + ContainsConstIterator + contains_begin () const + { + return contains_.begin (); + } + + ContainsConstIterator + contains_end () const + { + return contains_.end (); + } + + public: + Boolean + contained_compositor_p () + { + return contained_compositor_ != 0; + } + + ContainsCompositor& + contained_compositor () + { + assert (contained_compositor_ != 0); + return *contained_compositor_; + } + + public: + UnsignedLong + min () const + { + if (contained_compositor_ != 0) + return contained_compositor_->min (); + else + return Particle::min (); + } + + UnsignedLong + max () const + { + if (contained_compositor_ != 0) + return contained_compositor_->max (); + else + return Particle::max (); + } + + protected: + friend class Bits::Graph; + + Compositor () + : contained_compositor_ (0) + { + } + + Void + add_edge_left (ContainsParticle& e) + { + contains_.push_back (&e); + } + + Void + remove_edge_left (ContainsParticle& e) + { + for (ContainsList::Iterator i (contains_.begin ()); + i != contains_.end (); ++i) + { + if (*i == &e) + { + contains_.erase (i); + break; + } + } + } + + //@@ Ideally should be protected but then NodeArg has no way to + // access it. Maybe when (if) I move NodeArg into Grpah I can + // resolve this. + // + public: + Void + add_edge_left (ContainsParticle& e, ContainsIterator const& after) + { + if (after.base () == contains_.end ()) + contains_.push_front (&e); + else + { + ContainsList::Iterator i (after.base ()); + contains_.insert (++i, &e); + } + } + + protected: + using Node::add_edge_right; + using Particle::add_edge_right; + using Particle::remove_edge_right; + + Void + add_edge_right (ContainsCompositor& e) + { + contained_compositor_ = &e; + } + + Void + remove_edge_right (ContainsCompositor& e) + { + assert (contained_compositor_ == &e); + contained_compositor_ = 0; + } + + private: + ContainsList contains_; + ContainsCompositor* contained_compositor_; + }; + + + // + // + class All: public virtual Compositor + { + protected: + friend class Bits::Graph; + + All (Path const& file, UnsignedLong line, UnsignedLong column); + }; + + + // + // + class Choice: public virtual Compositor + { + protected: + friend class Bits::Graph; + + Choice (Path const& file, UnsignedLong line, UnsignedLong column); + }; + + + // + // + class Sequence: public virtual Compositor + { + protected: + friend class Bits::Graph; + + Sequence (Path const& file, UnsignedLong line, UnsignedLong column); + }; + } +} + +#endif // XSD_FRONTEND_SEMANTIC_GRAPH_COMPOSITORS_HXX diff --git a/libxsd-frontend/xsd-frontend/semantic-graph/element-group.cxx b/libxsd-frontend/xsd-frontend/semantic-graph/element-group.cxx new file mode 100644 index 0000000..0e71aa6 --- /dev/null +++ b/libxsd-frontend/xsd-frontend/semantic-graph/element-group.cxx @@ -0,0 +1,38 @@ +// file : xsd-frontend/semantic-graph/element-group.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2006-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include + +namespace XSDFrontend +{ + namespace SemanticGraph + { + namespace RTTI = Cult::RTTI; + + using RTTI::Access; + using RTTI::TypeInfo; + + + namespace + { + struct ElementGroupInit + { + ElementGroupInit () + { + TypeInfo ti (typeid (ElementGroup)); + ti.add_base (Access::public_, true, typeid (Scope)); + RTTI::insert (ti); + } + + } element_group_init_; + } + + ElementGroup:: + ElementGroup (Path const& file, UnsignedLong line, UnsignedLong column) + : Node (file, line, column), contains_compositor_ (0) + { + } + } +} diff --git a/libxsd-frontend/xsd-frontend/semantic-graph/element-group.hxx b/libxsd-frontend/xsd-frontend/semantic-graph/element-group.hxx new file mode 100644 index 0000000..23514b5 --- /dev/null +++ b/libxsd-frontend/xsd-frontend/semantic-graph/element-group.hxx @@ -0,0 +1,45 @@ +// file : xsd-frontend/semantic-graph/element-group.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2006-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_FRONTEND_SEMANTIC_GRAPH_ELEMENT_GROUP_HXX +#define XSD_FRONTEND_SEMANTIC_GRAPH_ELEMENT_GROUP_HXX + +#include +#include + +namespace XSDFrontend +{ + namespace SemanticGraph + { + class ElementGroup: public virtual Scope + { + public: + ContainsCompositor& + contains_compositor () + { + assert (contains_compositor_ != 0); + return *contains_compositor_; + } + + protected: + friend class Bits::Graph; + + ElementGroup (Path const& file, UnsignedLong line, UnsignedLong column); + + using Scope::add_edge_left; + + Void + add_edge_left (ContainsCompositor& e) + { + contains_compositor_ = &e; + } + + private: + ContainsCompositor* contains_compositor_; + }; + } +} + +#endif // XSD_FRONTEND_SEMANTIC_GRAPH_ELEMENT_GROUP_HXX diff --git a/libxsd-frontend/xsd-frontend/semantic-graph/element.cxx b/libxsd-frontend/xsd-frontend/semantic-graph/element.cxx new file mode 100644 index 0000000..1d8cda5 --- /dev/null +++ b/libxsd-frontend/xsd-frontend/semantic-graph/element.cxx @@ -0,0 +1,63 @@ +// file : xsd-frontend/semantic-graph/element.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include + +namespace XSDFrontend +{ + namespace SemanticGraph + { + namespace RTTI = Cult::RTTI; + + using RTTI::Access; + using RTTI::TypeInfo; + + + // Substitutes + // + namespace + { + struct SubstitutesInit + { + SubstitutesInit () + { + TypeInfo ti (typeid (Substitutes)); + ti.add_base (Access::public_, true, typeid (Edge)); + RTTI::insert (ti); + } + + } substitutes_init_; + } + + // Element + // + namespace + { + struct ElementInit + { + ElementInit () + { + TypeInfo ti (typeid (Element)); + ti.add_base (Access::public_, true, typeid (Member)); + ti.add_base (Access::public_, true, typeid (Particle)); + RTTI::insert (ti); + } + + } element_init_; + } + + Element:: + Element (Path const& file, + UnsignedLong line, + UnsignedLong column, + Boolean global, + Boolean qualified) + : Node (file, line, column), + Member (global, qualified), + substitutes_ (0) + { + } + } +} diff --git a/libxsd-frontend/xsd-frontend/semantic-graph/element.hxx b/libxsd-frontend/xsd-frontend/semantic-graph/element.hxx new file mode 100644 index 0000000..e7046e4 --- /dev/null +++ b/libxsd-frontend/xsd-frontend/semantic-graph/element.hxx @@ -0,0 +1,105 @@ +// file : xsd-frontend/semantic-graph/element.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_FRONTEND_SEMANTIC_GRAPH_ELEMENT_HXX +#define XSD_FRONTEND_SEMANTIC_GRAPH_ELEMENT_HXX + +#include +#include + +namespace XSDFrontend +{ + namespace SemanticGraph + { + class Element; + + class Substitutes: public virtual Edge + { + public: + Element& + substitution () const + { + return *substitution_; + } + + Element& + root () const + { + return *root_; + } + + protected: + friend class Bits::Graph; + + Substitutes () + { + } + + Void + set_left_node (Element& n) + { + substitution_ = &n; + } + + Void + set_right_node (Element& n) + { + root_ = &n; + } + + private: + Element* root_; + Element* substitution_; + }; + + + class Element: public virtual Member, + public virtual Particle + { + public: + Boolean + substitutes_p () const + { + return substitutes_ != 0; + } + + Substitutes& + substitutes () const + { + assert (substitutes_ != 0); + return *substitutes_; + } + + protected: + friend class Bits::Graph; + + Element (Path const& file, + UnsignedLong line, + UnsignedLong column, + Boolean global, + Boolean qualified); + + Void + add_edge_left (Substitutes& e) + { + substitutes_ = &e; + } + + Void + add_edge_right (Substitutes&) + { + } + + using Member::add_edge_left; + using Member::add_edge_right; + using Particle::add_edge_right; + + private: + Substitutes* substitutes_; + }; + } +} + +#endif // XSD_FRONTEND_SEMANTIC_GRAPH_ELEMENT_HXX diff --git a/libxsd-frontend/xsd-frontend/semantic-graph/elements.cxx b/libxsd-frontend/xsd-frontend/semantic-graph/elements.cxx new file mode 100644 index 0000000..6a2addf --- /dev/null +++ b/libxsd-frontend/xsd-frontend/semantic-graph/elements.cxx @@ -0,0 +1,350 @@ +// file : xsd-frontend/semantic-graph/elements.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include + +#include +#include + +using namespace std; + +namespace XSDFrontend +{ + namespace SemanticGraph + { + // Node + // + Annotation& Node:: + annotation () + { + return annotates_->annotation (); + } + + // Type + // + Void Type:: + remove_edge_left (Arguments& a) + { + ArgumentsSet::Iterator i (arguments_.find (&a)); + assert (i != arguments_.end ()); + arguments_.erase (i); + } + + // Specialization + // + Void Specialization:: + remove_edge_right (Arguments& a) + { + // The number of entries should be small so linear search will do. + // + Argumented::Iterator i ( + std::find (argumented_.begin (), argumented_.end (), &a)); + + assert (i != argumented_.end ()); + argumented_.erase (i); + } + + namespace RTTI = Cult::RTTI; + + using RTTI::Access; + using RTTI::TypeInfo; + + namespace + { + // Edge + // + struct EdgeInit + { + EdgeInit () + { + TypeInfo ti (typeid (Edge)); + RTTI::insert (ti); + } + + } edge_init_; + + + // Node + // + struct NodeInit + { + NodeInit () + { + TypeInfo ti (typeid (Node)); + RTTI::insert (ti); + } + + } node_init_; + + + // Names + // + struct NamesInit + { + NamesInit () + { + TypeInfo ti (typeid (Names)); + ti.add_base (Access::public_, true, typeid (Edge)); + RTTI::insert (ti); + } + + } names_init_; + + + // Nameable + // + struct NameableInit + { + NameableInit () + { + TypeInfo ti (typeid (Nameable)); + ti.add_base (Access::public_, true, typeid (Node)); + RTTI::insert (ti); + } + + } nameable_init_; + + + // Scope + // + struct ScopeInit + { + ScopeInit () + { + TypeInfo ti (typeid (Scope)); + ti.add_base (Access::public_, true, typeid (Nameable)); + RTTI::insert (ti); + } + + } scope_init_; + + + // Type + // + struct TypeInit + { + TypeInit () + { + TypeInfo ti (typeid (Type)); + ti.add_base (Access::public_, true, typeid (Nameable)); + RTTI::insert (ti); + } + + } type_init_; + + + // Instance + // + struct InstanceInit + { + InstanceInit () + { + TypeInfo ti (typeid (Instance)); + ti.add_base (Access::public_, true, typeid (Nameable)); + RTTI::insert (ti); + } + + } instance_init_; + + + // Belongs + // + struct BelongsInit + { + BelongsInit () + { + TypeInfo ti (typeid (Belongs)); + ti.add_base (Access::public_, true, typeid (Edge)); + RTTI::insert (ti); + } + + } belongs_init_; + + + + // Inherits + // + struct InheritsInit + { + InheritsInit () + { + TypeInfo ti (typeid (Inherits)); + ti.add_base (Access::public_, true, typeid (Edge)); + RTTI::insert (ti); + } + + } inherits_init_; + + + // Extends + // + struct ExtendsInit + { + ExtendsInit () + { + TypeInfo ti (typeid (Extends)); + ti.add_base (Access::public_, true, typeid (Inherits)); + RTTI::insert (ti); + } + + } extends_init_; + + + // Restricts + // + struct RestrictsInit + { + RestrictsInit () + { + TypeInfo ti (typeid (Restricts)); + ti.add_base (Access::public_, true, typeid (Inherits)); + RTTI::insert (ti); + } + + } restricts_init_; + + + // BelongsToNamespace + // + struct BelongsToNamespaceInit + { + BelongsToNamespaceInit () + { + TypeInfo ti (typeid (BelongsToNamespace)); + ti.add_base (Access::public_, true, typeid (Edge)); + RTTI::insert (ti); + } + + } belongs_to_namespace_init_; + + + // Member + // + struct MemberInit + { + MemberInit () + { + TypeInfo ti (typeid (Member)); + ti.add_base (Access::public_, true, typeid (Instance)); + RTTI::insert (ti); + } + + } member_init_; + + + // Specialization + // + struct SpecializationInit + { + SpecializationInit () + { + TypeInfo ti (typeid (Specialization)); + ti.add_base (Access::public_, true, typeid (Type)); + RTTI::insert (ti); + } + + } specialization_init_; + + + // Arguments + // + struct ArgumentsInit + { + ArgumentsInit () + { + TypeInfo ti (typeid (Arguments)); + ti.add_base (Access::public_, true, typeid (Edge)); + RTTI::insert (ti); + } + + } arguments_init_; + + + /* + // Contains + // + struct ContainsInit + { + ContainsInit () + { + TypeInfo ti (typeid (Contains)); + ti.add_base (Access::public_, true, typeid (Edge)); + RTTI::insert (ti); + } + + } contains_init_; + + + // Container + // + struct ContainerInit + { + ContainerInit () + { + TypeInfo ti (typeid (Container)); + ti.add_base (Access::public_, true, typeid (Node)); + RTTI::insert (ti); + } + + } container_init_; + */ + + + // AnyType + // + namespace + { + struct AnyTypeInit + { + AnyTypeInit () + { + TypeInfo ti (typeid (AnyType)); + ti.add_base (Access::public_, true, typeid (SemanticGraph::Type)); + RTTI::insert (ti); + } + + } any_type_init_; + } + + + // AnySimpleType + // + namespace + { + struct AnySimpleTypeInit + { + AnySimpleTypeInit () + { + TypeInfo ti (typeid (AnySimpleType)); + ti.add_base (Access::public_, true, typeid (Type)); + RTTI::insert (ti); + } + + } any_simple_type_init_; + } + } + + + // Instance + // + Type& Instance:: + type () const + { + return belongs ().type (); + } + } +} + +// Path +// +std::wostream& +operator<< (std::wostream& os, XSDFrontend::SemanticGraph::Path const& path) +{ +#if !defined(BOOST_FILESYSTEM_VERSION) || BOOST_FILESYSTEM_VERSION == 2 + return os << path.native_file_string ().c_str (); +#else + return os << path.string ().c_str (); +#endif +} diff --git a/libxsd-frontend/xsd-frontend/semantic-graph/elements.hxx b/libxsd-frontend/xsd-frontend/semantic-graph/elements.hxx new file mode 100644 index 0000000..78b6615 --- /dev/null +++ b/libxsd-frontend/xsd-frontend/semantic-graph/elements.hxx @@ -0,0 +1,1247 @@ +// file : xsd-frontend/semantic-graph/elements.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_FRONTEND_SEMANTIC_GRAPH_ELEMENTS_HXX +#define XSD_FRONTEND_SEMANTIC_GRAPH_ELEMENTS_HXX + +#include + +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include + +namespace XSDFrontend +{ + namespace SemanticGraph + { + using namespace Cult::Types; + + namespace Bits + { + using Cult::Containers::Graph; + + //@@ Should end up in Cult::Meta + // + template + struct strip_pointer + { + typedef X Type; + }; + + template + struct strip_pointer + { + typedef X Type; + }; + + template + struct PointerIterator + { + typedef + typename strip_pointer::Type + Value; + + typedef I BaseIterator; + typedef Value& Reference; + typedef Value* Pointer; + + PointerIterator () + : i_ () // i_ can be of a pointer type. + { + } + + PointerIterator (I const& i) + : i_ (i) + { + } + + public: + Reference + operator* () const + { + return **i_; + } + + Pointer + operator-> () const + { + return *i_; + } + + I const& + base () const + { + return i_; + } + + public: + PointerIterator& + operator++ () + { + ++i_; + return *this; + } + + PointerIterator + operator++ (Int) + { + PointerIterator r (*this); + ++i_; + return r; + } + + PointerIterator& + operator-- () + { + --i_; + return *this; + } + + PointerIterator + operator-- (Int) + { + PointerIterator r (*this); + --i_; + return r; + } + + private: + I i_; + }; + + template + inline + Boolean + operator== (PointerIterator const& a, PointerIterator const& b) + { + return a.base () == b.base (); + } + + template + inline + Boolean + operator!= (PointerIterator const& a, PointerIterator const& b) + { + return a.base () != b.base (); + } + + template + inline + typename PointerIterator::BaseIterator::difference_type + operator- (PointerIterator const& a, PointerIterator const& b) + { + return a.base () - b.base (); + } + } + + // + // + typedef + boost::filesystem::filesystem_error + InvalidPath; + + typedef + boost::filesystem::path + Path; + + typedef + Cult::Containers::Vector + Paths; + + typedef + FrontendElements::Context + Context; + + // + // + class Node; + class Edge; + + // + // + class Annotates; + class Annotation; + + // + // + class Edge + { + public: + Context& + context () const + { + return context_; + } + + virtual + ~Edge () + { + } + + public: + template + Boolean + is_a () const + { + return dynamic_cast (this) != 0; + } + + protected: + friend class Bits::Graph; + + Edge () + { + } + + private: + mutable Context context_; + }; + + inline Boolean + operator== (Edge const& x, Edge const& y) + { + return &x == &y; + } + + + // + // + class Node + { + public: + Context& + context () const + { + return context_; + } + + public: + Path const& + file () const + { + return file_; + } + + UnsignedLong + line () const + { + return line_; + } + + UnsignedLong + column () const + { + return column_; + } + + public: + Boolean + annotated_p () const + { + return annotates_ != 0; + } + + Annotates& + annotated () const + { + return *annotates_; + } + + Annotation& + annotation (); + + public: + template + Boolean + is_a () const + { + return dynamic_cast (this) != 0; + } + + public: + + virtual + ~Node () + { + } + + protected: + friend class Bits::Graph; + + Node (Path const& file, UnsignedLong line, UnsignedLong column) + : annotates_ (0), file_ (file), line_ (line), column_ (column) + { + } + + Node () // For virtual inheritance. + { + abort (); // Told you so! + } + + Void + add_edge_right (Annotates& a) + { + annotates_ = &a; + } + + private: + mutable Context context_; + Annotates* annotates_; + Path file_; + UnsignedLong line_; + UnsignedLong column_; + }; + + inline Boolean + operator== (Node const& x, Node const& y) + { + return &x == &y; + } + + + // + // + typedef WideString Name; + + + // + // + class Scope; + class Nameable; + + + // + // + class Names: public virtual Edge + { + public: + Name + name () const + { + return name_; + } + + Scope& + scope () const + { + return *scope_; + } + + Nameable& + named () const + { + return *named_; + } + + protected: + friend class Bits::Graph; + + Names (Name const& name) + : name_ (name) + { + } + + Void + set_left_node (Scope& n) + { + scope_ = &n; + } + + Void + set_right_node (Nameable& n) + { + named_ = &n; + } + + Void + clear_left_node (Scope& n) + { + assert (scope_ == &n); + scope_ = 0; + } + + Void + clear_right_node (Nameable& n) + { + assert (named_ == &n); + named_ = 0; + } + + private: + Scope* scope_; + Nameable* named_; + Name name_; + }; + + + class Nameable: public virtual Node + { + public: + Boolean + named_p () const + { + return named_ != 0; + } + + Name + name () const + { + assert (named_p ()); + return named_->name (); + } + + Scope& + scope () + { + assert (named_p ()); + return named_->scope (); + } + + Names& + named () + { + assert (named_p ()); + return *named_; + } + + protected: + friend class Bits::Graph; + + Nameable () + : named_ (0) + { + } + + Void + add_edge_right (Names& e) + { + named_ = &e; + } + + Void + remove_edge_right (Names& e) + { + assert (named_ == &e); + named_ = 0; + } + + using Node::add_edge_right; + + private: + Names* named_; + }; + + + // + // + typedef + Cult::Containers::Set + Nameables; + + + // + // + class Scope: public virtual Nameable + { + protected: + typedef + Cult::Containers::List + NamesList; + + typedef + Cult::Containers::Map + ListIteratorMap; + + typedef + Cult::Containers::Map + NamesMap; + + public: + typedef + Bits::PointerIterator + NamesIterator; + + typedef + Bits::PointerIterator + NamesConstIterator; + + typedef + Cult::Containers::Pair + NamesIteratorPair; + + NamesIterator + names_begin () + { + return names_.begin (); + } + + NamesIterator + names_end () + { + return names_.end (); + } + + NamesConstIterator + names_begin () const + { + return names_.begin (); + } + + NamesConstIterator + names_end () const + { + return names_.end (); + } + + virtual NamesIteratorPair + find (Name const& name) const + { + NamesMap::ConstIterator i (names_map_.find (name)); + + if (i == names_map_.end ()) + return NamesIteratorPair (names_.end (), names_.end ()); + else + return NamesIteratorPair (i->second.begin (), i->second.end ()); + } + + NamesIterator + find (Names& e) + { + ListIteratorMap::Iterator i (iterator_map_.find (&e)); + return i != iterator_map_.end () ? i->second : names_.end (); + } + + protected: + friend class Bits::Graph; + + Scope (Path const& file, UnsignedLong line, UnsignedLong column) + : Node (file, line, column) + { + } + + Scope () + { + } + + Void + add_edge_left (Names& e) + { + NamesList::Iterator i (names_.insert (names_.end (), &e)); + iterator_map_[&e] = i; + names_map_[e.name ()].push_back (&e); + } + + Void + remove_edge_left (Names& e) + { + ListIteratorMap::Iterator i (iterator_map_.find (&e)); + assert (i != iterator_map_.end ()); + + names_.erase (i->second); + iterator_map_.erase (i); + + NamesMap::Iterator j (names_map_.find (e.name ())); + + for (NamesList::Iterator i (j->second.begin ()); + i != j->second.end (); ++i) + { + if (*i == &e) + i = j->second.erase (i); + } + } + + //@@ Ideally should be protected but then NodeArg has no way to + // access it. Maybe when (if) I move NodeArg into Grpah I can + // resolve this. + // + public: + Void + add_edge_left (Names& e, NamesIterator const& after) + { + NamesList::Iterator i; + + if (after.base () == names_.end ()) + i = names_.insert (names_.begin (), &e); + else + { + NamesList::Iterator j (after.base ()); + i = names_.insert (++j, &e); + } + + iterator_map_[&e] = i; + names_map_[e.name ()].push_back (&e); + } + + protected: + using Nameable::add_edge_right; + + private: + NamesList names_; + ListIteratorMap iterator_map_; + NamesMap names_map_; + }; + + + // + // + class Belongs; + class Inherits; + class Arguments; + + class Type: public virtual Nameable + { + protected: + typedef + Cult::Containers::Vector + Classifies; + + typedef + Cult::Containers::Vector + Begets; + + typedef + Cult::Containers::Set + ArgumentsSet; + + public: + typedef + Bits::PointerIterator + ClassifiesIterator; + + ClassifiesIterator + classifies_begin () const + { + return classifies_.begin (); + } + + ClassifiesIterator + classifies_end () const + { + return classifies_.end (); + } + + // + // + Boolean + inherits_p () const + { + return inherits_ != 0; + } + + Inherits& + inherits () const + { + assert (inherits_ != 0); + return *inherits_; + } + + // + // + typedef + Bits::PointerIterator + BegetsIterator; + + BegetsIterator + begets_begin () const + { + return begets_.begin (); + } + + BegetsIterator + begets_end () const + { + return begets_.end (); + } + + // + // + typedef + Bits::PointerIterator + ArgumentsIterator; + + ArgumentsIterator + arguments_begin () const + { + return arguments_.begin (); + } + + ArgumentsIterator + arguments_end () const + { + return arguments_.end (); + } + + protected: + friend class Bits::Graph; + + Type () + : inherits_ (0) + { + } + + Void + add_edge_right (Belongs& e) + { + classifies_.push_back (&e); + } + + Void + add_edge_right (Inherits& e) + { + begets_.push_back (&e); + } + + using Nameable::add_edge_right; + + Void + add_edge_left (Arguments& a) + { + arguments_.insert (&a); + } + + Void + remove_edge_left (Arguments&); + + Void + add_edge_left (Inherits& e) + { + inherits_ = &e; + } + + private: + Inherits* inherits_; + Begets begets_; + Classifies classifies_; + ArgumentsSet arguments_; + }; + + + class Instance: public virtual Nameable + { + public: + Belongs& + belongs () const + { + return *belongs_; + } + + Type& + type () const; + + Boolean + typed_p () const + { + return belongs_ != 0; + } + + protected: + friend class Bits::Graph; + + Instance () + : belongs_ (0) + { + } + + Void + add_edge_left (Belongs& e) + { + belongs_ = &e; + } + + private: + Belongs* belongs_; + }; + + + class Belongs: public virtual Edge + { + public: + Instance& + instance () const + { + return *instance_; + } + + Type& + type () const + { + return *type_; + } + + protected: + friend class Bits::Graph; + + Belongs () + { + } + + Void + set_left_node (Instance& n) + { + instance_ = &n; + } + + Void + set_right_node (Type& n) + { + type_ = &n; + } + + private: + Instance* instance_; + Type* type_; + }; + + + // + // + class Inherits: public virtual Edge + { + public: + Type& + base () const + { + return *base_; + } + + Type& + derived () const + { + return *derived_; + } + + protected: + friend class Bits::Graph; + + Inherits () + { + } + + Void + set_left_node (Type& n) + { + derived_ = &n; + } + + Void + set_right_node (Type& n) + { + base_ = &n; + } + + private: + Type* base_; + Type* derived_; + }; + + + class Extends: public virtual Inherits + { + protected: + friend class Bits::Graph; + + Extends () + { + } + }; + + class Restricts: public virtual Inherits + { + protected: + typedef + Cult::Containers::Map + Facets; + + public: + typedef + Facets::Iterator + FacetIterator; + + Boolean + facet_empty () + { + return facets_.empty (); + } + + FacetIterator + facet_begin () + { + return facets_.begin (); + } + + FacetIterator + facet_end () + { + return facets_.end (); + } + + FacetIterator + facet_find (WideString const& name) + { + return facets_.find (name); + } + + Void + facet_insert (String const& name, String const& value) + { + facets_[name] = value; + } + + protected: + friend class Bits::Graph; + + Restricts () + { + } + + protected: + Facets facets_; + }; + + + // + // + class Member; + class Namespace; + + class BelongsToNamespace: public virtual Edge + { + public: + Member& + member () const + { + assert (member_ != 0); + return *member_; + } + + Namespace& + namespace_ () const + { + assert (namespace__ != 0); + return *namespace__; + } + + protected: + friend class Bits::Graph; + + BelongsToNamespace () + : member_ (0), namespace__ (0) + { + } + + Void + set_left_node (Member& n) + { + member_ = &n; + } + + Void + set_right_node (Namespace& n) + { + namespace__ = &n; + } + + private: + Member* member_; + Namespace* namespace__; + }; + + // + // + class Member: public virtual Instance + { + public: + // Member is global either if it is defined outside any type + // or it is a ref="" of a global member. + // + Boolean + global_p () const + { + return global_; + } + + Boolean + qualified_p () const + { + return qualified_; + } + + // Note that only qualified members belong to a namespace. + // + Namespace& + namespace_ () const + { + assert (belongs_to_namespace_ != 0); + return belongs_to_namespace_->namespace_ (); + } + + + // Default and fixed value API. Note that the fixed value semantics + // is a superset of the default value semantics. As such setting the + // fixed value appears as if the default value was also set. + // + Boolean + default_p () const + { + return value_type_ != ValueType::none; + } + + Boolean + fixed_p () const + { + return value_type_ == ValueType::fixed; + } + + struct NoValue {}; + + WideString + value () const + { + if (value_type_ != ValueType::none) + return value_; + else + throw NoValue (); + } + + // + // + Void + default_ (WideString const& v) + { + value_ = v; + value_type_ = ValueType::default_; + } + + Void + fixed (WideString const& v) + { + value_ = v; + value_type_ = ValueType::fixed; + } + + protected: + friend class Bits::Graph; + + Member (Boolean global, Boolean qualified) + : global_ (global), + qualified_ (qualified), + belongs_to_namespace_ (0), + value_type_ (ValueType::none) + { + } + + Void + add_edge_left (BelongsToNamespace& e) + { + // In the parser we sometimes re-add the same adge. + // + belongs_to_namespace_ = &e; + } + + using Instance::add_edge_left; + + private: + Boolean global_; + Boolean qualified_; + BelongsToNamespace* belongs_to_namespace_; + + struct ValueType + { + enum Value + { + none, + default_, + fixed + }; + }; + + WideString value_; + ValueType::Value value_type_; + }; + + + // Parametric types. + // + + class Specialization: public virtual Type + { + typedef + Cult::Containers::Vector + Argumented; + + public: + typedef + Bits::PointerIterator + ArgumentedIterator; + + typedef + Bits::PointerIterator + ArgumentedConstIterator; + + ArgumentedIterator + argumented_begin () + { + return argumented_.begin (); + } + + ArgumentedConstIterator + argumented_begin () const + { + return argumented_.begin (); + } + + ArgumentedIterator + argumented_end () + { + return argumented_.end (); + } + + ArgumentedConstIterator + argumented_end () const + { + return argumented_.end (); + } + + // Shortcut for one-argument specializations. + // + Arguments& + argumented () const + { + return *argumented_[0]; + } + + protected: + friend class Bits::Graph; + + using Type::add_edge_right; + + Void + add_edge_right (Arguments& a) + { + argumented_.push_back (&a); + } + + Void + remove_edge_right (Arguments&); + + public: + Void + add_edge_right (Arguments& a, ArgumentedIterator const& pos) + { + argumented_.insert (pos.base (), &a); + } + + private: + Argumented argumented_; + }; + + + class Arguments: public virtual Edge + { + public: + Type& + type () const + { + return *type_; + } + + Specialization& + specialization () const + { + return *specialization_; + } + + protected: + friend class Bits::Graph; + + void + set_left_node (Type& n) + { + type_ = &n; + } + + void + clear_left_node (Type& n) + { + assert (type_ == &n); + type_ = 0; + } + + void + set_right_node (Specialization& s) + { + specialization_ = &s; + } + + void + clear_right_node (Specialization& s) + { + assert (specialization_ == &s); + specialization_ = 0; + } + + private: + Type* type_; + Specialization* specialization_; + }; + + + // + // + class AnyType: public virtual Type + { + protected: + friend class Bits::Graph; + + AnyType (Path const& file, UnsignedLong line, UnsignedLong column) + : Node (file, line, column) + { + } + + AnyType () // For virtual inheritance. + { + } + }; + + + // + // + class AnySimpleType: public virtual Type + { + protected: + friend class Bits::Graph; + + AnySimpleType (Path const& file, UnsignedLong line, UnsignedLong column) + : Node (file, line, column) + { + } + + AnySimpleType () // For virtual inheritance. + { + } + }; + } +} + +// ADL won't find it because Path is a typedef. Note that this +// function prints in native format. +// +std::wostream& +operator<< (std::wostream& os, XSDFrontend::SemanticGraph::Path const& path); + +#endif // XSD_FRONTEND_SEMANTIC_GRAPH_ELEMENTS_HXX diff --git a/libxsd-frontend/xsd-frontend/semantic-graph/enumeration.cxx b/libxsd-frontend/xsd-frontend/semantic-graph/enumeration.cxx new file mode 100644 index 0000000..adcf71e --- /dev/null +++ b/libxsd-frontend/xsd-frontend/semantic-graph/enumeration.cxx @@ -0,0 +1,67 @@ +// file : xsd-frontend/semantic-graph/enumeration.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include + +namespace XSDFrontend +{ + namespace SemanticGraph + { + namespace RTTI = Cult::RTTI; + + using RTTI::Access; + using RTTI::TypeInfo; + + namespace + { + // Enumeration + // + struct EnumerationInit + { + EnumerationInit () + { + TypeInfo ti (typeid (Enumeration)); + ti.add_base (Access::public_, true, typeid (Complex)); + RTTI::insert (ti); + } + + } enumeration_init_; + + + // Enumerator + // + struct EnumeratorInit + { + EnumeratorInit () + { + TypeInfo ti (typeid (Enumerator)); + ti.add_base (Access::public_, true, typeid (Instance)); + RTTI::insert (ti); + } + + } enumerator_init_; + } + + + // Enumeration + // + + Enumeration:: + Enumeration (Path const& file, UnsignedLong line, UnsignedLong column) + : Node (file, line, column) + { + } + + + // Enumerator + // + + Enumerator:: + Enumerator (Path const& file, UnsignedLong line, UnsignedLong column) + : Node (file, line, column) + { + } + } +} diff --git a/libxsd-frontend/xsd-frontend/semantic-graph/enumeration.hxx b/libxsd-frontend/xsd-frontend/semantic-graph/enumeration.hxx new file mode 100644 index 0000000..a21e8f3 --- /dev/null +++ b/libxsd-frontend/xsd-frontend/semantic-graph/enumeration.hxx @@ -0,0 +1,35 @@ +// file : xsd-frontend/semantic-graph/enumeration.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_FRONTEND_SEMANTIC_GRAPH_ENUMERATION_HXX +#define XSD_FRONTEND_SEMANTIC_GRAPH_ENUMERATION_HXX + +#include +#include + +namespace XSDFrontend +{ + namespace SemanticGraph + { + class Enumeration: public virtual Complex + { + protected: + friend class Bits::Graph; + + Enumeration (Path const& file, UnsignedLong line, UnsignedLong column); + }; + + + class Enumerator: public virtual Instance + { + protected: + friend class Bits::Graph; + + Enumerator (Path const& file, UnsignedLong line, UnsignedLong column); + }; + } +} + +#endif // XSD_FRONTEND_SEMANTIC_GRAPH_ENUMERATION_HXX diff --git a/libxsd-frontend/xsd-frontend/semantic-graph/fundamental.cxx.m4 b/libxsd-frontend/xsd-frontend/semantic-graph/fundamental.cxx.m4 new file mode 100644 index 0000000..cc1316c --- /dev/null +++ b/libxsd-frontend/xsd-frontend/semantic-graph/fundamental.cxx.m4 @@ -0,0 +1,216 @@ +divert(-1) + +# file : xsd-frontend/semantic-graph/fundamental.cxx.m4 +# author : Boris Kolpackov +# copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +# license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +include(`fundamental.m4') + +define(`fundamental_type', + `fundamental_type_impl(`make_class_name(`$1')', `make_var_name(`$1')')') + + +define(`fundamental_type_impl', ` + + // $1 + // + namespace + { + struct $1Init + { + $1Init () + { + TypeInfo ti (typeid ($1)); + ti.add_base (Access::public_, true, typeid (Type)); + RTTI::insert (ti); + } + + } $2_init_; + } + + $1:: + $1 (Path const& file, + SemanticGraph::UnsignedLong line, + SemanticGraph::UnsignedLong column) + : Node (file, line, column) + { + }') + +divert(0)dnl +dnl +dnl +dnl +// file : xsd-frontend/semantic-graph/fundamental.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +// Note, that this file is automatically generated! +// + +#include + +namespace XSDFrontend +{ + namespace SemanticGraph + { + namespace Fundamental + { + namespace RTTI = Cult::RTTI; + + using RTTI::Access; + using RTTI::TypeInfo; + + + // Type + // + namespace + { + struct TypeInit + { + TypeInit () + { + TypeInfo ti (typeid (Type)); + ti.add_base (Access::public_, true, typeid (SemanticGraph::Type)); + RTTI::insert (ti); + } + + } any_type_init_; + } + + Type:: + Type () + { + } +dnl +dnl Integers. +dnl +fundamental_type(`byte') +fundamental_type(`unsigned byte') +fundamental_type(`short') +fundamental_type(`unsigned short') +fundamental_type(`int') +fundamental_type(`unsigned int') +fundamental_type(`long') +fundamental_type(`unsigned long') +fundamental_type(`integer') +fundamental_type(`non positive integer') +fundamental_type(`non negative integer') +fundamental_type(`positive integer') +fundamental_type(`negative integer') +dnl +dnl Boolean. +dnl +fundamental_type(`boolean') +dnl +dnl Floats. +dnl +fundamental_type(`float') +fundamental_type(`double') +fundamental_type(`decimal') +dnl +dnl Strings. +dnl +fundamental_type(`string') +fundamental_type(`normalized string') +fundamental_type(`token') +fundamental_type(`name') +fundamental_type(`name token') +fundamental_type(`name tokens') +fundamental_type(`NC name') +fundamental_type(`language') +dnl +dnl Qualified name. +dnl +fundamental_type(`q name') +dnl +dnl ID/IDREF. +dnl +fundamental_type(`id') + + + // IdRef + // + namespace + { + struct IdRefInit + { + IdRefInit () + { + TypeInfo ti (typeid (IdRef)); + ti.add_base (Access::public_, true, typeid (Type)); + ti.add_base (Access::public_, true, typeid (Specialization)); + RTTI::insert (ti); + } + + } id_ref_init_; + } + + IdRef:: + IdRef (Path const& file, + SemanticGraph::UnsignedLong line, + SemanticGraph::UnsignedLong column) + : Node (file, line, column) + { + } + + + // IdRefs + // + namespace + { + struct IdRefsInit + { + IdRefsInit () + { + TypeInfo ti (typeid (IdRefs)); + ti.add_base (Access::public_, true, typeid (Type)); + ti.add_base (Access::public_, true, typeid (Specialization)); + RTTI::insert (ti); + } + + } id_refs_init_; + } + + IdRefs:: + IdRefs (Path const& file, + SemanticGraph::UnsignedLong line, + SemanticGraph::UnsignedLong column) + : Node (file, line, column) + { + } +dnl +dnl URI. +dnl +fundamental_type(`any URI') +dnl +dnl Binary. +dnl +fundamental_type(`base 64 binary') +fundamental_type(`hex binary') +dnl +dnl Date/time. +dnl +fundamental_type(`date') +fundamental_type(`date time') +fundamental_type(`duration') +fundamental_type(`day') +fundamental_type(`month') +fundamental_type(`month day') +fundamental_type(`year') +fundamental_type(`year month') +fundamental_type(`time') +dnl +dnl Entity. +dnl +fundamental_type(`entity') +fundamental_type(`entities') +dnl +dnl Notation. +dnl +fundamental_type(`notation') +dnl + } + } +} diff --git a/libxsd-frontend/xsd-frontend/semantic-graph/fundamental.hxx.m4 b/libxsd-frontend/xsd-frontend/semantic-graph/fundamental.hxx.m4 new file mode 100644 index 0000000..f5a88a9 --- /dev/null +++ b/libxsd-frontend/xsd-frontend/semantic-graph/fundamental.hxx.m4 @@ -0,0 +1,165 @@ +divert(-1) + +# file : xsd-frontend/semantic-graph/fundamental.hxx.m4 +# author : Boris Kolpackov +# copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +# license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +include(`fundamental.m4') + +define(`fundamental_type', `fundamental_type_impl(`make_class_name(`$1')', `$1')') + +define(`fundamental_type_impl', ` + + // + // + class $1: public virtual Type + { + protected: + friend class Bits::Graph; + + $1 (Path const& file, + SemanticGraph::UnsignedLong line, + SemanticGraph::UnsignedLong column); + };') +divert(0)dnl +dnl +dnl +dnl +// file : xsd-frontend/semantic-graph/fundamental.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +// Note, that this file is automatically generated! +// + +#ifndef XSD_FRONTEND_SEMANTIC_GRAPH_FUNDAMENTAL_HXX +#define XSD_FRONTEND_SEMANTIC_GRAPH_FUNDAMENTAL_HXX + +#include + +namespace XSDFrontend +{ + namespace SemanticGraph + { + namespace Fundamental + { + // + // + class Type: public virtual SemanticGraph::Type + { + protected: + friend class Bits::Graph; + + Type (); + }; +dnl +dnl Integers. +dnl +fundamental_type(`byte') +fundamental_type(`unsigned byte') +fundamental_type(`short') +fundamental_type(`unsigned short') +fundamental_type(`int') +fundamental_type(`unsigned int') +fundamental_type(`long') +fundamental_type(`unsigned long') +fundamental_type(`integer') +fundamental_type(`non positive integer') +fundamental_type(`non negative integer') +fundamental_type(`positive integer') +fundamental_type(`negative integer') +dnl +dnl Boolean. +dnl +fundamental_type(`boolean') +dnl +dnl Floats. +dnl +fundamental_type(`float') +fundamental_type(`double') +fundamental_type(`decimal') +dnl +dnl Strings. +dnl +fundamental_type(`string') +fundamental_type(`normalized string') +fundamental_type(`token') +fundamental_type(`name') +fundamental_type(`name token') +fundamental_type(`name tokens') +fundamental_type(`NC name') +fundamental_type(`language') +dnl +dnl Qualified name. +dnl +fundamental_type(`q name') +dnl +dnl ID/IDREF. +dnl +fundamental_type(`id') + + + // + // + class IdRef: public virtual Type, + public virtual Specialization + { + protected: + friend class Bits::Graph; + + IdRef (Path const& file, + SemanticGraph::UnsignedLong line, + SemanticGraph::UnsignedLong column); + }; + + + // + // + class IdRefs: public virtual Type, + public virtual Specialization + { + protected: + friend class Bits::Graph; + + IdRefs (Path const& file, + SemanticGraph::UnsignedLong line, + SemanticGraph::UnsignedLong column); + }; +dnl +dnl URI. +dnl +fundamental_type(`any URI') +dnl +dnl Binary. +dnl +fundamental_type(`base 64 binary') +fundamental_type(`hex binary') +dnl +dnl Date/time. +dnl +fundamental_type(`date') +fundamental_type(`date time') +fundamental_type(`duration') +fundamental_type(`day') +fundamental_type(`month') +fundamental_type(`month day') +fundamental_type(`year') +fundamental_type(`year month') +fundamental_type(`time') +dnl +dnl Entity. +dnl +fundamental_type(`entity') +fundamental_type(`entities') +dnl +dnl Notation. +dnl +fundamental_type(`notation') +dnl + } + } +} + +#endif // XSD_FRONTEND_SEMANTIC_GRAPH_FUNDAMENTAL_HXX diff --git a/libxsd-frontend/xsd-frontend/semantic-graph/fundamental.m4 b/libxsd-frontend/xsd-frontend/semantic-graph/fundamental.m4 new file mode 100644 index 0000000..735b35d --- /dev/null +++ b/libxsd-frontend/xsd-frontend/semantic-graph/fundamental.m4 @@ -0,0 +1,18 @@ +# file : xsd-frontend/semantic-graph/fundamental.m4 +# author : Boris Kolpackov +# copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +# license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +define(`upcase', `translit(`$*', `a-z', `A-Z')') + + +define(`capitalize_word', + `regexp(`$1', `^\(.\)\(.*\)', `upcase(`\1')`\2'')') + + +define(`capitalize', + `patsubst(`$1', `\w+', `capitalize_word(`\&')')') + +define(`make_class_name', `patsubst(capitalize(`$1'), ` ')') + +define(`make_var_name', `patsubst(`$1', ` ', `_')') diff --git a/libxsd-frontend/xsd-frontend/semantic-graph/list.cxx b/libxsd-frontend/xsd-frontend/semantic-graph/list.cxx new file mode 100644 index 0000000..3184041 --- /dev/null +++ b/libxsd-frontend/xsd-frontend/semantic-graph/list.cxx @@ -0,0 +1,37 @@ +// file : xsd-frontend/semantic-graph/list.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include + +namespace XSDFrontend +{ + namespace SemanticGraph + { + namespace RTTI = Cult::RTTI; + + using RTTI::Access; + using RTTI::TypeInfo; + + namespace + { + struct ListInit + { + ListInit () + { + TypeInfo ti (typeid (List)); + ti.add_base (Access::public_, true, typeid (Specialization)); + RTTI::insert (ti); + } + + } list_init_; + } + + List:: + List (Path const& file, UnsignedLong line, UnsignedLong column) + : Node (file, line, column) + { + } + } +} diff --git a/libxsd-frontend/xsd-frontend/semantic-graph/list.hxx b/libxsd-frontend/xsd-frontend/semantic-graph/list.hxx new file mode 100644 index 0000000..3ba0c02 --- /dev/null +++ b/libxsd-frontend/xsd-frontend/semantic-graph/list.hxx @@ -0,0 +1,25 @@ +// file : xsd-frontend/semantic-graph/list.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_FRONTEND_SEMANTIC_GRAPH_LIST_HXX +#define XSD_FRONTEND_SEMANTIC_GRAPH_LIST_HXX + +#include + +namespace XSDFrontend +{ + namespace SemanticGraph + { + class List: public virtual Specialization + { + protected: + friend class Bits::Graph; + + List (Path const& file, UnsignedLong line, UnsignedLong column); + }; + } +} + +#endif // XSD_FRONTEND_SEMANTIC_GRAPH_LIST_HXX diff --git a/libxsd-frontend/xsd-frontend/semantic-graph/namespace.cxx b/libxsd-frontend/xsd-frontend/semantic-graph/namespace.cxx new file mode 100644 index 0000000..789b5d8 --- /dev/null +++ b/libxsd-frontend/xsd-frontend/semantic-graph/namespace.cxx @@ -0,0 +1,37 @@ +// file : xsd-frontend/semantic-graph/namespace.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include + +namespace XSDFrontend +{ + namespace SemanticGraph + { + namespace RTTI = Cult::RTTI; + + using RTTI::Access; + using RTTI::TypeInfo; + + namespace + { + struct NamespaceInit + { + NamespaceInit () + { + TypeInfo ti (typeid (Namespace)); + ti.add_base (Access::public_, true, typeid (Scope)); + RTTI::insert (ti); + } + + } namespace_init_; + } + + Namespace:: + Namespace (Path const& file, UnsignedLong line, UnsignedLong column) + : Node (file, line, column) + { + } + } +} diff --git a/libxsd-frontend/xsd-frontend/semantic-graph/namespace.hxx b/libxsd-frontend/xsd-frontend/semantic-graph/namespace.hxx new file mode 100644 index 0000000..25bd1c0 --- /dev/null +++ b/libxsd-frontend/xsd-frontend/semantic-graph/namespace.hxx @@ -0,0 +1,32 @@ +// file : xsd-frontend/semantic-graph/namespace.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_FRONTEND_SEMANTIC_GRAPH_NAMESPACE_HXX +#define XSD_FRONTEND_SEMANTIC_GRAPH_NAMESPACE_HXX + +#include + +namespace XSDFrontend +{ + namespace SemanticGraph + { + class Namespace : public virtual Scope + { + protected: + friend class Bits::Graph; + + Namespace (Path const& file, UnsignedLong line, UnsignedLong column); + + Void + add_edge_right (BelongsToNamespace&) + { + } + + using Scope::add_edge_right; + }; + } +} + +#endif // XSD_FRONTEND_SEMANTIC_GRAPH_NAMESPACE_HXX diff --git a/libxsd-frontend/xsd-frontend/semantic-graph/particle.cxx b/libxsd-frontend/xsd-frontend/semantic-graph/particle.cxx new file mode 100644 index 0000000..f8c93de --- /dev/null +++ b/libxsd-frontend/xsd-frontend/semantic-graph/particle.cxx @@ -0,0 +1,61 @@ +// file : xsd-frontend/semantic-graph/particle.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2006-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include + +namespace XSDFrontend +{ + namespace SemanticGraph + { + namespace RTTI = Cult::RTTI; + + using RTTI::Access; + using RTTI::TypeInfo; + + // ContainsParticle + // + namespace + { + struct ContainsParticleInit + { + ContainsParticleInit () + { + TypeInfo ti (typeid (ContainsParticle)); + ti.add_base (Access::public_, true, typeid (Edge)); + RTTI::insert (ti); + } + + } contains_particle_init_; + } + + ContainsParticle:: + ContainsParticle (UnsignedLong min, UnsignedLong max) + : particle_ (0), compositor_ (0), min_ (min), max_ (max) + { + } + + // Particle + // + namespace + { + struct ParticleInit + { + ParticleInit () + { + TypeInfo ti (typeid (Particle)); + ti.add_base (Access::public_, true, typeid (Node)); + RTTI::insert (ti); + } + + } particle_init_; + } + + Particle:: + Particle () + : contained_particle_ (0) + { + } + } +} diff --git a/libxsd-frontend/xsd-frontend/semantic-graph/particle.hxx b/libxsd-frontend/xsd-frontend/semantic-graph/particle.hxx new file mode 100644 index 0000000..df48de4 --- /dev/null +++ b/libxsd-frontend/xsd-frontend/semantic-graph/particle.hxx @@ -0,0 +1,145 @@ +// file : xsd-frontend/semantic-graph/particle.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2006-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_FRONTEND_SEMANTIC_GRAPH_PARTICLE_HXX +#define XSD_FRONTEND_SEMANTIC_GRAPH_PARTICLE_HXX + +#include + +namespace XSDFrontend +{ + namespace SemanticGraph + { + // + // + class Particle; + class Compositor; + + + // + // + class ContainsParticle: public virtual Edge + { + public: + Particle& + particle () const + { + return *particle_; + } + + Compositor& + compositor () const + { + return *compositor_; + } + + public: + UnsignedLong + min () const + { + return min_; + } + + UnsignedLong + max () const + { + return max_; + } + + protected: + friend class Bits::Graph; + + ContainsParticle (UnsignedLong min, UnsignedLong max); + + Void + set_left_node (Compositor& n) + { + compositor_ = &n; + } + + Void + set_right_node (Particle& n) + { + particle_ = &n; + } + + Void + clear_left_node (Compositor& n) + { + assert (compositor_ == &n); + compositor_ = 0; + } + + Void + clear_right_node (Particle& n) + { + assert (particle_ == &n); + particle_ = 0; + } + + private: + Particle* particle_; + Compositor* compositor_; + UnsignedLong min_, max_; + }; + + // + // + class Particle: public virtual Node + { + public: + Boolean + contained_particle_p () + { + return contained_particle_ != 0; + } + + ContainsParticle& + contained_particle () + { + assert (contained_particle_ != 0); + return *contained_particle_; + } + + public: + UnsignedLong + min () const + { + assert (contained_particle_ != 0); + return contained_particle_->min (); + } + + UnsignedLong + max () const + { + assert (contained_particle_ != 0); + return contained_particle_->max (); + } + + protected: + friend class Bits::Graph; + + Particle (); + + Void + add_edge_right (ContainsParticle& e) + { + contained_particle_ = &e; + } + + Void + remove_edge_right (ContainsParticle& e) + { + assert (contained_particle_ == &e); + contained_particle_ = 0; + } + + private: + ContainsParticle* contained_particle_; + }; + } +} + +#endif // XSD_FRONTEND_SEMANTIC_GRAPH_PARTICLE_HXX diff --git a/libxsd-frontend/xsd-frontend/semantic-graph/schema.cxx b/libxsd-frontend/xsd-frontend/semantic-graph/schema.cxx new file mode 100644 index 0000000..f812797 --- /dev/null +++ b/libxsd-frontend/xsd-frontend/semantic-graph/schema.cxx @@ -0,0 +1,139 @@ +// file : xsd-frontend/semantic-graph/schema.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include + +namespace XSDFrontend +{ + namespace SemanticGraph + { + namespace RTTI = Cult::RTTI; + + using RTTI::Access; + using RTTI::TypeInfo; + + namespace + { + // Uses + // + struct UsesInit + { + UsesInit () + { + TypeInfo ti (typeid (Uses)); + ti.add_base (Access::public_, true, typeid (Edge)); + RTTI::insert (ti); + } + + } uses_init_; + + + // Implies + // + struct ImpliesInit + { + ImpliesInit () + { + TypeInfo ti (typeid (Implies)); + ti.add_base (Access::public_, true, typeid (Uses)); + RTTI::insert (ti); + } + + } implies_init_; + + + // Sources + // + struct SourcesInit + { + SourcesInit () + { + TypeInfo ti (typeid (Sources)); + ti.add_base (Access::public_, true, typeid (Uses)); + RTTI::insert (ti); + } + + } sources_init_; + + + // Includes + // + struct IncludesInit + { + IncludesInit () + { + TypeInfo ti (typeid (Includes)); + ti.add_base (Access::public_, true, typeid (Uses)); + RTTI::insert (ti); + } + + } includes_init_; + + + // Imports + // + struct ImportsInit + { + ImportsInit () + { + TypeInfo ti (typeid (Imports)); + ti.add_base (Access::public_, true, typeid (Uses)); + RTTI::insert (ti); + } + + } imports_init_; + + + // Schema + // + struct SchemaInit + { + SchemaInit () + { + TypeInfo ti (typeid (Schema)); + ti.add_base (Access::public_, true, typeid (Scope)); + RTTI::insert (ti); + } + + } schema_init_; + } + + + // Schema + // + Schema::NamesIteratorPair Schema:: + find (Name const& name) const + { + // Here we are going to create an illusion that the namespace + // hierarchy is flat. + names_.clear (); + schemas_.clear (); + + find_ (name, names_, schemas_); + + return NamesIteratorPair (NamesConstIterator (names_.begin ()), + NamesConstIterator (names_.end ())); + } + + Void Schema:: + find_ (Name const& name, NamesList& names, SchemaSet& set) const + { + set.insert (this); + + // Check our own namespace first so it will end up first in the list. + // + NamesIteratorPair pair (Scope::find (name)); + names.insert (names.end (), pair.first.base (), pair.second.base ()); + + for (UsesIterator i (uses_begin ()), end (uses_end ()); i != end; ++i) + { + Schema& s (i->schema ()); + + if (set.find (&s) == set.end ()) + s.find_ (name, names, set); + } + } + } +} diff --git a/libxsd-frontend/xsd-frontend/semantic-graph/schema.hxx b/libxsd-frontend/xsd-frontend/semantic-graph/schema.hxx new file mode 100644 index 0000000..10d2f75 --- /dev/null +++ b/libxsd-frontend/xsd-frontend/semantic-graph/schema.hxx @@ -0,0 +1,281 @@ +// file : xsd-frontend/semantic-graph/schema.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_FRONTEND_SEMANTIC_GRAPH_SCHEMA_HXX +#define XSD_FRONTEND_SEMANTIC_GRAPH_SCHEMA_HXX + +#include + +#include +#include + +namespace XSDFrontend +{ + namespace SemanticGraph + { + // + // + class Schema; + + + class Uses: public virtual Edge + { + public: + Schema& + user () const + { + return *user_; + } + + Schema& + schema () const + { + return *schema_; + } + + Path + path () const + { + return path_; + } + + protected: + friend class Bits::Graph; + + Uses (Path const& path) + : path_ (path) + { + } + + Void + set_left_node (Schema& s) + { + user_ = &s; + } + + Void + set_right_node (Schema& s) + { + schema_ = &s; + } + + private: + Path path_; + Schema* user_; + Schema* schema_; + }; + + + // + // + class Implies: public virtual Uses + { + protected: + friend class Bits::Graph; + + Implies (Path const& path) + : Uses (path) + { + } + }; + + + // + // + class Sources: public virtual Uses + { + protected: + friend class Bits::Graph; + + Sources (Path const& path) + : Uses (path) + { + } + }; + + + // + // + class Includes: public virtual Uses + { + protected: + friend class Bits::Graph; + + Includes (Path const& path) + : Uses (path) + { + } + }; + + + // + // + class Imports: public virtual Uses + { + protected: + friend class Bits::Graph; + + Imports (Path const& path) + : Uses (path) + { + } + }; + + + // + // + class Schema: public virtual Scope, + private Bits::Graph, + public NonCopyable + { + typedef + Cult::Containers::Vector + UsesList; + + typedef + Cult::Containers::Vector + UsedList; + + public: + Schema (Path const& file, UnsignedLong line, UnsignedLong column) + : SemanticGraph::Node (file, line, column) + { + } + + public: + typedef + Bits::PointerIterator + UsesIterator; + + UsesIterator + uses_begin () const + { + return uses_.begin (); + } + + UsesIterator + uses_end () const + { + return uses_.end (); + } + + typedef + Bits::PointerIterator + UsedIterator; + + UsedIterator + used_begin () const + { + return used_.begin (); + } + + UsedIterator + used_end () const + { + return used_.end (); + } + + Boolean + used_p () const + { + return used_begin () != used_end (); + } + + virtual NamesIteratorPair + find (Name const& name) const; + + public: + using Bits::Graph::new_edge; + using Bits::Graph::reset_left_node; + using Bits::Graph::reset_right_node; + using Bits::Graph::add_edge_left; + using Bits::Graph::add_edge_right; + using Bits::Graph::delete_node; + using Bits::Graph::delete_edge; + + template + T& + new_node (Path const& file, UnsignedLong line, UnsignedLong column) + { + return graph ().new_node (file, line, column); + } + + template + T& + new_node (Path const& file, UnsignedLong line, UnsignedLong column, + A0 const& a0) + { + return graph ().new_node (file, line, column, a0); + } + + template + T& + new_node (Path const& file, UnsignedLong line, UnsignedLong column, + A0 const& a0, A1 const& a1) + { + return graph ().new_node (file, line, column, a0, a1); + } + + template + T& + new_node (Path const& file, UnsignedLong line, UnsignedLong column, + A0 const& a0, A1 const& a1, A2 const& a2) + { + return graph ().new_node (file, line, column, a0, a1, a2); + } + + template + T& + new_node (Path const& file, UnsignedLong line, UnsignedLong column, + A0 const& a0, A1 const& a1, A2 const& a2, A3 const& a3) + { + return graph ().new_node (file, line, column, a0, a1, a2, a3); + } + + protected: + //@@ gcc bug #21146 + // + friend class Bits::Graph; + + using Scope::add_edge_left; + using Node::add_edge_right; + + Void + add_edge_left (Uses& e) + { + uses_.push_back (&e); + } + + Void + add_edge_right (Uses& e) + { + used_.push_back (&e); + } + + private: + Bits::Graph& + graph () + { + return *this; + } + + private: + UsesList uses_; + UsedList used_; + + private: + typedef Cult::Containers::Set SchemaSet; + + Void + find_ (Name const& name, NamesList&, SchemaSet&) const; + + mutable NamesList names_; + mutable SchemaSet schemas_; + }; + } +} + +#endif // XSD_FRONTEND_SEMANTIC_GRAPH_SCHEMA_HXX diff --git a/libxsd-frontend/xsd-frontend/semantic-graph/union.cxx b/libxsd-frontend/xsd-frontend/semantic-graph/union.cxx new file mode 100644 index 0000000..b4b4cf0 --- /dev/null +++ b/libxsd-frontend/xsd-frontend/semantic-graph/union.cxx @@ -0,0 +1,37 @@ +// file : xsd-frontend/semantic-graph/union.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include + +namespace XSDFrontend +{ + namespace SemanticGraph + { + namespace RTTI = Cult::RTTI; + + using RTTI::Access; + using RTTI::TypeInfo; + + namespace + { + struct UnionInit + { + UnionInit () + { + TypeInfo ti (typeid (Union)); + ti.add_base (Access::public_, true, typeid (Specialization)); + RTTI::insert (ti); + } + + } union_init_; + } + + Union:: + Union (Path const& file, UnsignedLong line, UnsignedLong column) + : Node (file, line, column) + { + } + } +} diff --git a/libxsd-frontend/xsd-frontend/semantic-graph/union.hxx b/libxsd-frontend/xsd-frontend/semantic-graph/union.hxx new file mode 100644 index 0000000..62df730 --- /dev/null +++ b/libxsd-frontend/xsd-frontend/semantic-graph/union.hxx @@ -0,0 +1,25 @@ +// file : xsd-frontend/semantic-graph/union.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_FRONTEND_SEMANTIC_GRAPH_UNION_HXX +#define XSD_FRONTEND_SEMANTIC_GRAPH_UNION_HXX + +#include + +namespace XSDFrontend +{ + namespace SemanticGraph + { + class Union: public virtual Specialization + { + protected: + friend class Bits::Graph; + + Union (Path const& file, UnsignedLong line, UnsignedLong column); + }; + } +} + +#endif // XSD_FRONTEND_SEMANTIC_GRAPH_UNION_HXX diff --git a/libxsd-frontend/xsd-frontend/transformations/anonymous.cxx b/libxsd-frontend/xsd-frontend/transformations/anonymous.cxx new file mode 100644 index 0000000..118fd5d --- /dev/null +++ b/libxsd-frontend/xsd-frontend/transformations/anonymous.cxx @@ -0,0 +1,739 @@ +// file : xsd-frontend/transformations/anonymous.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2006-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include + +#include +#include + +#include +#include + +using std::wcerr; +using std::endl; + +namespace XSDFrontend +{ + using namespace Cult; + + typedef WideString String; + + namespace + { + using Transformations::AnonymousNameTranslator; + + class Context + { + public: + Context (SemanticGraph::Schema& schema_, + SemanticGraph::Path const& file, + AnonymousNameTranslator& trans_, + Boolean du) + : schema_path_ (file), + ns_ (0), + failed_ (false), + trans (trans_), + detect_unstable (du), + schema (schema_), + schema_path (schema_path_), + ns (ns_), + failed (failed_) + { + + } + + protected: + Context (Context& c) + : trans (c.trans), + detect_unstable (c.detect_unstable), + schema (c.schema), + schema_path (c.schema_path), + ns (c.ns), + failed (c.failed) + { + } + + public: + struct UnstableConflict + { + UnstableConflict (SemanticGraph::Type& type) + : type_ (type) + { + } + + SemanticGraph::Type& + type () const + { + return type_; + } + + private: + SemanticGraph::Type& type_; + }; + + Boolean + conflict (String const& name) + { + using SemanticGraph::Type; + using SemanticGraph::Schema; + + if (Type* t1 = find (schema, name)) + { + // Check if this is a stable conflict. A conflict is unstable + // if a conflicting type is visible from the root schema but + // is not visible from the schema where the conflicting + // element is defined. + // + if (detect_unstable) + { + Schema& s (dynamic_cast (ns->scope ())); + + Type* t2 (find (s, name)); + + if (t1 != t2) + throw UnstableConflict (*t1); + } + + return true; + } + + return false; + } + + SemanticGraph::Type* + find (SemanticGraph::Schema& schema, String const& name) + { + using SemanticGraph::Type; + using SemanticGraph::Scope; + using SemanticGraph::Namespace; + + String ns_name (ns->name ()); + + // Get all namespaces across include/import hierarchy with + // our namespace name. + // + Scope::NamesIteratorPair nip (schema.find (ns_name)); + + for (; nip.first != nip.second; ++nip.first) + { + Namespace& ns (dynamic_cast (nip.first->named ())); + + Scope::NamesIteratorPair types (ns.find (name)); + + for (; types.first != types.second; ++types.first) + { + if (Type* t = dynamic_cast (&types.first->named ())) + { + return t; + } + } + } + + return 0; + } + + public: + SemanticGraph::Path + path (SemanticGraph::Nameable& n) + { + using SemanticGraph::Scope; + using SemanticGraph::Schema; + using SemanticGraph::Uses; + + Schema* schema (0); + + for (Scope* s (dynamic_cast (&n) + ? dynamic_cast (&n) : &n.scope ());; + s = &s->scope ()) + { + if ((schema = dynamic_cast (s))) + break; + } + + if (!schema->used_p ()) + return schema_path; + + Uses& u (*schema->used_begin ()); + return u.path (); + } + + public: + String + xpath (SemanticGraph::Nameable& n) + { + if (dynamic_cast (&n) != 0) + return L""; // There is a bug if you see this. + + assert (n.named_p ()); + + SemanticGraph::Scope& scope (n.scope ()); + + if (dynamic_cast (&scope) != 0) + return n.name (); + + return xpath (scope) + L"/" + n.name (); + } + + private: + SemanticGraph::Path const schema_path_; + SemanticGraph::Namespace* ns_; + Boolean failed_; + + public: + AnonymousNameTranslator& trans; + Boolean detect_unstable; + + public: + SemanticGraph::Schema& schema; + SemanticGraph::Path const& schema_path; + SemanticGraph::Namespace*& ns; + Boolean& failed; + }; + + + // Go into implied/included/imported schemas while making sure + // we don't process the same stuff more than once. + // + struct Uses: Traversal::Uses + { + virtual Void + traverse (Type& u) + { + SemanticGraph::Schema& s (u.schema ()); + + if (!s.context ().count ("xsd-frontend-anonymous-seen")) + { + s.context ().set ("xsd-frontend-anonymous-seen", true); + Traversal::Uses::traverse (u); + } + } + }; + + // Keep track which namespace we are in. + // + struct Namespace: Traversal::Namespace + { + Namespace (SemanticGraph::Namespace*& ns) + : ns_ (ns) + { + } + + Void + pre (SemanticGraph::Namespace& ns) + { + ns_ = &ns; + } + + Void + post (SemanticGraph::Namespace&) + { + ns_ = 0; + } + + private: + SemanticGraph::Namespace*& ns_; + }; + + // + // + struct Type: Traversal::List, + Traversal::Union, + Traversal::Complex, + protected virtual Context + { + Type (Context& c) + : Context (c) + { + } + + virtual Void + traverse (SemanticGraph::List& l) + { + SemanticGraph::Type& t (l.argumented ().type ()); + + //@@ This IDREF stuff is really ugly! + // + if (!t.named_p () && + !t.is_a () && + !t.is_a ()) + { + try + { + // Run the name through the translation service. + // + SemanticGraph::Path file (path (l)); + String file_str; + + // Try to use the portable representation of the path. If that + // fails, fall back to the native representation. + // + try + { + file_str = file.string (); + } + catch (SemanticGraph::InvalidPath const&) + { +#if !defined(BOOST_FILESYSTEM_VERSION) || BOOST_FILESYSTEM_VERSION == 2 + file_str = file.native_file_string (); +#else + file_str = file.string (); +#endif + } + + String name ( + trans.translate ( + file_str, ns->name (), l.name () + L"_item", xpath (l))); + + // Make sure the name is unique. + // + UnsignedLong n (1); + String escaped (name); + + while (conflict (escaped)) + { + std::wostringstream os; + os << n++; + escaped = name + os.str (); + } + + t.context ().set ("anonymous", true); + schema.new_edge (*ns, t, escaped); + } + catch (UnstableConflict const& ex) + { + SemanticGraph::Type& t (ex.type ()); + + wcerr << l.file () << ":" << l.line () << ":" << l.column () + << ": error: list type name '" << xpath (l) << "' " + << "creates an unstable conflict when used as a base " + << "for the item type name" + << endl; + + wcerr << t.file () << ":" << t.line () << ":" << t.column () + << ": info: conflicting type is defined here" << endl; + + wcerr << l.file () << ":" << l.line () << ":" << l.column () + << ": info: " + << "use --anonymous-regex to resolve this conflict" + << endl; + + wcerr << l.file () << ":" << l.line () << ":" << l.column () + << ": info: " + << "and don't forget to pass the same option when " + << "translating '" << l.file ().leaf () << "' and all " + << "the schemas that refer to it" << endl; + + failed = true; + } + } + } + + virtual Void + traverse (SemanticGraph::Union& u) + { + String file_str; + + for (SemanticGraph::Union::ArgumentedIterator i ( + u.argumented_begin ()); i != u.argumented_end (); ++i) + { + SemanticGraph::Type& t (i->type ()); + + if (!t.named_p () && + !t.is_a () && + !t.is_a ()) + { + try + { + // Run the name through the translation service. + // + + if (!file_str) + { + SemanticGraph::Path file (path (u)); + + // Try to use the portable representation of the path. If + // that fails, fall back to the native representation. + // + try + { + file_str = file.string (); + } + catch (SemanticGraph::InvalidPath const&) + { +#if !defined(BOOST_FILESYSTEM_VERSION) || BOOST_FILESYSTEM_VERSION == 2 + file_str = file.native_file_string (); +#else + file_str = file.string (); +#endif + } + } + + String name ( + trans.translate ( + file_str, ns->name (), u.name () + L"_member", xpath (u))); + + // Make sure the name is unique. + // + UnsignedLong n (1); + String escaped (name); + + while (conflict (escaped)) + { + std::wostringstream os; + os << n++; + escaped = name + os.str (); + } + + t.context ().set ("anonymous", true); + schema.new_edge (*ns, t, escaped); + } + catch (UnstableConflict const& ex) + { + SemanticGraph::Type& t (ex.type ()); + + wcerr << u.file () << ":" << u.line () << ":" << u.column () + << ": error: union type name '" << xpath (u) << "' " + << "creates an unstable conflict when used as a base " + << "for the member type name" + << endl; + + wcerr << t.file () << ":" << t.line () << ":" << t.column () + << ": info: conflicting type is defined here" << endl; + + wcerr << u.file () << ":" << u.line () << ":" << u.column () + << ": info: " + << "use --anonymous-regex to resolve this conflict" + << endl; + + wcerr << u.file () << ":" << u.line () << ":" << u.column () + << ": info: " + << "and don't forget to pass the same option when " + << "translating '" << u.file ().leaf () << "' and all " + << "the schemas that refer to it" << endl; + + failed = true; + } + } + } + } + + virtual Void + traverse (SemanticGraph::Complex& c) + { + if (!c.inherits_p ()) + return; + + SemanticGraph::Type& t (c.inherits ().base ()); + + //@@ This IDREF stuff is really ugly! + // + if (!t.named_p () && + !t.is_a () && + !t.is_a ()) + { + try + { + // Run the name through the translation service. + // + SemanticGraph::Path file (path (c)); + String file_str; + + // Try to use the portable representation of the path. If that + // fails, fall back to the native representation. + // + try + { + file_str = file.string (); + } + catch (SemanticGraph::InvalidPath const&) + { +#if !defined(BOOST_FILESYSTEM_VERSION) || BOOST_FILESYSTEM_VERSION == 2 + file_str = file.native_file_string (); +#else + file_str = file.string (); +#endif + } + + String name ( + trans.translate ( + file_str, ns->name (), c.name () + L"_base", xpath (c))); + + // Make sure the name is unique. + // + UnsignedLong n (1); + String escaped (name); + + while (conflict (escaped)) + { + std::wostringstream os; + os << n++; + escaped = name + os.str (); + } + + t.context ().set ("anonymous", true); + schema.new_edge (*ns, t, escaped); + } + catch (UnstableConflict const& ex) + { + SemanticGraph::Type& t (ex.type ()); + + wcerr << c.file () << ":" << c.line () << ":" << c.column () + << ": error: simple type name '" << xpath (c) << "' " + << "creates an unstable conflict when used as a base " + << "for the base type name" + << endl; + + wcerr << t.file () << ":" << t.line () << ":" << t.column () + << ": info: conflicting type is defined here" << endl; + + wcerr << c.file () << ":" << c.line () << ":" << c.column () + << ": info: " + << "use --anonymous-regex to resolve this conflict" + << endl; + + wcerr << c.file () << ":" << c.line () << ":" << c.column () + << ": info: " + << "and don't forget to pass the same option when " + << "translating '" << c.file ().leaf () << "' and all " + << "the schemas that refer to it" << endl; + + failed = true; + } + } + } + }; + + + // + // + struct Member: Traversal::Element, + Traversal::Attribute, + protected virtual Context + { + Member (Context& c) + : Context (c) + { + } + + virtual Void + traverse (SemanticGraph::Element& e) + { + SemanticGraph::Type& t (e.type ()); + + //@@ This IDREF stuff is really ugly! + // + if (!t.named_p () && + !t.is_a () && + !t.is_a ()) + { + try + { + traverse_ (e); + } + catch (UnstableConflict const& ex) + { + SemanticGraph::Type& t (ex.type ()); + + wcerr << e.file () << ":" << e.line () << ":" << e.column () + << ": error: element name '" << xpath (e) << "' " + << "creates an unstable conflict when used as a type name" + << endl; + + wcerr << t.file () << ":" << t.line () << ":" << t.column () + << ": info: conflicting type is defined here" << endl; + + wcerr << e.file () << ":" << e.line () << ":" << e.column () + << ": info: " + << "use --anonymous-regex to resolve this conflict" + << endl; + + wcerr << e.file () << ":" << e.line () << ":" << e.column () + << ": info: " + << "and don't forget to pass the same option when " + << "translating '" << e.file ().leaf () << "' and all " + << "the schemas that refer to it" << endl; + + failed = true; + } + } + } + + virtual Void + traverse (SemanticGraph::Attribute& a) + { + SemanticGraph::Type& t (a.type ()); + + //@@ This IDREF stuff us really ugly! + // + if (!t.named_p () && + !t.is_a () && + !t.is_a ()) + { + try + { + traverse_ (a); + } + catch (UnstableConflict const& ex) + { + SemanticGraph::Type& t (ex.type ()); + + wcerr << a.file () << ":" << a.line () << ":" << a.column () + << ": error: attribute name '" << xpath (a) << "' " + << "creates an unstable conflict when used as a type name" + << endl; + + wcerr << t.file () << ":" << t.line () << ":" << t.column () + << ": info: conflicting type is defined here" << endl; + + wcerr << a.file () << ":" << a.line () << ":" << a.column () + << ": info: " + << "use --anonymous-regex to resolve this conflict" + << endl; + + wcerr << a.file () << ":" << a.line () << ":" << a.column () + << ": info: " + << "and don't forget to pass the same option when " + << "translating '" << a.file ().leaf () << "' and all " + << "the schemas that refer to it" << endl; + + failed = true; + } + } + } + + Void + traverse_ (SemanticGraph::Member& m) + { + using SemanticGraph::Type; + + Type& t (m.type ()); + + // Normally this will be the member which also "defined" the type. + // However, in some cases of cyclic schema inclusion, this does + // not happen. As a result we need an extra check that will make + // sure we create the Names edge in the same Schema node as the + // one which contains the member which initially defined this + // type. See the cyclic-inclusion test for an example. + // + + // Find the first member that this type classifies. + // + for (Type::ClassifiesIterator i (t.classifies_begin ()); + i != t.classifies_end (); ++i) + { + SemanticGraph::Instance& inst (i->instance ()); + + if (inst.is_a ()) + { + // If it is the same member as the one we are traversing, + // then continue. + // + if (&inst == &m) + break; + else + return; + } + } + + // Run the name through the translation service. + // + SemanticGraph::Path file (path (m)); + String file_str; + + // Try to use the portable representation of the path. If that + // fails, fall back to the native representation. + // + try + { + file_str = file.string (); + } + catch (SemanticGraph::InvalidPath const&) + { +#if !defined(BOOST_FILESYSTEM_VERSION) || BOOST_FILESYSTEM_VERSION == 2 + file_str = file.native_file_string (); +#else + file_str = file.string (); +#endif + } + + String name ( + trans.translate (file_str, ns->name (), m.name (), xpath (m))); + + // Make sure the name is unique. + // + UnsignedLong n (1); + String escaped (name); + + while (conflict (escaped)) + { + std::wostringstream os; + os << n++; + escaped = name + os.str (); + } + + t.context ().set ("anonymous", true); + schema.new_edge (*ns, t, escaped); + } + }; + } + + namespace Transformations + { + Anonymous:: + Anonymous (AnonymousNameTranslator& trans) + : trans_ (trans) + { + } + + Void Anonymous:: + transform (SemanticGraph::Schema& s, + SemanticGraph::Path const& f, + Boolean duc) + { + Context ctx (s, f, trans_, duc); + + Traversal::Schema schema; + Uses uses; + + schema >> uses >> schema; + + Traversal::Names schema_names; + Namespace ns (ctx.ns); + Traversal::Names ns_names_member; + Traversal::Names ns_names_type; + + schema >> schema_names >> ns; + ns >> ns_names_member; + ns >> ns_names_type; + + Type type (ctx); + ns_names_type >> type; + + Traversal::Scope scope; // Goes to both types and groups. + Member member (ctx); + + ns_names_member >> scope; + ns_names_member >> member; + + Traversal::Names names; + + scope >> names >> member; + + // Some twisted schemas do recusive inclusions. + // + s.context ().set ("xsd-frontend-anonymous-seen", true); + + schema.dispatch (s); + + if (ctx.failed) + throw Failed (); + } + + AnonymousNameTranslator:: + ~AnonymousNameTranslator () + { + } + } +} diff --git a/libxsd-frontend/xsd-frontend/transformations/anonymous.hxx b/libxsd-frontend/xsd-frontend/transformations/anonymous.hxx new file mode 100644 index 0000000..2409822 --- /dev/null +++ b/libxsd-frontend/xsd-frontend/transformations/anonymous.hxx @@ -0,0 +1,60 @@ +// file : xsd-frontend/transformations/anonymous.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2006-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_FRONTEND_TRANSFORMATIONS_ANONYMOUS_HXX +#define XSD_FRONTEND_TRANSFORMATIONS_ANONYMOUS_HXX + +#include + +#include // Path +#include + +namespace XSDFrontend +{ + namespace Transformations + { + using namespace Cult::Types; + + class AnonymousNameTranslator + { + public: + virtual + ~AnonymousNameTranslator (); + + // The file argument is empty for the currect translation + // unit. + // + virtual WideString + translate (WideString const& file, + WideString const& ns, + WideString const& name, + WideString const& xpath) = 0; + }; + + // This transformation morphs anonymous types into named ones + // with the names derived from the enclosing attributes and + // elements. If the detect_unstable_conflicts argument is true + // then the transformation detects and reports unstable conflicts + // in name assignment. + // + class Anonymous + { + public: + struct Failed {}; + + Anonymous (AnonymousNameTranslator&); + + Void + transform (SemanticGraph::Schema&, + SemanticGraph::Path const&, + Boolean detect_unstable_conflicts); + + private: + AnonymousNameTranslator& trans_; + }; + } +} + +#endif // XSD_FRONTEND_TRANSFORMATIONS_ANONYMOUS_HXX diff --git a/libxsd-frontend/xsd-frontend/transformations/enum-synthesis.cxx b/libxsd-frontend/xsd-frontend/transformations/enum-synthesis.cxx new file mode 100644 index 0000000..e10b9d3 --- /dev/null +++ b/libxsd-frontend/xsd-frontend/transformations/enum-synthesis.cxx @@ -0,0 +1,249 @@ +// file : xsd-frontend/transformations/enum-synthesis.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2006-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include + +#include +#include + +#include + +namespace XSDFrontend +{ + using namespace Cult; + typedef WideString String; + + namespace + { + typedef Cult::Containers::Set Enumerators; + + struct Enumerator: Traversal::Enumerator + { + Enumerator (SemanticGraph::Schema& s, + SemanticGraph::Enumeration& e, + Enumerators& enumerators) + : schema_ (s), enum_ (e), enumerators_ (enumerators) + { + } + + virtual Void + traverse (Type& e) + { + String const& name (e.name ()); + + if (enumerators_.find (name) == enumerators_.end ()) + { + enumerators_.insert (name); + + // Clone the enumerator and add it to enum_. + // + Type& c (schema_.new_node (e.file (), e.line (), e.column ())); + + schema_.new_edge (enum_, c, name); + schema_.new_edge (c, enum_); + + if (e.annotated_p ()) + schema_.new_edge (e.annotation (), c); + } + } + + private: + SemanticGraph::Schema& schema_; + SemanticGraph::Enumeration& enum_; + Enumerators& enumerators_; + }; + + // + // + struct Union: Traversal::Union + { + Union (SemanticGraph::Schema& schema) + : schema_ (schema) + { + } + + virtual Void + traverse (Type& u) + { + using SemanticGraph::Enumeration; + + SemanticGraph::Context& uc (u.context ()); + + if (uc.count ("xsd-frontend-enum-synthesis-processed")) + return; + + uc.set ("xsd-frontend-enum-synthesis-processed", true); + + // First see if this union is suitable for synthesis. + // + SemanticGraph::Type* base (0); + + for (Type::ArgumentedIterator i (u.argumented_begin ()); + i != u.argumented_end (); ++i) + { + if (i->type ().is_a ()) + { + // See if we can synthesize an enum for this union. This + // call can change the value i->type() returns. + // + dispatch (i->type ()); + } + + SemanticGraph::Type& t (i->type ()); + + if (!t.is_a ()) + return; + + // Make sure all the enums have a common base. + // + if (base == 0) + base = &t; + else + { + // Traverse the inheritance hierarchy until we fine a + // common base. + // + while (base != 0) + { + SemanticGraph::Type* b (&t); + + for (; b != base && b->inherits_p (); + b = &b->inherits ().base ()) ; + + if (base == b) + break; + + // Could not find any match on this level. Go one step + // lower and try again. + // + base = base->inherits_p () ? &base->inherits ().base () : 0; + } + + if (base == 0) + return; // No common base. + } + } + + if (base == 0) + return; // Empty union. + + // So this union is suitable for synthesis. Base variable points + // to the "most-derived" common base type. + // + Enumeration& e (schema_.new_node ( + u.file (), u.line (), u.column ())); + + schema_.new_edge (e, *base); + + // Copy enumerators from the member enums. + // + { + Enumerators set; + Traversal::Enumeration en; + Traversal::Names names; + Enumerator er (schema_, e, set); + en >> names >> er; + + for (Type::ArgumentedIterator i (u.argumented_begin ()); + i != u.argumented_end (); ++i) + { + en.dispatch (i->type ()); + } + } + + // Reset edges pointing to union to point to enum. + // + if (u.annotated_p ()) + { + schema_.reset_right_node (u.annotated (), e); + schema_.add_edge_right (e, u.annotated ()); + } + + schema_.reset_right_node (u.named (), e); + schema_.add_edge_right (e, u.named ()); + + for (Type::ClassifiesIterator i (u.classifies_begin ()), + end (u.classifies_end ()); i != end; ++i) + { + schema_.reset_right_node (*i, e); + schema_.add_edge_right (e, *i); + } + + for (Type::BegetsIterator i (u.begets_begin ()), + end (u.begets_end ()); i != end; ++i) + { + schema_.reset_right_node (*i, e); + schema_.add_edge_right (e, *i); + } + + for (Type::ArgumentsIterator i (u.arguments_begin ()), + end (u.arguments_end ()); i != end; ++i) + { + schema_.reset_left_node (*i, e); + schema_.add_edge_left (e, *i); + } + + // Remove Arguments edges pointing to the union. + // + while (u.argumented_begin () != u.argumented_end ()) + { + SemanticGraph::Arguments& a (*u.argumented_begin ()); + schema_.delete_edge (a.type (), a.specialization (), a); + } + + // Copy context and delete the union node. + // + e.context ().swap (uc); + schema_.delete_node (u); + } + + private: + SemanticGraph::Schema& schema_; + }; + + // Go into implied/included/imported schemas while making sure + // we don't process the same stuff more than once. + // + struct Uses: Traversal::Uses + { + virtual Void + traverse (Type& u) + { + SemanticGraph::Schema& s (u.schema ()); + + if (!s.context ().count ("xsd-frontend-enum-synthesis-seen")) + { + s.context ().set ("xsd-frontend-enum-synthesis-seen", true); + Traversal::Uses::traverse (u); + } + } + }; + } + + namespace Transformations + { + Void EnumSynthesis:: + transform (SemanticGraph::Schema& s, SemanticGraph::Path const&) + { + Traversal::Schema schema; + Uses uses; + + schema >> uses >> schema; + + Traversal::Names schema_names; + Traversal::Namespace ns; + Traversal::Names ns_names; + Union u (s); + + schema >> schema_names >> ns >> ns_names >> u; + + // Some twisted schemas do recusive inclusions. + // + s.context ().set ("xsd-frontend-enum-synthesis-seen", true); + + schema.dispatch (s); + } + } +} diff --git a/libxsd-frontend/xsd-frontend/transformations/enum-synthesis.hxx b/libxsd-frontend/xsd-frontend/transformations/enum-synthesis.hxx new file mode 100644 index 0000000..e3c38c7 --- /dev/null +++ b/libxsd-frontend/xsd-frontend/transformations/enum-synthesis.hxx @@ -0,0 +1,33 @@ +// file : xsd-frontend/transformations/enum-synthesis.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2006-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_FRONTEND_TRANSFORMATIONS_ENUM_SYNTHESIS_HXX +#define XSD_FRONTEND_TRANSFORMATIONS_ENUM_SYNTHESIS_HXX + +#include + +#include // Path +#include + +namespace XSDFrontend +{ + namespace Transformations + { + using namespace Cult::Types; + + // This transformation replaces unions of one or more enumerations + // with the same base with an equivalent synthesized enumeration. + // This transformation assumes that there are no anonymous types. + // + class EnumSynthesis + { + public: + Void + transform (SemanticGraph::Schema&, SemanticGraph::Path const&); + }; + } +} + +#endif // XSD_FRONTEND_TRANSFORMATIONS_ENUM_SYNTHESIS_HXX diff --git a/libxsd-frontend/xsd-frontend/transformations/restriction.cxx b/libxsd-frontend/xsd-frontend/transformations/restriction.cxx new file mode 100644 index 0000000..c58d98f --- /dev/null +++ b/libxsd-frontend/xsd-frontend/transformations/restriction.cxx @@ -0,0 +1,582 @@ +// file : xsd-frontend/transformations/restriction.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2006-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include + +#include +#include + +#include + +#include + +using std::wcerr; +using std::endl; + +namespace XSDFrontend +{ + using namespace Cult; + + typedef WideString String; + typedef Transformations::Restriction::Failed Failed; + typedef Containers::Vector BaseList; + + namespace + { + // + // + struct Complex: Traversal::Complex + { + Complex (SemanticGraph::Schema& schema) + : schema_ (schema) + { + } + + virtual Void + traverse (Type& c) + { + using namespace SemanticGraph; + using SemanticGraph::Complex; + + if (c.context ().count ("xsd-frontend-restriction-seen")) + return; + + c.context ().set ("xsd-frontend-restriction-seen", true); + + // The base content model can be spread over several types + // in the inheritance-by-extension hierarchy. + // + BaseList base_model; + + // Since attribute wildcards don't have names, we will have + // to rely on their relative position to find association. + // + BaseList base_list; + + // Current implementation of semantic graph uses the same Restricts + // edge for both simple type/content restriction and complex content + // restriction. Here we are interested in the complex content only. + // + // + if (c.inherits_p () && + c.inherits ().is_a () && + !c.inherits ().base ().is_a ()) + { + // Go down our inheritance hierarchy until the end or the previous + // restriction. + // + Complex* base (&c); + + while ((base = dynamic_cast (&base->inherits ().base ()))) + { + traverse (*base); // Make sure our base is processed. + + // Handle attributes. + // + merge_attributes (c, *base); + + base_list.push_back (base); + + // Collect types that have complex content. + // + if (base->contains_compositor_p ()) + base_model.push_back (base); + + if (!base->inherits_p () || base->inherits ().is_a ()) + break; + } + + // Handle attribute wildcards. + // + handle_any_attributes (c, base_list); + + // Handle complex content (not for the faint of heart). + // + if (c.contains_compositor_p ()) + { + // Traverse both restricted content model and base content + // model (in base_model) while looking for matches. + // + Compositor& root (c.contains_compositor ().compositor ()); + + if (base_model.size () == 1) + handle (root, + base_model[0]->contains_compositor ().compositor ()); + else + { + Compositor::ContainsIterator i (root.contains_begin ()); + BaseList::ReverseIterator j (base_model.rbegin ()); + + for (; i != root.contains_end (); ++i, ++j) + { + Particle& p (i->particle ()); + + if (!p.is_a ()) + { + wcerr << p.file () << ":" << p.line () << ":" << p.column () + << ": error: expected compositor instead of particle" + << endl; + throw Failed (); + } + + for (; j != base_model.rend (); ++j) + { + if (match (p, (*j)->contains_compositor ().compositor ())) + { + handle (p, (*j)->contains_compositor ().compositor ()); + break; + } + } + + if (j == base_model.rend ()) + break; + } + + if (i != root.contains_end ()) + { + Particle& p (i->particle ()); + + wcerr << p.file () << ":" << p.line () << ":" << p.column () + << ": error: unable to match restricted compositor" + << endl; + throw Failed (); + } + } + } + } + + // Traverse anonymous types (via elements & attributes). + // + Traversal::Complex::names (c); + } + + private: + Void + handle (SemanticGraph::Particle& r, SemanticGraph::Particle& b) + { + using namespace SemanticGraph; + + if (r.is_a ()) + { + Compositor& rc (dynamic_cast (r)); + Compositor& bc (dynamic_cast (b)); + + Compositor::ContainsIterator i (rc.contains_begin ()); + Compositor::ContainsIterator j (bc.contains_begin ()); + + for (; i != rc.contains_end (); ++i, ++j) + { + for (; j != bc.contains_end (); ++j) + { + Particle& rp (i->particle ()); + Particle& bp (j->particle ()); + + if (typeid (rp) != typeid (bp)) + continue; + + if (match (rp, bp)) + { + handle (rp, bp); + break; + } + } + + if (j == bc.contains_end ()) + break; + } + + if (i != rc.contains_end ()) + { + Particle& p (i->particle ()); + + wcerr << p.file () << ":" << p.line () << ":" << p.column () + << ": error: unable to match restricted particle" + << endl; + throw Failed (); + } + + rc.context ().set ("xsd-frontend-restriction-correspondence", &bc); + } + else if (r.is_a ()) + { + // Element + // + r.context ().set ("xsd-frontend-restriction-correspondence", + dynamic_cast (&b)); + } + else + { + // Wildcard + // + r.context ().set ("xsd-frontend-restriction-correspondence", + dynamic_cast (&b)); + } + } + + Boolean + match (SemanticGraph::Particle& r, SemanticGraph::Particle& b) + { + using namespace SemanticGraph; + + if (typeid (r) != typeid (b)) + return false; + + if (r.is_a ()) + { + Compositor& rc (dynamic_cast (r)); + Compositor& bc (dynamic_cast (b)); + + Compositor::ContainsIterator i (rc.contains_begin ()); + + if (i == rc.contains_end ()) + return true; + + Particle& rp (i->particle ()); + + for (Compositor::ContainsIterator j (bc.contains_begin ()); + j != bc.contains_end (); ++j) + { + Particle& bp (j->particle ()); + + if (typeid (rp) != typeid (bp)) + continue; + + if (match (rp, bp)) + return true; + } + } + else if (r.is_a ()) + { + Element& re (dynamic_cast (r)); + Element& be (dynamic_cast (b)); + + if (re.qualified_p ()) + { + if (be.qualified_p () && + re.name () == be.name () && + re.namespace_ ().name () == be.namespace_ ().name ()) + return true; + } + else + { + if (!be.qualified_p () && re.name () == be.name ()) + return true; + } + + // @@ Need to take into account substitution groups. + // + } + else + { + // Wildcard. + // + + // @@ To handle this properly we will need to analyze + // namespaces. + // + return true; + } + + return false; + } + + Void + merge_attributes (SemanticGraph::Complex& c, + SemanticGraph::Complex& base) + { + using namespace SemanticGraph; + + for (Scope::NamesIterator i (base.names_begin ()), + e (base.names_end ()); i != e; ++i) + { + Attribute* prot (dynamic_cast (&i->named ())); + + if (prot == 0) + continue; + + Name name (prot->name ()); + Scope::NamesIteratorPair r (c.find (name)); + + Attribute* a (0); + + for (; r.first != r.second; ++r.first) + { + a = dynamic_cast (&r.first->named ()); + + if (a == 0) + continue; + + if (prot->qualified_p ()) + { + if (a->qualified_p () && + prot->namespace_ ().name () == a->namespace_ ().name ()) + { + break; + } + } + else + { + if (!a->qualified_p ()) + break; + } + + a = 0; + } + + if (a == 0) + { + a = &schema_.new_node (prot->file (), + prot->line (), + prot->column (), + prot->optional_p (), + prot->global_p (), + prot->qualified_p ()); + + schema_.new_edge (c, *a, name); + + // Transfer namespace. + // + if (prot->qualified_p ()) + { + schema_.new_edge (*a, prot->namespace_ ()); + } + + // Default and fixed values if any. + // + if (prot->fixed_p ()) + a->fixed (prot->value ()); + else if (prot->default_p ()) + a->default_ (prot->value ()); + + // Belongs edge. + // + schema_.new_edge (*a, prot->type ()); + + // Transfer annotation. + // + if (prot->annotated_p ()) + schema_.new_edge (prot->annotation (), *a); + } + + a->context ().set ("xsd-frontend-restriction-correspondence", prot); + } + } + + Void + handle_any_attributes (SemanticGraph::Complex& c, BaseList& bl) + { + using namespace SemanticGraph; + + BaseList::ReverseIterator bi (bl.rbegin ()), be (bl.rend ()); + Scope::NamesIterator si; + + if (bi != be) + si = (*bi)->names_begin (); + + for (Scope::NamesIterator i (c.names_begin ()), + e (c.names_end ()); i != e; ++i) + { + AnyAttribute* a (dynamic_cast (&i->named ())); + + if (a == 0) + continue; + + AnyAttribute* p (0); + + while (bi != be) + { + for (; si != (*bi)->names_end (); ++si) + { + p = dynamic_cast (&si->named ()); + + if (p != 0) + { + ++si; + break; + } + } + + if (p != 0) + break; + + // Didn't find anything in this base. Move on to the next. + // + ++bi; + + if (bi != be) + si = (*bi)->names_begin (); + } + + if (p != 0) + { + a->context ().set ("xsd-frontend-restriction-correspondence", p); + } + else + { + wcerr << a->file () << ":" << a->line () << ":" << a->column () + << ": error: unable to find matching wildcard in base type" + << endl; + throw Failed (); + } + } + } + + private: + SemanticGraph::Schema& schema_; + }; + + // + // + struct Anonymous : Traversal::Element, + Traversal::Attribute + { + Anonymous (Traversal::NodeDispatcherBase& d1) + : complex_ (&d1, 0) + { + *this >> belongs_ >> complex_; + } + + Anonymous (Traversal::NodeDispatcherBase& d1, + Traversal::NodeDispatcherBase& d2) + : complex_ (&d1, &d2) + { + *this >> belongs_ >> complex_; + } + + // Hooks. + // + public: + virtual void + member_pre (SemanticGraph::Member&) + { + } + + virtual void + member_post (SemanticGraph::Member&) + { + } + + public: + + virtual Void + traverse (SemanticGraph::Element& e) + { + SemanticGraph::Type& t (e.type ()); + + if (!t.named_p () && !t.context ().count ("seen")) + { + t.context ().set ("seen", true); + + member_pre (e); + + Element::belongs (e, belongs_); + + member_post (e); + + t.context ().remove ("seen"); + } + } + + virtual Void + traverse (SemanticGraph::Attribute& a) + { + SemanticGraph::Type& t (a.type ()); + + if (!t.named_p () && !t.context ().count ("seen")) + { + t.context ().set ("seen", true); + + member_pre (a); + + Attribute::belongs (a, belongs_); + + member_post (a); + + t.context ().remove ("seen"); + } + } + + private: + struct Complex : Traversal::Complex + { + Complex (Traversal::NodeDispatcherBase* d1, + Traversal::NodeDispatcherBase* d2) + : d1_ (d1), d2_ (d2) + { + } + + virtual Void + traverse (SemanticGraph::Complex& c) + { + if (d1_) + d1_->dispatch (c); + + if (d2_) + d2_->dispatch (c); + } + + private: + Traversal::NodeDispatcherBase* d1_; + Traversal::NodeDispatcherBase* d2_; + + } complex_; + + Traversal::Belongs belongs_; + }; + + + // Go into implied/included/imported schemas while making sure + // we don't process the same stuff more than once. + // + struct Uses: Traversal::Uses + { + virtual Void + traverse (Type& u) + { + SemanticGraph::Schema& s (u.schema ()); + + if (!s.context ().count ("xsd-frontend-restriction-seen")) + { + s.context ().set ("xsd-frontend-restriction-seen", true); + Traversal::Uses::traverse (u); + } + } + }; + } + + namespace Transformations + { + Void Restriction:: + transform (SemanticGraph::Schema& s, SemanticGraph::Path const&) + { + Traversal::Schema schema; + Uses uses; + + schema >> uses >> schema; + + Traversal::Names schema_names; + Traversal::Namespace ns; + Traversal::Names ns_names; + + schema >> schema_names >> ns >> ns_names; + + Complex complex_type (s); + Anonymous anonymous (complex_type); + + ns_names >> complex_type; + ns_names >> anonymous; + + Traversal::Names names; + + complex_type >> names >> anonymous; + + // Some twisted schemas do recusive inclusions. + // + s.context ().set ("xsd-frontend-restriction-seen", true); + + schema.dispatch (s); + } + } +} diff --git a/libxsd-frontend/xsd-frontend/transformations/restriction.hxx b/libxsd-frontend/xsd-frontend/transformations/restriction.hxx new file mode 100644 index 0000000..7c3282e --- /dev/null +++ b/libxsd-frontend/xsd-frontend/transformations/restriction.hxx @@ -0,0 +1,39 @@ +// file : xsd-frontend/transformations/restriction.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2006-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_FRONTEND_TRANSFORMATIONS_RESTRICTION_HXX +#define XSD_FRONTEND_TRANSFORMATIONS_RESTRICTION_HXX + +#include + +#include // Path +#include + +namespace XSDFrontend +{ + namespace Transformations + { + using namespace Cult::Types; + + // This transformation performs two major tasks. It transfers omitted + // attribute declarations from the base to derived-by-restriction type + // and establishes correspondence between particles and compositors by + // adding the "xsd-frontend-restriction-correspondence" key-value pair + // in the context that contains a pointer to the corresponding particle + // or compositor in the base. Note that restriction of anyType is + // a special case and is not handled by this transformation. + // + class Restriction + { + public: + struct Failed {}; + + Void + transform (SemanticGraph::Schema&, SemanticGraph::Path const&); + }; + } +} + +#endif // XSD_FRONTEND_TRANSFORMATIONS_RESTRICTION_HXX diff --git a/libxsd-frontend/xsd-frontend/transformations/schema-per-type.cxx b/libxsd-frontend/xsd-frontend/transformations/schema-per-type.cxx new file mode 100644 index 0000000..9ac8445 --- /dev/null +++ b/libxsd-frontend/xsd-frontend/transformations/schema-per-type.cxx @@ -0,0 +1,453 @@ +// file : xsd-frontend/transformations/schema-per-type.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2006-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include + +#include +#include + +#include +#include +#include + +#include +#include + +#include // strcasecmp + +using std::wcerr; +using std::endl; + +namespace XSDFrontend +{ + using namespace Cult; + + typedef WideString String; + typedef Transformations::SchemaPerType::Failed Failed; + + typedef Containers::Vector Schemas; + typedef Containers::Map TypeSchemaMap; + + // Compare file paths case-insensitively. + // + struct FileComparator + { + Boolean + operator() (NarrowString const& x, NarrowString const& y) const + { + return strcasecmp (x.c_str (), y.c_str ()) < 0; + } + }; + + typedef Containers::Set FileSet; + + namespace + { + // Go into included and imported schemas while making sure + // we don't process the same stuff more than once. + // + struct Uses: Traversal::Includes, + Traversal::Imports, + Traversal::Implies + { + Uses (Schemas& schemas, SemanticGraph::Schema*& xsd) + : schemas_ (schemas), xsd_ (xsd) + { + xsd_ = 0; + } + + virtual Void + traverse (SemanticGraph::Includes& i) + { + SemanticGraph::Schema& s (i.schema ()); + + if (!s.context ().count ("xsd-frontend-schema-per-type-seen")) + { + schemas_.push_back (&s); + s.context ().set ("xsd-frontend-schema-per-type-seen", true); + Traversal::Includes::traverse (i); + } + } + + virtual Void + traverse (SemanticGraph::Imports& i) + { + SemanticGraph::Schema& s (i.schema ()); + + if (!s.context ().count ("xsd-frontend-schema-per-type-seen")) + { + schemas_.push_back (&s); + s.context ().set ("xsd-frontend-schema-per-type-seen", true); + Traversal::Imports::traverse (i); + } + } + + virtual Void + traverse (SemanticGraph::Implies& i) + { + if (xsd_ == 0) + xsd_ = &i.schema (); + } + + private: + Schemas& schemas_; + SemanticGraph::Schema*& xsd_; + }; + + Void + process_schema (SemanticGraph::Schema& s, + SemanticGraph::Schema& root, + SemanticGraph::Schema& xsd, + TypeSchemaMap& tsm, + FileSet& file_set, + Transformations::SchemaPerTypeTranslator& trans) + { + using namespace SemanticGraph; + + Path xsd_path ("XMLSchema.xsd"); + Namespace& ns (dynamic_cast (s.names_begin ()->named ())); + + // We should be careful with iterator caching since we are going to + // remove some of the nodes. + // + for (Scope::NamesIterator i (ns.names_begin ()); i != ns.names_end ();) + { + Nameable& n (i->named ()); + + if (n.is_a ()) + { + String name (n.name ()); + + // Remove from the namespace. + // + Scope::NamesIterator tmp (i++); + root.delete_edge (ns, n, *tmp); + + // Add a new schema node. + // + Path path; + String tn (trans.translate_type (ns.name (), name)); + String wbase (tn ? tn : name); + + try + { + NarrowString base (wbase.to_narrow ()); + + // Escape directory separators unless they came from the + // translator. + // + if (!tn) + { + for (NarrowString::Iterator i (base.begin ()), e (base.end ()); + i != e; ++i) + { + if (*i == '/' || *i == '\\') + *i = '_'; + } + } + + // Make sure it is unique. + // + NarrowString file_name (base); + + for (UnsignedLong i (1); + file_set.find (file_name) != file_set.end (); + ++i) + { + std::ostringstream os; + os << i; + file_name = base + os.str (); + } + + file_set.insert (file_name); + file_name += ".xsd"; + + try + { +#if !defined(BOOST_FILESYSTEM_VERSION) || BOOST_FILESYSTEM_VERSION == 2 + path = Path (file_name); +#else + path = Path (file_name.c_str()); +#endif + } + catch (InvalidPath const&) + { + wcerr << "error: '" << file_name.c_str () << "' is not a valid " + << "filesystem path" << endl; + + wcerr << "info: use type to file name translation mechanism " + << "to resolve this" << endl; + + throw Failed (); + } + } + catch (String::NonRepresentable const&) + { + wcerr << "error: '" << wbase << "' cannot be represented as a " + << "narrow string" << endl; + + wcerr << "info: use type to file name translation mechanism " + << "to resolve this" << endl; + + throw Failed (); + } + + Schema& ts (root.new_node (path, 1, 1)); + root.new_edge (ts, xsd, xsd_path); + + Namespace& tns (root.new_node (path, 1, 1)); + root.new_edge (ts, tns, ns.name ()); + root.new_edge (tns, n, name); + + // Add include to the original schema and enter into the + // type-schema map. + // + root.new_edge (s, ts, path); + tsm[&dynamic_cast (n)] = &ts; + } + else + ++i; + } + } + + struct Type: Traversal::List, + Traversal::Complex, + Traversal::Member + { + Type (SemanticGraph::Schema& schema, + SemanticGraph::Schema& root, + Char const* by_value_key, + TypeSchemaMap& tsm) + : schema_ (schema), + root_ (root), + by_value_key_ (by_value_key), + tsm_ (tsm) + { + *this >> names_ >> *this; + } + + virtual Void + traverse (SemanticGraph::List& l) + { + // Treat item type as base type since it is impossible + // to create recursive constructs using list. + // + SemanticGraph::Type& t (l.argumented ().type ()); + set_dep (t, false); + } + + virtual Void + traverse (SemanticGraph::Complex& c) + { + if (c.inherits_p ()) + set_dep (c.inherits ().base (), false); + + Traversal::Complex::names (c); + } + + virtual Void + traverse (SemanticGraph::Member& m) + { + SemanticGraph::Type& t (m.type ()); + + Boolean weak ( + by_value_key_ == 0 || + !t.context ().count (by_value_key_) || + !t.context ().get (by_value_key_)); + + set_dep (t, weak); + } + + private: + Void + set_dep (SemanticGraph::Type& t, Boolean weak) + { + using namespace SemanticGraph; + + TypeSchemaMap::Iterator i (tsm_.find (&t)); + + // If a type is not present in the map then it must be + // a built-in type. + // + if (i == tsm_.end ()) + return; + + // Check if we already saw this type. Theoretically, it could + // be that we need to upgrade the type of include from weak to + // strong. But because inheritance is handled first, the type + // in the set will already be with the right type. + // + if (type_set_.find (&t) != type_set_.end ()) + return; + + type_set_.insert (&t); + + Schema& s (*i->second); + Path path (s.used_begin ()->path ()); + SemanticGraph::Uses* u; + + if (s.names_begin ()->name () == schema_.names_begin ()->name ()) + u = &root_.new_edge (schema_, s, path); + else + u = &root_.new_edge (schema_, s, path); + + if (weak) + u->context().set ("weak", true); + } + + private: + SemanticGraph::Schema& schema_; + SemanticGraph::Schema& root_; + Char const* by_value_key_; + TypeSchemaMap& tsm_; + Containers::Set type_set_; + + Traversal::Names names_; + }; + } + + namespace Transformations + { + SchemaPerType:: + SchemaPerType (SchemaPerTypeTranslator& trans, Char const* by_value_key) + : by_value_key_ (by_value_key), trans_ (trans) + { + } + + Schemas SchemaPerType:: + transform (SemanticGraph::Schema& root) + { + // Collect initial schema nodes. + // + Schemas schemas; + SemanticGraph::Schema* xsd; + + { + Traversal::Schema schema; + Uses uses (schemas, xsd); + + schema >> uses >> schema; + + // Some twisted schemas do recusive inclusions. + // + root.context ().set ("xsd-frontend-schema-per-type-seen", true); + + schema.dispatch (root); + } + + // wcerr << schemas.size () << " initial schema nodes" << endl; + + // Add the schema file names to the file set. + // + FileSet file_set; + + for (Schemas::Iterator i (schemas.begin ()); i != schemas.end (); ++i) + { + SemanticGraph::Path const& path ( + (*i)->context ().get ("absolute-path")); + + // Translate the schema file name. + // + NarrowString abs_path; + +#if !defined(BOOST_FILESYSTEM_VERSION) || BOOST_FILESYSTEM_VERSION == 2 + // Try to use the portable representation of the path. If that + // fails, fall back to the native representation. + // + try + { + abs_path = path.string (); + } + catch (SemanticGraph::InvalidPath const&) + { + abs_path = path.native_file_string (); + } +#else + // The new ABI does not have a fallback native representation + abs_path = path.string (); +#endif + + NarrowString tf (trans_.translate_schema (abs_path)); +#if !defined(BOOST_FILESYSTEM_VERSION) || BOOST_FILESYSTEM_VERSION == 2 + NarrowString file (tf ? tf : path.leaf ()); +#else + NarrowString file (tf ? tf : path.filename ().string()); +#endif + + Size p (file.rfind ('.')); + NarrowString ext ( + p != NarrowString::npos ? NarrowString (file, p) : ""); + + NarrowString base ( + p != NarrowString::npos ? NarrowString (file, 0, p) : file); + + // Make sure it is unique. + // + NarrowString new_name (base); + + for (UnsignedLong n (1); + file_set.find (new_name) != file_set.end (); + ++n) + { + std::ostringstream os; + os << n; + new_name = base + os.str (); + } + + file_set.insert (new_name); + new_name += ext; + + try + { +#if !defined(BOOST_FILESYSTEM_VERSION) || BOOST_FILESYSTEM_VERSION == 2 + (*i)->context ().set ("renamed", SemanticGraph::Path (new_name)); +#else + (*i)->context ().set ("renamed", SemanticGraph::Path (new_name.c_str())); +#endif + } + catch (SemanticGraph::InvalidPath const&) + { + wcerr << "error: '" << new_name.c_str () << "' is not a valid " + << "filesystem path" << endl; + + wcerr << "info: use schema file name translation mechanism " + << "to resolve this" << endl; + + throw Failed (); + } + } + + // Process each schema node. + // + TypeSchemaMap tsm; + + for (Schemas::Iterator i (schemas.begin ()); i != schemas.end (); ++i) + { + process_schema (**i, root, *xsd, tsm, file_set, trans_); + } + + // wcerr << tsm.size () << " type schema nodes" << endl; + + // Establish include/import dependencies. While at it add the + // new schemas to the list which we will return. + // + for (TypeSchemaMap::Iterator i (tsm.begin ()); i != tsm.end (); ++i) + { + SemanticGraph::Schema& s (*i->second); + Type t (s, root, by_value_key_, tsm); + t.dispatch (*i->first); + schemas.push_back (&s); + } + + return schemas; + } + + SchemaPerTypeTranslator:: + ~SchemaPerTypeTranslator () + { + } + } +} diff --git a/libxsd-frontend/xsd-frontend/transformations/schema-per-type.hxx b/libxsd-frontend/xsd-frontend/transformations/schema-per-type.hxx new file mode 100644 index 0000000..89b6d83 --- /dev/null +++ b/libxsd-frontend/xsd-frontend/transformations/schema-per-type.hxx @@ -0,0 +1,61 @@ +// file : xsd-frontend/transformations/schema-per-type.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2006-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_FRONTEND_TRANSFORMATIONS_SCHEMA_PER_TYPE_HXX +#define XSD_FRONTEND_TRANSFORMATIONS_SCHEMA_PER_TYPE_HXX + +#include +#include + +#include // Path +#include + +namespace XSDFrontend +{ + namespace Transformations + { + using namespace Cult::Types; + + class SchemaPerTypeTranslator + { + public: + virtual + ~SchemaPerTypeTranslator (); + + // The following two functions should return empty string if + // there is no match. + // + virtual WideString + translate_type (WideString const& ns, WideString const& name) = 0; + + virtual NarrowString + translate_schema (NarrowString const& abs_path) = 0; + }; + + // This transformation restructures the semantic graph to have + // each type definition in a seperate schema file. + // + class SchemaPerType + { + public: + struct Failed {}; + + // If a type of an element or attribute has a context entry + // with the by_value_key key and it is true, then the schema + // for this type is included "strongly". + // + SchemaPerType (SchemaPerTypeTranslator&, Char const* by_value_key = 0); + + Cult::Containers::Vector + transform (SemanticGraph::Schema&); + + private: + Char const* by_value_key_; + SchemaPerTypeTranslator& trans_; + }; + } +} + +#endif // XSD_FRONTEND_TRANSFORMATIONS_SCHEMA_PER_TYPE_HXX diff --git a/libxsd-frontend/xsd-frontend/transformations/simplifier.cxx b/libxsd-frontend/xsd-frontend/transformations/simplifier.cxx new file mode 100644 index 0000000..2ccaed2 --- /dev/null +++ b/libxsd-frontend/xsd-frontend/transformations/simplifier.cxx @@ -0,0 +1,167 @@ +// file : xsd-frontend/transformations/simplifier.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2006-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include + +#include +#include + +#include + +namespace XSDFrontend +{ + using namespace Cult; + + namespace + { + struct Compositor: Traversal::All, + Traversal::Choice, + Traversal::Sequence + { + Compositor (SemanticGraph::Schema& root) + : root_ (root) + { + } + + virtual Void + traverse (SemanticGraph::All& a) + { + // The all compositor cannot contain compositors. + // + if (a.contains_begin () == a.contains_end ()) + remove (a); + } + + virtual Void + traverse (SemanticGraph::Choice& c) + { + // Do the depth-first traversal so that we take into account + // the potential removal of nested compositors. + // + using SemanticGraph::Compositor; + + for (Compositor::ContainsIterator i (c.contains_begin ()); + i != c.contains_end ();) + { + edge_traverser ().dispatch (*i++); + } + + Choice::contains (c); + + if (c.contains_begin () == c.contains_end ()) + remove (c); + } + + virtual Void + traverse (SemanticGraph::Sequence& s) + { + // Do the depth-first traversal so that we take into account + // the potential removal of nested compositors. + // + using SemanticGraph::Compositor; + + for (Compositor::ContainsIterator i (s.contains_begin ()); + i != s.contains_end ();) + { + edge_traverser ().dispatch (*i++); + } + + if (s.contains_begin () == s.contains_end ()) + remove (s); + } + + private: + virtual Void + remove (SemanticGraph::Compositor& c) + { + using SemanticGraph::Node; + using SemanticGraph::Choice; + using SemanticGraph::Complex; + using SemanticGraph::Compositor; + + if (c.contained_particle_p ()) + { + Compositor& com (c.contained_particle ().compositor ()); + + // Empty compositors in choice are important. + // + if (!com.is_a ()) + root_.delete_edge (com, c, c.contained_particle ()); + } + else + { + Complex& con ( + dynamic_cast (c.contained_compositor ().container ())); + root_.delete_edge (con, c, c.contained_compositor ()); + } + } + + private: + SemanticGraph::Schema& root_; + }; + + // + // + struct Type: Traversal::Complex + { + virtual Void + traverse (SemanticGraph::Complex& c) + { + if (c.contains_compositor_p ()) + Complex::contains_compositor (c); + } + }; + + // Go into implied/included/imported schemas while making sure + // we don't process the same stuff more than once. + // + struct Uses: Traversal::Uses + { + virtual Void + traverse (Type& u) + { + SemanticGraph::Schema& s (u.schema ()); + + if (!s.context ().count ("xsd-frontend-simplifier-seen")) + { + s.context ().set ("xsd-frontend-simplifier-seen", true); + Traversal::Uses::traverse (u); + } + } + }; + } + + namespace Transformations + { + Void Simplifier:: + transform (SemanticGraph::Schema& s, SemanticGraph::Path const&) + { + Traversal::Schema schema; + Uses uses; + + schema >> uses >> schema; + + Traversal::Names schema_names; + Traversal::Namespace ns; + Traversal::Names ns_names; + Type type; + + schema >> schema_names >> ns >> ns_names >> type; + + Compositor compositor (s); + Traversal::ContainsCompositor contains_compositor; + Traversal::ContainsParticle contains_particle; + + type >> contains_compositor >> compositor; + compositor >> contains_particle >> compositor; + + // Some twisted schemas do recusive inclusions. + // + s.context ().set ("xsd-frontend-simplifier-seen", true); + + schema.dispatch (s); + } + } +} diff --git a/libxsd-frontend/xsd-frontend/transformations/simplifier.hxx b/libxsd-frontend/xsd-frontend/transformations/simplifier.hxx new file mode 100644 index 0000000..676c166 --- /dev/null +++ b/libxsd-frontend/xsd-frontend/transformations/simplifier.hxx @@ -0,0 +1,33 @@ +// file : xsd-frontend/transformations/simplifier.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2006-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_FRONTEND_TRANSFORMATIONS_SIMPLIFIER_HXX +#define XSD_FRONTEND_TRANSFORMATIONS_SIMPLIFIER_HXX + +#include + +#include // Path +#include + +namespace XSDFrontend +{ + namespace Transformations + { + using namespace Cult::Types; + + // This transformation performs various schema simplifications + // (e.g., removing empty compositors, etc). This transformation + // assumes that there are no anonymous types. + // + class Simplifier + { + public: + Void + transform (SemanticGraph::Schema&, SemanticGraph::Path const&); + }; + } +} + +#endif // XSD_FRONTEND_TRANSFORMATIONS_SIMPLIFIER_HXX diff --git a/libxsd-frontend/xsd-frontend/traversal.hxx b/libxsd-frontend/xsd-frontend/traversal.hxx new file mode 100644 index 0000000..9b1c359 --- /dev/null +++ b/libxsd-frontend/xsd-frontend/traversal.hxx @@ -0,0 +1,26 @@ +// file : xsd-frontend/traversal.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_FRONTEND_TRAVERSAL_HXX +#define XSD_FRONTEND_TRAVERSAL_HXX + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif // XSD_FRONTEND_TRAVERSAL_HXX diff --git a/libxsd-frontend/xsd-frontend/traversal/any-attribute.hxx b/libxsd-frontend/xsd-frontend/traversal/any-attribute.hxx new file mode 100644 index 0000000..55ed999 --- /dev/null +++ b/libxsd-frontend/xsd-frontend/traversal/any-attribute.hxx @@ -0,0 +1,22 @@ +// file : xsd-frontend/traversal/any-attribute.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_FRONTEND_TRAVERSAL_ANY_ATTRIBUTE_HXX +#define XSD_FRONTEND_TRAVERSAL_ANY_ATTRIBUTE_HXX + +#include +#include + +namespace XSDFrontend +{ + namespace Traversal + { + typedef + Node + AnyAttribute; + } +} + +#endif // XSD_FRONTEND_TRAVERSAL_ANY_ATTRIBUTE_HXX diff --git a/libxsd-frontend/xsd-frontend/traversal/any.hxx b/libxsd-frontend/xsd-frontend/traversal/any.hxx new file mode 100644 index 0000000..505d336 --- /dev/null +++ b/libxsd-frontend/xsd-frontend/traversal/any.hxx @@ -0,0 +1,22 @@ +// file : xsd-frontend/traversal/any.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_FRONTEND_TRAVERSAL_ANY_HXX +#define XSD_FRONTEND_TRAVERSAL_ANY_HXX + +#include +#include + +namespace XSDFrontend +{ + namespace Traversal + { + typedef + Node + Any; + } +} + +#endif // XSD_FRONTEND_TRAVERSAL_ANY_HXX diff --git a/libxsd-frontend/xsd-frontend/traversal/attribute-group.cxx b/libxsd-frontend/xsd-frontend/traversal/attribute-group.cxx new file mode 100644 index 0000000..e5c2237 --- /dev/null +++ b/libxsd-frontend/xsd-frontend/traversal/attribute-group.cxx @@ -0,0 +1,30 @@ +// file : xsd-frontend/traversal/attribute-group.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2006-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include + +namespace XSDFrontend +{ + namespace Traversal + { + Void AttributeGroup:: + traverse (Type& g) + { + pre (g); + names (g); + post (g); + } + + Void AttributeGroup:: + pre (Type&) + { + } + + Void AttributeGroup:: + post (Type&) + { + } + } +} diff --git a/libxsd-frontend/xsd-frontend/traversal/attribute-group.hxx b/libxsd-frontend/xsd-frontend/traversal/attribute-group.hxx new file mode 100644 index 0000000..cd01a97 --- /dev/null +++ b/libxsd-frontend/xsd-frontend/traversal/attribute-group.hxx @@ -0,0 +1,30 @@ +// file : xsd-frontend/traversal/attribute-group.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2006-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_FRONTEND_TRAVERSAL_ATTRIBUTE_GROUP_HXX +#define XSD_FRONTEND_TRAVERSAL_ATTRIBUTE_GROUP_HXX + +#include +#include + +namespace XSDFrontend +{ + namespace Traversal + { + struct AttributeGroup: ScopeTemplate + { + virtual Void + traverse (Type&); + + virtual Void + pre (Type&); + + virtual Void + post (Type&); + }; + } +} + +#endif // XSD_FRONTEND_TRAVERSAL_ATTRIBUTE_GROUP_HXX diff --git a/libxsd-frontend/xsd-frontend/traversal/attribute.cxx b/libxsd-frontend/xsd-frontend/traversal/attribute.cxx new file mode 100644 index 0000000..c051667 --- /dev/null +++ b/libxsd-frontend/xsd-frontend/traversal/attribute.cxx @@ -0,0 +1,48 @@ +// file : xsd-frontend/traversal/attribute.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include + +namespace XSDFrontend +{ + namespace Traversal + { + Void Attribute:: + traverse (Type& a) + { + pre (a); + belongs (a); + name (a); + post (a); + } + + Void Attribute:: + pre (Type&) + { + } + + Void Attribute:: + belongs (Type& a, EdgeDispatcherBase& d) + { + d.dispatch (a.belongs ()); + } + + Void Attribute:: + belongs (Type& a) + { + belongs (a, *this); + } + + Void Attribute:: + name (Type&) + { + } + + Void Attribute:: + post (Type&) + { + } + } +} diff --git a/libxsd-frontend/xsd-frontend/traversal/attribute.hxx b/libxsd-frontend/xsd-frontend/traversal/attribute.hxx new file mode 100644 index 0000000..feb6b31 --- /dev/null +++ b/libxsd-frontend/xsd-frontend/traversal/attribute.hxx @@ -0,0 +1,41 @@ +// file : xsd-frontend/traversal/attribute.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_FRONTEND_TRAVERSAL_ATTRIBUTE_HXX +#define XSD_FRONTEND_TRAVERSAL_ATTRIBUTE_HXX + +#include + +#include + + +namespace XSDFrontend +{ + namespace Traversal + { + struct Attribute : Node + { + virtual Void + traverse (Type&); + + virtual Void + pre (Type&); + + virtual Void + belongs (Type&, EdgeDispatcherBase&); + + virtual Void + belongs (Type&); + + virtual Void + name (Type&); + + virtual Void + post (Type&); + }; + } +} + +#endif // XSD_FRONTEND_TRAVERSAL_ATTRIBUTE_HXX diff --git a/libxsd-frontend/xsd-frontend/traversal/complex.cxx b/libxsd-frontend/xsd-frontend/traversal/complex.cxx new file mode 100644 index 0000000..d6cfc41 --- /dev/null +++ b/libxsd-frontend/xsd-frontend/traversal/complex.cxx @@ -0,0 +1,64 @@ +// file : xsd-frontend/traversal/complex.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include + +namespace XSDFrontend +{ + namespace Traversal + { + Void Complex:: + traverse (Type& c) + { + pre (c); + name (c); + inherits (c); + names (c); + contains_compositor (c); + post (c); + } + + Void Complex:: + pre (Type&) + { + } + + Void Complex:: + name (Type&) + { + } + + Void Complex:: + inherits (Type& c) + { + inherits (c, *this); + } + + Void Complex:: + inherits (Type& c, EdgeDispatcherBase& d) + { + if (c.inherits_p ()) + d.dispatch (c.inherits ()); + } + + Void Complex:: + contains_compositor (Type& c) + { + contains_compositor (c, *this); + } + + Void Complex:: + contains_compositor (Type& c, EdgeDispatcherBase& d) + { + if (c.contains_compositor_p ()) + d.dispatch (c.contains_compositor ()); + } + + Void Complex:: + post (Type&) + { + } + } +} diff --git a/libxsd-frontend/xsd-frontend/traversal/complex.hxx b/libxsd-frontend/xsd-frontend/traversal/complex.hxx new file mode 100644 index 0000000..3dd7e7b --- /dev/null +++ b/libxsd-frontend/xsd-frontend/traversal/complex.hxx @@ -0,0 +1,45 @@ +// file : xsd-frontend/traversal/complex.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_FRONTEND_TRAVERSAL_COMPLEX_HXX +#define XSD_FRONTEND_TRAVERSAL_COMPLEX_HXX + +#include +#include + +namespace XSDFrontend +{ + namespace Traversal + { + struct Complex : ScopeTemplate + { + virtual Void + traverse (Type&); + + virtual Void + pre (Type&); + + virtual Void + name (Type&); + + virtual Void + inherits (Type&); + + Void + inherits (Type&, EdgeDispatcherBase&); + + virtual Void + contains_compositor (Type&); + + Void + contains_compositor (Type&, EdgeDispatcherBase&); + + virtual Void + post (Type&); + }; + } +} + +#endif // XSD_FRONTEND_TRAVERSAL_COMPLEX_HXX diff --git a/libxsd-frontend/xsd-frontend/traversal/compositors.cxx b/libxsd-frontend/xsd-frontend/traversal/compositors.cxx new file mode 100644 index 0000000..d3089fc --- /dev/null +++ b/libxsd-frontend/xsd-frontend/traversal/compositors.cxx @@ -0,0 +1,165 @@ +// file : xsd-frontend/traversal/compositors.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2006-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include + +namespace XSDFrontend +{ + namespace Traversal + { + // ContainsParticle + // + Void ContainsParticle:: + traverse (Type& c) + { + dispatch (c.particle ()); + } + + + // ContainsCompositor + // + Void ContainsCompositor:: + traverse (Type& c) + { + dispatch (c.compositor ()); + } + + + // Compositor + // + Void Compositor:: + traverse (Type& c) + { + pre (c); + contains (c); + post (c); + } + + Void Compositor:: + pre (Type&) + { + } + + Void Compositor:: + contains (Type& c) + { + iterate_and_dispatch ( + c.contains_begin (), c.contains_end (), edge_traverser ()); + } + + Void Compositor:: + contains (Type& c, EdgeDispatcherBase& d) + { + iterate_and_dispatch (c.contains_begin (), c.contains_end (), d); + } + + Void Compositor:: + post (Type&) + { + } + + + // All + // + Void All:: + traverse (Type& c) + { + pre (c); + contains (c); + post (c); + } + + Void All:: + pre (Type&) + { + } + + Void All:: + contains (Type& c) + { + iterate_and_dispatch ( + c.contains_begin (), c.contains_end (), edge_traverser ()); + } + + Void All:: + contains (Type& c, EdgeDispatcherBase& d) + { + iterate_and_dispatch (c.contains_begin (), c.contains_end (), d); + } + + Void All:: + post (Type&) + { + } + + + // Choice + // + Void Choice:: + traverse (Type& c) + { + pre (c); + contains (c); + post (c); + } + + Void Choice:: + pre (Type&) + { + } + + Void Choice:: + contains (Type& c) + { + iterate_and_dispatch ( + c.contains_begin (), c.contains_end (), edge_traverser ()); + } + + Void Choice:: + contains (Type& c, EdgeDispatcherBase& d) + { + iterate_and_dispatch (c.contains_begin (), c.contains_end (), d); + } + + Void Choice:: + post (Type&) + { + } + + + // Sequence + // + Void Sequence:: + traverse (Type& c) + { + pre (c); + contains (c); + post (c); + } + + Void Sequence:: + pre (Type&) + { + } + + Void Sequence:: + contains (Type& c) + { + iterate_and_dispatch ( + c.contains_begin (), c.contains_end (), edge_traverser ()); + } + + Void Sequence:: + contains (Type& c, EdgeDispatcherBase& d) + { + iterate_and_dispatch (c.contains_begin (), c.contains_end (), d); + } + + Void Sequence:: + post (Type&) + { + } + } +} diff --git a/libxsd-frontend/xsd-frontend/traversal/compositors.hxx b/libxsd-frontend/xsd-frontend/traversal/compositors.hxx new file mode 100644 index 0000000..e81460b --- /dev/null +++ b/libxsd-frontend/xsd-frontend/traversal/compositors.hxx @@ -0,0 +1,136 @@ +// file : xsd-frontend/traversal/compositors.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2006-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_FRONTEND_TRAVERSAL_COMPOSITORS_HXX +#define XSD_FRONTEND_TRAVERSAL_COMPOSITORS_HXX + +#include +#include + +namespace XSDFrontend +{ + namespace Traversal + { + // + // + struct ContainsParticle: Edge + { + ContainsParticle () + { + } + + ContainsParticle (NodeBase& n) + { + node_traverser (n); + } + + virtual Void + traverse (Type&); + }; + + + // + // + struct ContainsCompositor: Edge + { + ContainsCompositor () + { + } + + ContainsCompositor (NodeBase& n) + { + node_traverser (n); + } + + virtual Void + traverse (Type&); + }; + + // + // + struct Compositor : Node + { + virtual Void + traverse (Type&); + + virtual Void + pre (Type&); + + virtual Void + contains (Type&); + + virtual Void + contains (Type&, EdgeDispatcherBase&); + + virtual Void + post (Type&); + }; + + + // + // + struct All : Node + { + virtual Void + traverse (Type&); + + virtual Void + pre (Type&); + + virtual Void + contains (Type&); + + virtual Void + contains (Type&, EdgeDispatcherBase&); + + virtual Void + post (Type&); + }; + + + // + // + struct Choice : Node + { + virtual Void + traverse (Type&); + + virtual Void + pre (Type&); + + virtual Void + contains (Type&); + + virtual Void + contains (Type&, EdgeDispatcherBase&); + + virtual Void + post (Type&); + }; + + + // + // + struct Sequence : Node + { + virtual Void + traverse (Type&); + + virtual Void + pre (Type&); + + virtual Void + contains (Type&); + + virtual Void + contains (Type&, EdgeDispatcherBase&); + + virtual Void + post (Type&); + }; + } +} + +#endif // XSD_FRONTEND_TRAVERSAL_COMPOSITORS_HXX diff --git a/libxsd-frontend/xsd-frontend/traversal/element-group.cxx b/libxsd-frontend/xsd-frontend/traversal/element-group.cxx new file mode 100644 index 0000000..cb7a51a --- /dev/null +++ b/libxsd-frontend/xsd-frontend/traversal/element-group.cxx @@ -0,0 +1,43 @@ +// file : xsd-frontend/traversal/element-group.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2006-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include + +namespace XSDFrontend +{ + namespace Traversal + { + Void ElementGroup:: + traverse (Type& g) + { + pre (g); + names (g); + contains_compositor (g); + post (g); + } + + Void ElementGroup:: + pre (Type&) + { + } + + Void ElementGroup:: + contains_compositor (Type& g, EdgeDispatcherBase& d) + { + d.dispatch (g.contains_compositor ()); + } + + Void ElementGroup:: + contains_compositor (Type& g) + { + contains_compositor (g, *this); + } + + Void ElementGroup:: + post (Type&) + { + } + } +} diff --git a/libxsd-frontend/xsd-frontend/traversal/element-group.hxx b/libxsd-frontend/xsd-frontend/traversal/element-group.hxx new file mode 100644 index 0000000..8ebe0bd --- /dev/null +++ b/libxsd-frontend/xsd-frontend/traversal/element-group.hxx @@ -0,0 +1,36 @@ +// file : xsd-frontend/traversal/element-group.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2006-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_FRONTEND_TRAVERSAL_ELEMENT_GROUP_HXX +#define XSD_FRONTEND_TRAVERSAL_ELEMENT_GROUP_HXX + +#include +#include + +namespace XSDFrontend +{ + namespace Traversal + { + struct ElementGroup: ScopeTemplate + { + virtual Void + traverse (Type&); + + virtual Void + pre (Type&); + + virtual Void + contains_compositor (Type&); + + virtual Void + contains_compositor (Type&, EdgeDispatcherBase&); + + virtual Void + post (Type&); + }; + } +} + +#endif // XSD_FRONTEND_TRAVERSAL_ELEMENT_GROUP_HXX diff --git a/libxsd-frontend/xsd-frontend/traversal/element.cxx b/libxsd-frontend/xsd-frontend/traversal/element.cxx new file mode 100644 index 0000000..7f296ee --- /dev/null +++ b/libxsd-frontend/xsd-frontend/traversal/element.cxx @@ -0,0 +1,48 @@ +// file : xsd-frontend/traversal/element.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include + +namespace XSDFrontend +{ + namespace Traversal + { + Void Element:: + traverse (Type& m) + { + pre (m); + belongs (m); + name (m); + post (m); + } + + Void Element:: + pre (Type&) + { + } + + Void Element:: + belongs (Type& m, EdgeDispatcherBase& d) + { + d.dispatch (m.belongs ()); + } + + Void Element:: + belongs (Type& m) + { + belongs (m, edge_traverser ()); + } + + Void Element:: + name (Type&) + { + } + + Void Element:: + post (Type&) + { + } + } +} diff --git a/libxsd-frontend/xsd-frontend/traversal/element.hxx b/libxsd-frontend/xsd-frontend/traversal/element.hxx new file mode 100644 index 0000000..d5187ad --- /dev/null +++ b/libxsd-frontend/xsd-frontend/traversal/element.hxx @@ -0,0 +1,39 @@ +// file : xsd-frontend/traversal/element.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_FRONTEND_TRAVERSAL_ELEMENT_HXX +#define XSD_FRONTEND_TRAVERSAL_ELEMENT_HXX + +#include +#include + +namespace XSDFrontend +{ + namespace Traversal + { + struct Element : Node + { + virtual Void + traverse (Type&); + + virtual Void + pre (Type&); + + virtual Void + belongs (Type&, EdgeDispatcherBase&); + + virtual Void + belongs (Type&); + + virtual Void + name (Type&); + + virtual Void + post (Type&); + }; + } +} + +#endif // XSD_FRONTEND_TRAVERSAL_ELEMENT_HXX diff --git a/libxsd-frontend/xsd-frontend/traversal/elements.cxx b/libxsd-frontend/xsd-frontend/traversal/elements.cxx new file mode 100644 index 0000000..b1c47a0 --- /dev/null +++ b/libxsd-frontend/xsd-frontend/traversal/elements.cxx @@ -0,0 +1,77 @@ +// file : xsd-frontend/traversal/elements.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include + +namespace XSDFrontend +{ + namespace Traversal + { + // Instance + // + Void Instance:: + traverse (Type& a) + { + pre (a); + belongs (a); + post (a); + } + + Void Instance:: + pre (Type&) + { + } + + Void Instance:: + belongs (Type& a, EdgeDispatcherBase& d) + { + d.dispatch (a.belongs ()); + } + + Void Instance:: + belongs (Type& a) + { + belongs (a, edge_traverser ()); + } + + Void Instance:: + post (Type&) + { + } + + + // Member + // + Void Member:: + traverse (Type& a) + { + pre (a); + belongs (a); + post (a); + } + + Void Member:: + pre (Type&) + { + } + + Void Member:: + belongs (Type& a, EdgeDispatcherBase& d) + { + d.dispatch (a.belongs ()); + } + + Void Member:: + belongs (Type& a) + { + belongs (a, edge_traverser ()); + } + + Void Member:: + post (Type&) + { + } + } +} diff --git a/libxsd-frontend/xsd-frontend/traversal/elements.hxx b/libxsd-frontend/xsd-frontend/traversal/elements.hxx new file mode 100644 index 0000000..c405a1b --- /dev/null +++ b/libxsd-frontend/xsd-frontend/traversal/elements.hxx @@ -0,0 +1,480 @@ +// file : xsd-frontend/traversal/elements.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_FRONTEND_TRAVERSAL_ELEMENTS_HXX +#define XSD_FRONTEND_TRAVERSAL_ELEMENTS_HXX + +#include + +#include + +#include + +namespace XSDFrontend +{ + namespace Traversal + { + using namespace Cult::Types; + + namespace Bits + { + using FrontendElements::Traversal::TraverserBase; + using FrontendElements::Traversal::Traverser; + + using FrontendElements::Traversal::DispatcherBase; + using FrontendElements::Traversal::Dispatcher; + + } + + typedef Bits::DispatcherBase NodeDispatcherBase; + typedef Bits::DispatcherBase EdgeDispatcherBase; + + + // + // + struct NodeBase : virtual Bits::Dispatcher, + virtual Bits::Dispatcher + { + Void + edge_traverser (EdgeDispatcherBase& d) + { + Bits::Dispatcher::traverser (d); + } + + EdgeDispatcherBase& + edge_traverser () + { + return *this; + } + + public: + using Bits::Dispatcher::dispatch; + using Bits::Dispatcher::dispatch; + + using Bits::Dispatcher::map; + + using Bits::Dispatcher::iterate_and_dispatch; + }; + + + // + // + template + struct Node : Bits::TraverserBase, virtual NodeBase + { + typedef + T + Type; + + Node () + { + map (typeid (Type), *this); + } + + virtual Void + traverse (Type&) = 0; + + virtual Void + trampoline (SemanticGraph::Node& i) + { + traverse (dynamic_cast (i)); + } + + virtual Void + trampoline (SemanticGraph::Node const&) + { + abort (); + } + }; + + + // + // + struct EdgeBase : virtual Bits::Dispatcher, + virtual Bits::Dispatcher + { + Void + node_traverser (NodeDispatcherBase& d) + { + Bits::Dispatcher::traverser (d); + } + + NodeDispatcherBase& + node_traverser () + { + return *this; + } + + public: + using Bits::Dispatcher::dispatch; + using Bits::Dispatcher::dispatch; + + using Bits::Dispatcher::map; + + using Bits::Dispatcher::iterate_and_dispatch; + }; + + template + struct Edge : Bits::TraverserBase, virtual EdgeBase + { + typedef + T + Type; + + Edge () + { + map (typeid (Type), *this); + } + + virtual Void + traverse (Type&) = 0; + + virtual Void + trampoline (SemanticGraph::Edge& i) + { + traverse (dynamic_cast (i)); + } + + virtual Void + trampoline (SemanticGraph::Edge const&) + { + abort (); + } + }; + + inline + EdgeBase& + operator>> (NodeBase& n, EdgeBase& e) + { + n.edge_traverser (e); + return e; + } + + inline + NodeBase& + operator>> (EdgeBase& e, NodeBase& n) + { + e.node_traverser (n); + return n; + } + + // Edges + // + + // + // + struct Names : Edge + { + Names () + { + } + + Names (NodeBase& n) + { + node_traverser (n); + } + + virtual Void + traverse (Type& e) + { + dispatch (e.named ()); + } + }; + + + // + // + struct Belongs : Edge + { + Belongs () + { + } + + Belongs (NodeBase& n) + { + node_traverser (n); + } + + virtual Void + traverse (Type& e) + { + dispatch (e.type ()); + } + }; + + + // Nodes + // + + + // + // + struct Nameable : Node + { + }; + + + // + // + template + struct ScopeTemplate : Node + { + public: + virtual Void + traverse (T& s) + { + names (s); + } + + template + Void + names (T& s, + EdgeDispatcherBase& d, + Void (X::*pre_) (T&) = (Void (ScopeTemplate::*)(T&)) (0), + Void (X::*post_) (T&) = (Void (ScopeTemplate::*)(T&)) (0), + Void (X::*none_) (T&) = (Void (ScopeTemplate::*)(T&)) (0), + Void (X::*next_) (T&) = (Void (ScopeTemplate::*)(T&)) (0)) + { + X* this_ (dynamic_cast (this)); + + typename T::NamesIterator b (s.names_begin ()), e (s.names_end ()); + + if (b != e) + { + if (pre_) + (this_->*pre_) (s); + + //iterate_and_dispatch (b, e, d, *this_, next_, s); + + for (; b != s.names_end ();) + { + d.dispatch (*b); + + if (++b != s.names_end () && next_ != 0) + (this_->*next_) (s); + } + + if (post_) + (this_->*post_) (s); + } + else + { + if (none_) + (this_->*none_) (s); + } + } + + virtual Void + names (T& s, EdgeDispatcherBase& d) + { + names > (s, d); + } + + virtual Void + names (T& s) + { + names (s, + *this, + &ScopeTemplate::names_pre, + &ScopeTemplate::names_post, + &ScopeTemplate::names_none, + &ScopeTemplate::names_next); + } + + virtual Void + names_pre (T&) + { + } + + virtual Void + names_next (T&) + { + } + + virtual Void + names_post (T&) + { + } + + virtual Void + names_none (T&) + { + } + }; + + + // + // + typedef + ScopeTemplate + Scope; + + + // + // + struct Type : Node + { + virtual Void + traverse (SemanticGraph::Type&) = 0; + }; + + + // + // + struct Instance : Node + { + virtual Void + traverse (Type&); + + virtual Void + pre (Type&); + + virtual Void + belongs (Type&, EdgeDispatcherBase&); + + virtual Void + belongs (Type&); + + virtual Void + post (Type&); + }; + + + // + // + struct Member : Node + { + virtual Void + traverse (Type&); + + virtual Void + pre (Type&); + + virtual Void + belongs (Type&, EdgeDispatcherBase&); + + virtual Void + belongs (Type&); + + virtual Void + post (Type&); + }; + + + // + // + struct Inherits : Edge + { + Inherits () + { + } + + Inherits (NodeBase& n) + { + node_traverser (n); + } + + virtual Void + traverse (Type& e) + { + dispatch (e.base ()); + } + }; + + + // + // + struct Extends : Edge + { + Extends () + { + } + + Extends (NodeBase& n) + { + node_traverser (n); + } + + virtual Void + traverse (Type& e) + { + dispatch (e.base ()); + } + }; + + + // + // + struct Restricts : Edge + { + Restricts () + { + } + + Restricts (NodeBase& n) + { + node_traverser (n); + } + + virtual Void + traverse (Type& e) + { + dispatch (e.base ()); + } + }; + + + // + // + struct Argumented : Edge + { + Argumented () + { + } + + Argumented (NodeBase& n) + { + node_traverser (n); + } + + virtual Void + traverse (Type& a) + { + dispatch (a.type ()); + } + }; + + + /* + // + // + struct Contains : Edge + { + virtual Void + traverse (Type& e) + { + dispatch (e.element ()); + } + }; + */ + + // + // + typedef + Node + AnyType; + + + // + // + typedef + Node + AnySimpleType; + } +} + +#include + +#endif // XSD_FRONTEND_TRAVERSAL_ELEMENTS_HXX diff --git a/libxsd-frontend/xsd-frontend/traversal/elements.txx b/libxsd-frontend/xsd-frontend/traversal/elements.txx new file mode 100644 index 0000000..b673a8d --- /dev/null +++ b/libxsd-frontend/xsd-frontend/traversal/elements.txx @@ -0,0 +1,11 @@ +// file : xsd-frontend/traversal/elements.txx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +namespace XSDFrontend +{ + namespace Traversal + { + } +} diff --git a/libxsd-frontend/xsd-frontend/traversal/enumeration.cxx b/libxsd-frontend/xsd-frontend/traversal/enumeration.cxx new file mode 100644 index 0000000..a8a49a5 --- /dev/null +++ b/libxsd-frontend/xsd-frontend/traversal/enumeration.cxx @@ -0,0 +1,91 @@ +// file : xsd-frontend/traversal/enumeration.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include + +namespace XSDFrontend +{ + namespace Traversal + { + // Enumeration + // + Void Enumeration:: + traverse (Type& e) + { + pre (e); + name (e); + inherits (e); + names (e); + post (e); + } + + Void Enumeration:: + pre (Type&) + { + } + + Void Enumeration:: + name (Type&) + { + } + + Void Enumeration:: + inherits (Type& e) + { + inherits (e, *this); + } + + Void Enumeration:: + inherits (Type& e, EdgeDispatcherBase& d) + { + if (e.inherits_p ()) + d.dispatch (e.inherits ()); + } + + Void Enumeration:: + post (Type&) + { + } + + + // Enumerator + // + Void Enumerator:: + traverse (Type& e) + { + pre (e); + belongs (e); + name (e); + post (e); + } + + Void Enumerator:: + pre (Type&) + { + } + + Void Enumerator:: + belongs (Type& e, EdgeDispatcherBase& d) + { + d.dispatch (e.belongs ()); + } + + Void Enumerator:: + belongs (Type& e) + { + belongs (e, edge_traverser ()); + } + + Void Enumerator:: + name (Type&) + { + } + + Void Enumerator:: + post (Type&) + { + } + } +} diff --git a/libxsd-frontend/xsd-frontend/traversal/enumeration.hxx b/libxsd-frontend/xsd-frontend/traversal/enumeration.hxx new file mode 100644 index 0000000..c6d7f04 --- /dev/null +++ b/libxsd-frontend/xsd-frontend/traversal/enumeration.hxx @@ -0,0 +1,60 @@ +// file : xsd-frontend/traversal/enumeration.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_FRONTEND_TRAVERSAL_ENUMERATION_HXX +#define XSD_FRONTEND_TRAVERSAL_ENUMERATION_HXX + +#include +#include + +namespace XSDFrontend +{ + namespace Traversal + { + struct Enumeration : ScopeTemplate + { + virtual Void + traverse (Type&); + + virtual Void + pre (Type&); + + virtual Void + name (Type&); + + virtual Void + inherits (Type&); + + Void + inherits (Type&, EdgeDispatcherBase&); + + virtual Void + post (Type&); + }; + + struct Enumerator : Node + { + virtual Void + traverse (Type&); + + virtual Void + pre (Type&); + + virtual Void + belongs (Type&, EdgeDispatcherBase&); + + virtual Void + belongs (Type&); + + virtual Void + name (Type&); + + virtual Void + post (Type&); + }; + } +} + +#endif // XSD_FRONTEND_TRAVERSAL_ENUMERATION_HXX diff --git a/libxsd-frontend/xsd-frontend/traversal/fundamental.cxx b/libxsd-frontend/xsd-frontend/traversal/fundamental.cxx new file mode 100644 index 0000000..b9cadec --- /dev/null +++ b/libxsd-frontend/xsd-frontend/traversal/fundamental.cxx @@ -0,0 +1,13 @@ +// file : xsd-frontend/traversal/fundamental.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include + +namespace XSDFrontend +{ + namespace Traversal + { + } +} diff --git a/libxsd-frontend/xsd-frontend/traversal/fundamental.hxx b/libxsd-frontend/xsd-frontend/traversal/fundamental.hxx new file mode 100644 index 0000000..5c20d9c --- /dev/null +++ b/libxsd-frontend/xsd-frontend/traversal/fundamental.hxx @@ -0,0 +1,234 @@ +// file : xsd-frontend/traversal/fundamental.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_FRONTEND_TRAVERSAL_FUNDAMENTAL_HXX +#define XSD_FRONTEND_TRAVERSAL_FUNDAMENTAL_HXX + +#include +#include + +namespace XSDFrontend +{ + namespace Traversal + { + namespace Fundamental + { + typedef + Node + Type; + + // Integers. + // + typedef + Node + Byte; + + typedef + Node + UnsignedByte; + + typedef + Node + Short; + + typedef + Node + UnsignedShort; + + typedef + Node + Int; + + typedef + Node + UnsignedInt; + + typedef + Node + Long; + + typedef + Node + UnsignedLong; + + typedef + Node + Integer; + + typedef + Node + NonPositiveInteger; + + typedef + Node + NonNegativeInteger; + + typedef + Node + PositiveInteger; + + typedef + Node + NegativeInteger; + + + // Boolean. + // + typedef + Node + Boolean; + + + // Floats. + // + typedef + Node + Float; + + typedef + Node + Double; + + typedef + Node + Decimal; + + + // Strings. + // + typedef + Node + String; + + typedef + Node + NormalizedString; + + typedef + Node + Token; + + typedef + Node + Name; + + typedef + Node + NameToken; + + typedef + Node + NameTokens; + + typedef + Node + NCName; + + typedef + Node + Language; + + + // Qualified name. + // + typedef + Node + QName; + + + // ID/IDREF. + // + typedef + Node + Id; + + typedef + Node + IdRef; + + typedef + Node + IdRefs; + + + // URI. + // + typedef + Node + AnyURI; + + + // Binary. + // + typedef + Node + Base64Binary; + + typedef + Node + HexBinary; + + + // Date/time. + // + typedef + Node + Date; + + typedef + Node + DateTime; + + typedef + Node + Duration; + + typedef + Node + Day; + + typedef + Node + Month; + + typedef + Node + MonthDay; + + typedef + Node + Year; + + typedef + Node + YearMonth; + + typedef + Node + Time; + + + // Entity. + // + typedef + Node + Entity; + + typedef + Node + Entities; + + + // Notation. + // + typedef + Node + Notation; + } + } +} + + +#endif // XSD_FRONTEND_TRAVERSAL_FUNDAMENTAL_HXX diff --git a/libxsd-frontend/xsd-frontend/traversal/list.cxx b/libxsd-frontend/xsd-frontend/traversal/list.cxx new file mode 100644 index 0000000..ec434ba --- /dev/null +++ b/libxsd-frontend/xsd-frontend/traversal/list.cxx @@ -0,0 +1,48 @@ +// file : xsd-frontend/traversal/list.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include + +namespace XSDFrontend +{ + namespace Traversal + { + Void List:: + traverse (Type& l) + { + pre (l); + argumented (l); + name (l); + post (l); + } + + Void List:: + pre (Type&) + { + } + + Void List:: + argumented (Type& l) + { + argumented (l, *this); + } + + Void List:: + argumented (Type& l, EdgeDispatcherBase& d) + { + d.dispatch (l.argumented ()); + } + + Void List:: + name (Type&) + { + } + + Void List:: + post (Type&) + { + } + } +} diff --git a/libxsd-frontend/xsd-frontend/traversal/list.hxx b/libxsd-frontend/xsd-frontend/traversal/list.hxx new file mode 100644 index 0000000..2bbc136 --- /dev/null +++ b/libxsd-frontend/xsd-frontend/traversal/list.hxx @@ -0,0 +1,39 @@ +// file : xsd-frontend/traversal/list.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_FRONTEND_TRAVERSAL_LIST_HXX +#define XSD_FRONTEND_TRAVERSAL_LIST_HXX + +#include +#include + +namespace XSDFrontend +{ + namespace Traversal + { + struct List: Node + { + virtual Void + traverse (Type&); + + virtual Void + pre (Type&); + + virtual Void + argumented (Type&); + + virtual Void + argumented (Type&, EdgeDispatcherBase& d); + + virtual Void + name (Type&); + + virtual Void + post (Type&); + }; + } +} + +#endif // XSD_FRONTEND_TRAVERSAL_LIST_HXX diff --git a/libxsd-frontend/xsd-frontend/traversal/namespace.cxx b/libxsd-frontend/xsd-frontend/traversal/namespace.cxx new file mode 100644 index 0000000..cbc6ef2 --- /dev/null +++ b/libxsd-frontend/xsd-frontend/traversal/namespace.cxx @@ -0,0 +1,13 @@ +// file : xsd-frontend/traversal/namespace.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include + +namespace XSDFrontend +{ + namespace Traversal + { + } +} diff --git a/libxsd-frontend/xsd-frontend/traversal/namespace.hxx b/libxsd-frontend/xsd-frontend/traversal/namespace.hxx new file mode 100644 index 0000000..22305e1 --- /dev/null +++ b/libxsd-frontend/xsd-frontend/traversal/namespace.hxx @@ -0,0 +1,45 @@ +// file : xsd-frontend/traversal/namespace.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_FRONTEND_TRAVERSAL_NAMESPACE_HXX +#define XSD_FRONTEND_TRAVERSAL_NAMESPACE_HXX + +#include +#include + +namespace XSDFrontend +{ + namespace Traversal + { + struct Namespace: ScopeTemplate + { + virtual Void + traverse (Type& m) + { + pre (m); + name (m); + names (m); + post (m); + } + + virtual Void + pre (Type&) + { + } + + virtual Void + name (Type&) + { + } + + virtual Void + post (Type&) + { + } + }; + } +} + +#endif // XSD_FRONTEND_TRAVERSAL_NAMESPACE_HXX diff --git a/libxsd-frontend/xsd-frontend/traversal/particle.cxx b/libxsd-frontend/xsd-frontend/traversal/particle.cxx new file mode 100644 index 0000000..e3d3a97 --- /dev/null +++ b/libxsd-frontend/xsd-frontend/traversal/particle.cxx @@ -0,0 +1,31 @@ +// file : xsd-frontend/traversal/particle.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2006-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include + +namespace XSDFrontend +{ + namespace Traversal + { + // Particle + // + Void Particle:: + traverse (Type& c) + { + pre (c); + post (c); + } + + Void Particle:: + pre (Type&) + { + } + + Void Particle:: + post (Type&) + { + } + } +} diff --git a/libxsd-frontend/xsd-frontend/traversal/particle.hxx b/libxsd-frontend/xsd-frontend/traversal/particle.hxx new file mode 100644 index 0000000..3584c12 --- /dev/null +++ b/libxsd-frontend/xsd-frontend/traversal/particle.hxx @@ -0,0 +1,30 @@ +// file : xsd-frontend/traversal/particle.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2006-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_FRONTEND_TRAVERSAL_PARTICLE_HXX +#define XSD_FRONTEND_TRAVERSAL_PARTICLE_HXX + +#include +#include + +namespace XSDFrontend +{ + namespace Traversal + { + struct Particle : Node + { + virtual Void + traverse (Type&); + + virtual Void + pre (Type&); + + virtual Void + post (Type&); + }; + } +} + +#endif // XSD_FRONTEND_TRAVERSAL_PARTICLE_HXX diff --git a/libxsd-frontend/xsd-frontend/traversal/schema.cxx b/libxsd-frontend/xsd-frontend/traversal/schema.cxx new file mode 100644 index 0000000..acfca26 --- /dev/null +++ b/libxsd-frontend/xsd-frontend/traversal/schema.cxx @@ -0,0 +1,13 @@ +// file : xsd-frontend/traversal/schema.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include + +namespace XSDFrontend +{ + namespace Traversal + { + } +} diff --git a/libxsd-frontend/xsd-frontend/traversal/schema.hxx b/libxsd-frontend/xsd-frontend/traversal/schema.hxx new file mode 100644 index 0000000..a975475 --- /dev/null +++ b/libxsd-frontend/xsd-frontend/traversal/schema.hxx @@ -0,0 +1,150 @@ +// file : xsd-frontend/traversal/schema.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_FRONTEND_TRAVERSAL_SCHEMA_HXX +#define XSD_FRONTEND_TRAVERSAL_SCHEMA_HXX + +#include +#include + +namespace XSDFrontend +{ + namespace Traversal + { + // + // + struct Uses: Edge + { + Uses () + { + } + + Uses (NodeBase& n) + { + node_traverser (n); + } + + virtual Void + traverse (Type& e) + { + dispatch (e.schema ()); + } + }; + + // + // + struct Implies: Edge + { + Implies () + { + } + + Implies (NodeBase& n) + { + node_traverser (n); + } + + virtual Void + traverse (Type& e) + { + dispatch (e.schema ()); + } + }; + + + // + // + struct Sources: Edge + { + Sources () + { + } + + Sources (NodeBase& n) + { + node_traverser (n); + } + + virtual Void + traverse (Type& e) + { + dispatch (e.schema ()); + } + }; + + + // + // + struct Includes: Edge + { + Includes () + { + } + + Includes (NodeBase& n) + { + node_traverser (n); + } + + virtual Void + traverse (Type& e) + { + dispatch (e.schema ()); + } + }; + + + // + // + struct Imports: Edge + { + Imports () + { + } + + Imports (NodeBase& n) + { + node_traverser (n); + } + + virtual Void + traverse (Type& e) + { + dispatch (e.schema ()); + } + }; + + + // + // + struct Schema: ScopeTemplate + { + virtual Void + traverse (Type& s) + { + pre (s); + + iterate_and_dispatch ( + s.uses_begin (), s.uses_end (), edge_traverser ()); + + names (s); + + post (s); + } + + virtual Void + pre (Type&) + { + } + + virtual Void + post (Type&) + { + } + }; + } +} + +#endif // XSD_FRONTEND_TRAVERSAL_SCHEMA_HXX diff --git a/libxsd-frontend/xsd-frontend/traversal/union.cxx b/libxsd-frontend/xsd-frontend/traversal/union.cxx new file mode 100644 index 0000000..acf419a --- /dev/null +++ b/libxsd-frontend/xsd-frontend/traversal/union.cxx @@ -0,0 +1,48 @@ +// file : xsd-frontend/traversal/union.cxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#include + +namespace XSDFrontend +{ + namespace Traversal + { + Void Union:: + traverse (Type& u) + { + pre (u); + argumented (u); + name (u); + post (u); + } + + Void Union:: + pre (Type&) + { + } + + Void Union:: + argumented (Type& u) + { + argumented (u, *this); + } + + Void Union:: + argumented (Type& u, EdgeDispatcherBase& d) + { + iterate_and_dispatch (u.argumented_begin (), u.argumented_end (), d); + } + + Void Union:: + name (Type&) + { + } + + Void Union:: + post (Type&) + { + } + } +} diff --git a/libxsd-frontend/xsd-frontend/traversal/union.hxx b/libxsd-frontend/xsd-frontend/traversal/union.hxx new file mode 100644 index 0000000..e3d31bd --- /dev/null +++ b/libxsd-frontend/xsd-frontend/traversal/union.hxx @@ -0,0 +1,39 @@ +// file : xsd-frontend/traversal/union.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_FRONTEND_TRAVERSAL_UNION_HXX +#define XSD_FRONTEND_TRAVERSAL_UNION_HXX + +#include +#include + +namespace XSDFrontend +{ + namespace Traversal + { + struct Union: Node + { + virtual Void + traverse (Type&); + + virtual Void + pre (Type&); + + virtual Void + argumented (Type&); + + virtual Void + argumented (Type&, EdgeDispatcherBase& d); + + virtual Void + name (Type&); + + virtual Void + post (Type&); + }; + } +} + +#endif // XSD_FRONTEND_TRAVERSAL_UNION_HXX diff --git a/libxsd-frontend/xsd-frontend/types.hxx b/libxsd-frontend/xsd-frontend/types.hxx new file mode 100644 index 0000000..b3059fd --- /dev/null +++ b/libxsd-frontend/xsd-frontend/types.hxx @@ -0,0 +1,18 @@ +// file : xsd-frontend/types.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_FRONTEND_TYPES_HXX +#define XSD_FRONTEND_TYPES_HXX + +#include + +namespace XSDFrontend +{ + using namespace Cult::Types; + + typedef Cult::WideString String; +} + +#endif // XSD_FRONTEND_TYPES_HXX diff --git a/libxsd-frontend/xsd-frontend/xml.hxx b/libxsd-frontend/xsd-frontend/xml.hxx new file mode 100644 index 0000000..8c9b01c --- /dev/null +++ b/libxsd-frontend/xsd-frontend/xml.hxx @@ -0,0 +1,567 @@ +// file : xsd-frontend/xml.hxx +// author : Boris Kolpackov +// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC +// license : GNU GPL v2 + exceptions; see accompanying LICENSE file + +#ifndef XSD_FRONTEND_XML_HXX +#define XSD_FRONTEND_XML_HXX + +#include + +#include +#include + +#include + +#include +#include + +namespace XSDFrontend +{ + namespace XML + { + namespace Xerces = xercesc; + + inline + String + transcode (XMLCh const* s, Size length) + { + if (sizeof (WideChar) == 4) + { + // UTF-32 + // + XMLCh const* end (s + length); + + // Find what the resulting buffer size will be. + // + Size rl (0); + Boolean valid (true); + + for (XMLCh const* p (s); p < end; ++p) + { + rl++; + + if ((*p >= 0xD800) && (*p <= 0xDBFF)) + { + // Make sure we have one more char and it has a valid + // value for the second char in a surrogate pair. + // + if (++p == end || !((*p >= 0xDC00) && (*p <= 0xDFFF))) + { + valid = false; + break; + } + } + } + + if (!valid) + return String (); + + String r; + r.reserve (rl + 1); + r.resize (rl); + WideChar* rs (const_cast (r.c_str ())); + + Size i (0); + + for (XMLCh const* p (s); p < end; ++p) + { + XMLCh x (*p); + + if (x < 0xD800 || x > 0xDBFF) + rs[i++] = WideChar (x); + else + rs[i++] = ((x - 0xD800) << 10) + (*++p - 0xDC00) + 0x10000; + } + + return r; + } + else if (sizeof (WideChar) == 2) + { + // UTF-16 + // + return String (reinterpret_cast (s), length); + } + else + return String (); + } + + inline + String + transcode (XMLCh const* s) + { + return transcode (s, Xerces::XMLString::stringLen (s)); + } + + inline + NarrowString + transcode_to_narrow (XMLCh const* xs) + { + Char* s (Xerces::XMLString::transcode (xs)); + NarrowString r (s); + Xerces::XMLString::release (&s); + return r; + } + + inline + XMLCh* + transcode (String const& str) + { + Size l (str.size ()); + WideChar const* s (str.c_str ()); + + if (sizeof (WideChar) == 4) + { + // Find what the resulting buffer size will be. + // + Size rl (0); + + for (WideChar const* p (s); p < s + l; ++p) + { + rl += (*p & 0xFFFF0000) ? 2 : 1; + } + + XMLCh* r (new XMLCh[rl + 1]); + XMLCh* ir (r); + + for (WideChar const* p (s); p < s + l; ++p) + { + WideChar w (*p); + + if (w & 0xFFFF0000) + { + // Surrogate pair. + // + *ir++ = static_cast (((w - 0x10000) >> 10) + 0xD800); + *ir++ = static_cast ((w & 0x3FF) + 0xDC00); + } + else + *ir++ = static_cast (w); + } + + *ir = XMLCh (0); + + return r; + } + else if (sizeof (WideChar) == 2) + { + XMLCh* r (new XMLCh[l + 1]); + XMLCh* ir (r); + + for (Size i (0); i < l; ++ir, ++i) + *ir = static_cast (s[i]); + + *ir = XMLCh (0); + + return r; + } + else + return 0; + } + + class XMLChString + { + public : + XMLChString (String const& s) + : s_ (transcode (s)) + { + } + + XMLChString (WideChar const* s) + : s_ (transcode (String (s))) + { + } + + ~XMLChString () + { + delete[] s_; + } + + XMLCh const* + c_str () const + { + return s_; + } + + private: + XMLChString (XMLChString const&); + + XMLChString& + operator= (XMLChString const&); + + private: + XMLCh* s_; + }; + + + class Element + { + public: + Element (Xerces::DOMElement* e) + : e_ (e), + name_ (transcode (e->getLocalName ())), + namespace__ (transcode (e->getNamespaceURI ())) + { + } + + String + name () const + { + return name_; + } + + String + namespace_ () const + { + return namespace__; + } + + public: + UnsignedLong + line () const + { + //@@ cache + // + return reinterpret_cast (e_->getUserData (line_key)); + } + + UnsignedLong + column () const + { + //@@ cache + // + return reinterpret_cast (e_->getUserData (column_key)); + } + + public: + Element + parent () const + { + return dynamic_cast(e_->getParentNode ()); + } + + public: + // Attribute identified by a name. + // + Boolean + attribute_p (String const& name) const + { + return attribute_p ("", name); + } + + String + attribute (String const& name) const + { + return attribute ("", name); + } + + String + operator[] (String const& name) const + { + return attribute (name); + } + + // Attribute identified by namespace and name. + // + + Boolean + attribute_p (String const& namespace_, String const& name) const + { + Xerces::DOMAttr* a ( + e_->getAttributeNodeNS ( + XMLChString (namespace_).c_str (), + XMLChString (name).c_str ())); + + return a != 0; + } + + String + attribute (String const& namespace_, String const& name) const + { + XMLCh const* value ( + e_->getAttributeNS ( + XMLChString (namespace_).c_str (), + XMLChString (name).c_str ())); + + return transcode (value); + } + + public: + Xerces::DOMElement* + dom_element () const + { + return e_; + } + + private: + Xerces::DOMElement* e_; + + String name_; + String namespace__; + }; + + inline String + prefix (String const& n) + { + Size i (0); + while (i < n.length () && n[i] != L':') ++i; + + //std::wcerr << "prefix " << n << " " + // << String (n, i == n.length () ? i : 0, i) << std::endl; + + return String (n, i == n.length () ? i : 0, i); + } + + inline String + uq_name (String const& n) + { + Size i (0); + while (i < n.length () && n[i] != L':') ++i; + + return String (n.c_str () + (i == n.length () ? 0 : i + 1)); + } + + struct NoMapping + { + NoMapping (String const& prefix) + : prefix_ (prefix) + { + } + + String const& + prefix () const + { + return prefix_; + } + + private: + String prefix_; + }; + + // Throws NoMapping if there is no prefix-namespace association. + // + inline String + ns_name (Xerces::DOMElement const* e, String const& prefix) + { + // 'xml' prefix requires special handling and Xerces folks refuse + // to handle this in DOM so I have to do it myself. + // + if (prefix == L"xml") + return L"http://www.w3.org/XML/1998/namespace"; + + // 0 means "no prefix" to Xerces. + // + XMLCh const* xns ( + e->lookupNamespaceURI ( + prefix.empty () ? 0 : XMLChString (prefix).c_str ())); + + if (xns == 0) + throw NoMapping (prefix); + + return transcode (xns); + } + + class NoPrefix {}; + + inline String + ns_prefix (Element const& e, String const& wns) + { + XMLChString ns (wns); + +#if _XERCES_VERSION >= 30000 + XMLCh const* p ( + e.dom_element ()->lookupPrefix (ns.c_str ())); +#else + XMLCh const* p ( + e.dom_element ()->lookupNamespacePrefix (ns.c_str (), false)); +#endif + + if (p == 0) + { + Boolean r (e.dom_element ()->isDefaultNamespace (ns.c_str ())); + + if (r) + return L""; + else + { + // 'xml' prefix requires special handling and Xerces folks refuse + // to handle this in DOM so I have to do it myself. + // + if (wns == L"http://www.w3.org/XML/1998/namespace") + return L"xml"; + + throw NoPrefix (); + } + } + + return transcode (p); + } + + inline String + fq_name (Element const& e, String const& n) + { + String un (uq_name (n)); + + try + { + String ns (ns_name (e.dom_element (), prefix (n))); + return ns + L'#' + un; + } + catch (XML::NoMapping const&) + { + return un; + } + } + + + // Simple auto_ptr version that calls release() instead of delete. + // + + template + struct AutoPtrRef + { + X* x_; + + explicit + AutoPtrRef (X* x) + : x_ (x) + { + } + }; + + template + struct AutoPtr + { + ~AutoPtr () + { + reset (); + } + + explicit + AutoPtr (X* x = 0) + : x_ (x) + { + } + + AutoPtr (AutoPtr& y) + : x_ (y.release ()) + { + } + + AutoPtr (AutoPtrRef r) + : x_ (r.x_) + { + } + + AutoPtr& + operator= (AutoPtr& y) + { + if (this != &y) + { + reset (y.release ()); + } + + return *this; + } + + AutoPtr& + operator= (AutoPtrRef r) + { + if (r.x_ != x_) + { + reset (r.x_); + } + + return *this; + } + + operator AutoPtrRef () + { + return AutoPtrRef (release ()); + } + + public: + X& + operator* () const + { + return *x_; + } + + X* + operator-> () const + { + return x_; + } + + X* + get () const + { + return x_; + } + + X* + release () + { + X* x (x_); + x_ = 0; + return x; + } + + void + reset (X* x = 0) + { + if (x_) + x_->release (); + + x_ = x; + } + + // Conversion to bool. + // + typedef X* (AutoPtr::*BooleanConvertible)() const; + + operator BooleanConvertible () const throw () + { + return x_ ? &AutoPtr::operator-> : 0; + } + + private: + X* x_; + }; + + template + struct PtrVector: Cult::Containers::Vector + { + typedef Cult::Containers::Vector Base; + + ~PtrVector () + { + for (typename Base::Iterator i (this->begin ()), e (this->end ()); + i != e; ++i) + { + if (*i) + (*i)->release (); + } + } + + Void + push_back (AutoPtr& x) + { + Base::push_back (0); + this->back () = x.release (); + } + }; + } +} + +// Xerces DOoM. +// +// +inline +std::wostream& +operator<< (std::wostream& o, XMLCh const* s) +{ + return o << XSDFrontend::XML::transcode (s); +} + +#endif // XSD_FRONTEND_XML_HXX -- cgit v1.2.3