summaryrefslogtreecommitdiff
path: root/libxsd-frontend
diff options
context:
space:
mode:
authorJörg Frings-Fürst <jff@merkur>2014-05-18 16:08:14 +0200
committerJörg Frings-Fürst <jff@merkur>2014-05-18 16:08:14 +0200
commita15cf65c44d5c224169c32ef5495b68c758134b7 (patch)
tree3419f58fc8e1b315ba8171910ee044c5d467c162 /libxsd-frontend
Imported Upstream version 3.3.0.2upstream/3.3.0.2
Diffstat (limited to 'libxsd-frontend')
-rw-r--r--libxsd-frontend/GPLv2340
-rw-r--r--libxsd-frontend/INSTALL28
-rw-r--r--libxsd-frontend/LICENSE22
-rw-r--r--libxsd-frontend/NEWS281
-rw-r--r--libxsd-frontend/README13
-rw-r--r--libxsd-frontend/build/bootstrap.make46
-rw-r--r--libxsd-frontend/build/cxx/configuration-dynamic.make14
-rw-r--r--libxsd-frontend/build/cxx/gnu/configuration-dynamic.make8
-rw-r--r--libxsd-frontend/build/export/libxsd-frontend/stub.make10
-rw-r--r--libxsd-frontend/build/import/libboost/LICENSE340
-rw-r--r--libxsd-frontend/build/import/libboost/configuration-dynamic.make8
-rw-r--r--libxsd-frontend/build/import/libboost/configuration-rules.make15
-rwxr-xr-xlibxsd-frontend/build/import/libboost/configure74
-rw-r--r--libxsd-frontend/build/import/libboost/filesystem/rules.make53
-rw-r--r--libxsd-frontend/build/import/libboost/filesystem/stub.make36
-rw-r--r--libxsd-frontend/build/import/libboost/version1
-rw-r--r--libxsd-frontend/build/import/libcult/LICENSE340
-rw-r--r--libxsd-frontend/build/import/libcult/configuration-dynamic.make4
-rw-r--r--libxsd-frontend/build/import/libcult/configuration-rules.make15
-rwxr-xr-xlibxsd-frontend/build/import/libcult/configure55
-rw-r--r--libxsd-frontend/build/import/libcult/stub.make30
-rw-r--r--libxsd-frontend/build/import/libfrontend-elements/LICENSE340
-rw-r--r--libxsd-frontend/build/import/libfrontend-elements/configuration-dynamic.make4
-rw-r--r--libxsd-frontend/build/import/libfrontend-elements/configuration-rules.make15
-rwxr-xr-xlibxsd-frontend/build/import/libfrontend-elements/configure55
-rw-r--r--libxsd-frontend/build/import/libfrontend-elements/stub.make30
-rw-r--r--libxsd-frontend/build/import/libxerces-c/LICENSE340
-rw-r--r--libxsd-frontend/build/import/libxerces-c/configuration-dynamic.make1
-rw-r--r--libxsd-frontend/build/import/libxerces-c/configuration-rules.make15
-rwxr-xr-xlibxsd-frontend/build/import/libxerces-c/configure73
-rw-r--r--libxsd-frontend/build/import/libxerces-c/rules.make52
-rw-r--r--libxsd-frontend/build/import/libxerces-c/stub.make32
-rw-r--r--libxsd-frontend/build/import/libxerces-c/version1
l---------libxsd-frontend/build/import/libxsd-frontend/LICENSE1
-rw-r--r--libxsd-frontend/build/import/libxsd-frontend/configuration-rules.make15
-rwxr-xr-xlibxsd-frontend/build/import/libxsd-frontend/configure55
-rw-r--r--libxsd-frontend/build/import/libxsd-frontend/stub.make30
-rw-r--r--libxsd-frontend/build/ld/configuration-lib-dynamic.make13
-rw-r--r--libxsd-frontend/makefile17
-rw-r--r--libxsd-frontend/tests/dump/driver.cxx734
-rw-r--r--libxsd-frontend/tests/dump/makefile56
-rw-r--r--libxsd-frontend/tests/makefile17
-rw-r--r--libxsd-frontend/tests/schema/annotation/makefile35
-rw-r--r--libxsd-frontend/tests/schema/annotation/test-000.std67
-rw-r--r--libxsd-frontend/tests/schema/annotation/test-000.xsd120
-rw-r--r--libxsd-frontend/tests/schema/annotation/test-001.std36
-rw-r--r--libxsd-frontend/tests/schema/annotation/test-001.xsd53
-rw-r--r--libxsd-frontend/tests/schema/anonymous/makefile35
-rw-r--r--libxsd-frontend/tests/schema/anonymous/test-000.std30
-rw-r--r--libxsd-frontend/tests/schema/anonymous/test-000.xsd42
-rw-r--r--libxsd-frontend/tests/schema/anonymous/test-001.std38
-rw-r--r--libxsd-frontend/tests/schema/anonymous/test-001.xsd47
-rw-r--r--libxsd-frontend/tests/schema/attribute-group/makefile35
-rw-r--r--libxsd-frontend/tests/schema/attribute-group/test-000.std17
-rw-r--r--libxsd-frontend/tests/schema/attribute-group/test-000.xsd31
-rw-r--r--libxsd-frontend/tests/schema/attribute-group/test-001.std12
-rw-r--r--libxsd-frontend/tests/schema/attribute-group/test-001.xsd20
-rw-r--r--libxsd-frontend/tests/schema/default/makefile35
-rw-r--r--libxsd-frontend/tests/schema/default/test-000.std28
-rw-r--r--libxsd-frontend/tests/schema/default/test-000.xsd23
-rw-r--r--libxsd-frontend/tests/schema/default/test-001.std15
-rw-r--r--libxsd-frontend/tests/schema/default/test-001.xsd11
-rw-r--r--libxsd-frontend/tests/schema/element-group/makefile35
-rw-r--r--libxsd-frontend/tests/schema/element-group/test-000.std33
-rw-r--r--libxsd-frontend/tests/schema/element-group/test-000.xsd39
-rw-r--r--libxsd-frontend/tests/schema/element-group/test-001.std137
-rw-r--r--libxsd-frontend/tests/schema/element-group/test-001.xsd33
-rw-r--r--libxsd-frontend/tests/schema/element-group/test-002.std24
-rw-r--r--libxsd-frontend/tests/schema/element-group/test-002.xsd26
-rw-r--r--libxsd-frontend/tests/schema/enumeration/makefile35
-rw-r--r--libxsd-frontend/tests/schema/enumeration/test-000.std62
-rw-r--r--libxsd-frontend/tests/schema/enumeration/test-000.xsd72
-rw-r--r--libxsd-frontend/tests/schema/makefile25
-rw-r--r--libxsd-frontend/tests/schema/union/makefile35
-rw-r--r--libxsd-frontend/tests/schema/union/test-000.std37
-rw-r--r--libxsd-frontend/tests/schema/union/test-000.xsd40
-rw-r--r--libxsd-frontend/tests/schema/union/test-001.std15
-rw-r--r--libxsd-frontend/tests/schema/union/test-001.xsd21
-rw-r--r--libxsd-frontend/version1
-rw-r--r--libxsd-frontend/xsd-frontend/makefile126
-rw-r--r--libxsd-frontend/xsd-frontend/parser.cxx5126
-rw-r--r--libxsd-frontend/xsd-frontend/parser.hxx76
-rw-r--r--libxsd-frontend/xsd-frontend/schema-dom-parser.cxx196
-rw-r--r--libxsd-frontend/xsd-frontend/schema-dom-parser.hxx93
-rw-r--r--libxsd-frontend/xsd-frontend/semantic-graph.hxx27
-rw-r--r--libxsd-frontend/xsd-frontend/semantic-graph/annotation.cxx50
-rw-r--r--libxsd-frontend/xsd-frontend/semantic-graph/annotation.hxx89
-rw-r--r--libxsd-frontend/xsd-frontend/semantic-graph/any-attribute.cxx114
-rw-r--r--libxsd-frontend/xsd-frontend/semantic-graph/any-attribute.hxx85
-rw-r--r--libxsd-frontend/xsd-frontend/semantic-graph/any.cxx125
-rw-r--r--libxsd-frontend/xsd-frontend/semantic-graph/any.hxx90
-rw-r--r--libxsd-frontend/xsd-frontend/semantic-graph/attribute-group.cxx39
-rw-r--r--libxsd-frontend/xsd-frontend/semantic-graph/attribute-group.hxx27
-rw-r--r--libxsd-frontend/xsd-frontend/semantic-graph/attribute.cxx44
-rw-r--r--libxsd-frontend/xsd-frontend/semantic-graph/attribute.hxx39
-rw-r--r--libxsd-frontend/xsd-frontend/semantic-graph/complex.cxx45
-rw-r--r--libxsd-frontend/xsd-frontend/semantic-graph/complex.hxx78
-rw-r--r--libxsd-frontend/xsd-frontend/semantic-graph/compositors.cxx124
-rw-r--r--libxsd-frontend/xsd-frontend/semantic-graph/compositors.hxx263
-rw-r--r--libxsd-frontend/xsd-frontend/semantic-graph/element-group.cxx38
-rw-r--r--libxsd-frontend/xsd-frontend/semantic-graph/element-group.hxx45
-rw-r--r--libxsd-frontend/xsd-frontend/semantic-graph/element.cxx63
-rw-r--r--libxsd-frontend/xsd-frontend/semantic-graph/element.hxx105
-rw-r--r--libxsd-frontend/xsd-frontend/semantic-graph/elements.cxx350
-rw-r--r--libxsd-frontend/xsd-frontend/semantic-graph/elements.hxx1247
-rw-r--r--libxsd-frontend/xsd-frontend/semantic-graph/enumeration.cxx67
-rw-r--r--libxsd-frontend/xsd-frontend/semantic-graph/enumeration.hxx35
-rw-r--r--libxsd-frontend/xsd-frontend/semantic-graph/fundamental.cxx.m4216
-rw-r--r--libxsd-frontend/xsd-frontend/semantic-graph/fundamental.hxx.m4165
-rw-r--r--libxsd-frontend/xsd-frontend/semantic-graph/fundamental.m418
-rw-r--r--libxsd-frontend/xsd-frontend/semantic-graph/list.cxx37
-rw-r--r--libxsd-frontend/xsd-frontend/semantic-graph/list.hxx25
-rw-r--r--libxsd-frontend/xsd-frontend/semantic-graph/namespace.cxx37
-rw-r--r--libxsd-frontend/xsd-frontend/semantic-graph/namespace.hxx32
-rw-r--r--libxsd-frontend/xsd-frontend/semantic-graph/particle.cxx61
-rw-r--r--libxsd-frontend/xsd-frontend/semantic-graph/particle.hxx145
-rw-r--r--libxsd-frontend/xsd-frontend/semantic-graph/schema.cxx139
-rw-r--r--libxsd-frontend/xsd-frontend/semantic-graph/schema.hxx281
-rw-r--r--libxsd-frontend/xsd-frontend/semantic-graph/union.cxx37
-rw-r--r--libxsd-frontend/xsd-frontend/semantic-graph/union.hxx25
-rw-r--r--libxsd-frontend/xsd-frontend/transformations/anonymous.cxx739
-rw-r--r--libxsd-frontend/xsd-frontend/transformations/anonymous.hxx60
-rw-r--r--libxsd-frontend/xsd-frontend/transformations/enum-synthesis.cxx249
-rw-r--r--libxsd-frontend/xsd-frontend/transformations/enum-synthesis.hxx33
-rw-r--r--libxsd-frontend/xsd-frontend/transformations/restriction.cxx582
-rw-r--r--libxsd-frontend/xsd-frontend/transformations/restriction.hxx39
-rw-r--r--libxsd-frontend/xsd-frontend/transformations/schema-per-type.cxx453
-rw-r--r--libxsd-frontend/xsd-frontend/transformations/schema-per-type.hxx61
-rw-r--r--libxsd-frontend/xsd-frontend/transformations/simplifier.cxx167
-rw-r--r--libxsd-frontend/xsd-frontend/transformations/simplifier.hxx33
-rw-r--r--libxsd-frontend/xsd-frontend/traversal.hxx26
-rw-r--r--libxsd-frontend/xsd-frontend/traversal/any-attribute.hxx22
-rw-r--r--libxsd-frontend/xsd-frontend/traversal/any.hxx22
-rw-r--r--libxsd-frontend/xsd-frontend/traversal/attribute-group.cxx30
-rw-r--r--libxsd-frontend/xsd-frontend/traversal/attribute-group.hxx30
-rw-r--r--libxsd-frontend/xsd-frontend/traversal/attribute.cxx48
-rw-r--r--libxsd-frontend/xsd-frontend/traversal/attribute.hxx41
-rw-r--r--libxsd-frontend/xsd-frontend/traversal/complex.cxx64
-rw-r--r--libxsd-frontend/xsd-frontend/traversal/complex.hxx45
-rw-r--r--libxsd-frontend/xsd-frontend/traversal/compositors.cxx165
-rw-r--r--libxsd-frontend/xsd-frontend/traversal/compositors.hxx136
-rw-r--r--libxsd-frontend/xsd-frontend/traversal/element-group.cxx43
-rw-r--r--libxsd-frontend/xsd-frontend/traversal/element-group.hxx36
-rw-r--r--libxsd-frontend/xsd-frontend/traversal/element.cxx48
-rw-r--r--libxsd-frontend/xsd-frontend/traversal/element.hxx39
-rw-r--r--libxsd-frontend/xsd-frontend/traversal/elements.cxx77
-rw-r--r--libxsd-frontend/xsd-frontend/traversal/elements.hxx480
-rw-r--r--libxsd-frontend/xsd-frontend/traversal/elements.txx11
-rw-r--r--libxsd-frontend/xsd-frontend/traversal/enumeration.cxx91
-rw-r--r--libxsd-frontend/xsd-frontend/traversal/enumeration.hxx60
-rw-r--r--libxsd-frontend/xsd-frontend/traversal/fundamental.cxx13
-rw-r--r--libxsd-frontend/xsd-frontend/traversal/fundamental.hxx234
-rw-r--r--libxsd-frontend/xsd-frontend/traversal/list.cxx48
-rw-r--r--libxsd-frontend/xsd-frontend/traversal/list.hxx39
-rw-r--r--libxsd-frontend/xsd-frontend/traversal/namespace.cxx13
-rw-r--r--libxsd-frontend/xsd-frontend/traversal/namespace.hxx45
-rw-r--r--libxsd-frontend/xsd-frontend/traversal/particle.cxx31
-rw-r--r--libxsd-frontend/xsd-frontend/traversal/particle.hxx30
-rw-r--r--libxsd-frontend/xsd-frontend/traversal/schema.cxx13
-rw-r--r--libxsd-frontend/xsd-frontend/traversal/schema.hxx150
-rw-r--r--libxsd-frontend/xsd-frontend/traversal/union.cxx48
-rw-r--r--libxsd-frontend/xsd-frontend/traversal/union.hxx39
-rw-r--r--libxsd-frontend/xsd-frontend/types.hxx18
-rw-r--r--libxsd-frontend/xsd-frontend/xml.hxx567
164 files changed, 20271 insertions, 0 deletions
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.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ 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.
+
+ <signature of Ty Coon>, 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 <namespace>#<qname> 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 <boris@codesynthesis.com>
+# 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 <boris@codesynthesis.com>
+# 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.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ 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.
+
+ <signature of Ty Coon>, 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 <boris@kolpackov.net>
+# 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 <boris@kolpackov.net>
+# 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 <boris@kolpackov.net>
+# 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 <boris@kolpackov.net>
+# 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.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ 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.
+
+ <signature of Ty Coon>, 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 <boris@kolpackov.net>
+# 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 <boris@kolpackov.net>
+# 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 <boris@kolpackov.net>
+# 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.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ 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.
+
+ <signature of Ty Coon>, 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 <boris@kolpackov.net>
+# 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 <boris@kolpackov.net>
+# 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 <boris@kolpackov.net>
+# 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.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ 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.
+
+ <signature of Ty Coon>, 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 <boris@kolpackov.net>
+# 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 <boris@kolpackov.net>
+# 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 <boris@kolpackov.net>
+# 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 <boris@kolpackov.net>
+# 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 <boris@codesynthesis.com>
+# 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 <boris@codesynthesis.com>
+# 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 <boris@codesynthesis.com>
+# 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 <boris@codesynthesis.com>
+# 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 <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2010 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <cult/types.hxx>
+
+#include <xsd-frontend/parser.hxx>
+#include <xsd-frontend/transformations/anonymous.hxx>
+#include <xsd-frontend/transformations/enum-synthesis.hxx>
+
+#include <xsd-frontend/semantic-graph.hxx>
+#include <xsd-frontend/traversal.hxx>
+
+#include <iostream>
+
+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 ("<anonymous>"));
+
+ 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 ("<anonymous>")) << " ";
+
+ 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 ("<anonymous>")) << ": " <<
+ 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 <recursive-anonymous>" << 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 ("<anonymous>"));
+
+ 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<SemanticGraph::Schema> 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 <boris@codesynthesis.com>
+# 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 <boris@codesynthesis.com>
+# 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 <boris@codesynthesis.com>
+# 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 @@
+<schema documentation>
+primary
+{
+ namespace test
+ {
+ <list type documentation>
+ list list http://www.w3.org/2001/XMLSchema#string
+ <union type documentation>
+ union union http://www.w3.org/2001/XMLSchema#int http://www.w3.org/2001/XMLSchema#string
+ <enumeration type documentation>
+ enumeration enum: http://www.w3.org/2001/XMLSchema#string
+ {
+ <enumerator documentation (male)>
+ enumerator male
+ <enumerator documentation (female)>
+ enumerator female
+ }
+ <complex type documentation>
+ complex type
+ {
+ <local element efoo documentation>
+ element efoo
+ <local element ebar documentation>
+ element ebar
+ <local element ebaz documentation>
+ element ebaz
+ <any documentation>
+ any 'any #0'
+ <local attribute afoo documentation>
+ optional attribute afoo http://www.w3.org/2001/XMLSchema#string
+ <local attribute abar documentation>
+ optional attribute abar
+ {
+ <list type documentation>
+ list <anonymous> http://www.w3.org/2001/XMLSchema#string
+ }
+ <local attribute abaz documentation>
+ optional attribute abaz http://www.w3.org/2001/XMLSchema#string
+ <anyAttribute documentation>
+ any-attribute 'any-attribute #0'
+ [1, 1] sequence
+ {
+ [1, 1] element efoo http://www.w3.org/2001/XMLSchema#string
+ [1, 1] element ebar
+ {
+ complex <anonymous>
+ {
+ <nested local element efoo documentation>
+ element efoo
+ <nested local attribute afoo documentation>
+ 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'
+ }
+ }
+ <global element documentation>
+ element ebaz http://www.w3.org/2001/XMLSchema#string
+ <global attribute documentation>
+ 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 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:t="test" targetNamespace="test">
+
+ <annotation>
+ <documentation>schema documentation</documentation>
+ </annotation>
+
+ <simpleType name="list">
+ <annotation>
+ <documentation>list type documentation</documentation>
+ </annotation>
+ <list itemType="string"/>
+ </simpleType>
+
+ <simpleType name="union">
+ <annotation>
+ <documentation>union type documentation</documentation>
+ </annotation>
+ <union memberTypes="int string"/>
+ </simpleType>
+
+ <simpleType name="enum">
+ <annotation>
+ <documentation>enumeration type documentation</documentation>
+ </annotation>
+ <restriction base="string">
+ <enumeration value="male">
+ <annotation>
+ <documentation>enumerator documentation (male)</documentation>
+ </annotation>
+ </enumeration>
+ <enumeration value="female">
+ <annotation>
+ <documentation>enumerator documentation (female)</documentation>
+ </annotation>
+ </enumeration>
+ </restriction>
+ </simpleType>
+
+ <complexType name="type">
+ <annotation>
+ <documentation>complex type documentation</documentation>
+ </annotation>
+ <sequence>
+ <element name="efoo" type="string">
+ <annotation>
+ <documentation>local element efoo documentation</documentation>
+ </annotation>
+ </element>
+ <element name="ebar">
+ <annotation>
+ <documentation>local element ebar documentation</documentation>
+ </annotation>
+ <complexType>
+ <sequence>
+ <element name="efoo" type="string">
+ <annotation>
+ <documentation>nested local element efoo documentation</documentation>
+ </annotation>
+ </element>
+ </sequence>
+ <attribute name="afoo" type="string">
+ <annotation>
+ <documentation>nested local attribute afoo documentation</documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+ <element ref="t:ebaz">
+ <annotation>
+ <documentation>local element ebaz documentation</documentation>
+ </annotation>
+ </element>
+ <any namespace="##other">
+ <annotation>
+ <documentation>any documentation</documentation>
+ </annotation>
+ </any>
+ </sequence>
+ <attribute name="afoo" type="string">
+ <annotation>
+ <documentation>local attribute afoo documentation</documentation>
+ </annotation>
+ </attribute>
+ <attribute name="abar">
+ <annotation>
+ <documentation>local attribute abar documentation</documentation>
+ </annotation>
+ <simpleType>
+ <annotation>
+ <documentation>list type documentation</documentation>
+ </annotation>
+ <list itemType="string"/>
+ </simpleType>
+ </attribute>
+ <attribute ref="t:abaz">
+ <annotation>
+ <documentation>local attribute abaz documentation</documentation>
+ </annotation>
+ </attribute>
+ <anyAttribute namespace="##other">
+ <annotation>
+ <documentation>anyAttribute documentation</documentation>
+ </annotation>
+ </anyAttribute>
+ </complexType>
+
+ <element name="ebaz" type="string">
+ <annotation>
+ <documentation>global element documentation</documentation>
+ </annotation>
+ </element>
+
+ <attribute name="abaz" type="string">
+ <annotation>
+ <documentation>global attribute documentation</documentation>
+ </annotation>
+ </attribute>
+
+</schema>
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
+ {
+ <global element ebar documentation>
+ element ebar
+ <group element efoo documentation>
+ element efoo
+ <global element ebar documentation>
+ element ebar
+ <global attribute abar documentation>
+ optional attribute abar http://www.w3.org/2001/XMLSchema#string
+ <group attribute afoo documentation>
+ optional attribute afoo http://www.w3.org/2001/XMLSchema#string
+ <global attribute abaz documentation>
+ 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
+ }
+ }
+ }
+ <global element ebar documentation>
+ element ebar http://www.w3.org/2001/XMLSchema#string
+ <global attribute abar documentation>
+ attribute abar http://www.w3.org/2001/XMLSchema#string
+ <global attribute abaz documentation>
+ 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 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:t="test" targetNamespace="test">
+
+ <!-- Test various ref constructs. -->
+
+ <complexType name="type">
+ <sequence>
+ <element ref="t:ebar"/>
+ <group ref="t:eg"/>
+ </sequence>
+ <attribute ref="t:abar"/>
+ <attributeGroup ref="t:ag"/>
+ </complexType>
+
+ <group name="eg">
+ <choice>
+ <element name="efoo" type="string">
+ <annotation>
+ <documentation>group element efoo documentation</documentation>
+ </annotation>
+ </element>
+ <element ref="t:ebar"/>
+ </choice>
+ </group>
+
+ <element name="ebar" type="string">
+ <annotation>
+ <documentation>global element ebar documentation</documentation>
+ </annotation>
+ </element>
+
+ <attributeGroup name="ag">
+ <attribute name="afoo" type="string">
+ <annotation>
+ <documentation>group attribute afoo documentation</documentation>
+ </annotation>
+ </attribute>
+ <attribute ref="t:abaz"/>
+ </attributeGroup>
+
+ <attribute name="abar" type="string">
+ <annotation>
+ <documentation>global attribute abar documentation</documentation>
+ </annotation>
+ </attribute>
+
+ <attribute name="abaz" type="string">
+ <annotation>
+ <documentation>global attribute abaz documentation</documentation>
+ </annotation>
+ </attribute>
+
+</schema>
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 <boris@codesynthesis.com>
+# 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 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:t="test" targetNamespace="test">
+
+ <simpleType name="named">
+ <list itemType="string"/>
+ </simpleType>
+
+ <simpleType name="anon_item">
+ <restriction base="string">
+ <enumeration value="male"/>
+ <enumeration value="female"/>
+ </restriction>
+ </simpleType>
+
+ <simpleType name="anon">
+ <list>
+ <simpleType>
+ <restriction base="string">
+ <enumeration value="male"/>
+ <enumeration value="female"/>
+ </restriction>
+ </simpleType>
+ </list>
+ </simpleType>
+
+ <simpleType name="anon_nested">
+ <list>
+ <simpleType>
+ <restriction>
+ <simpleType>
+ <restriction base="string">
+ <maxLength value="20"/>
+ </restriction>
+ </simpleType>
+ <enumeration value="male"/>
+ <enumeration value="female"/>
+ </restriction>
+ </simpleType>
+ </list>
+ </simpleType>
+
+</schema>
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 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:t="test" targetNamespace="test">
+
+ <simpleType name="named">
+ <restriction base="string">
+ <enumeration value="male"/>
+ <enumeration value="female"/>
+ </restriction>
+ </simpleType>
+
+ <simpleType name="anon_base">
+ <restriction base="string">
+ <enumeration value="male"/>
+ <enumeration value="female"/>
+ </restriction>
+ </simpleType>
+
+ <simpleType name="anon">
+ <restriction>
+ <simpleType>
+ <restriction base="string">
+ <maxLength value="20"/>
+ </restriction>
+ </simpleType>
+ <enumeration value="male"/>
+ <enumeration value="female"/>
+ </restriction>
+ </simpleType>
+
+ <simpleType name="anon_nested">
+ <restriction>
+ <simpleType>
+ <restriction>
+ <simpleType>
+ <restriction base="string">
+ <maxLength value="40"/>
+ </restriction>
+ </simpleType>
+ <maxLength value="20"/>
+ </restriction>
+ </simpleType>
+ <enumeration value="male"/>
+ <enumeration value="female"/>
+ </restriction>
+ </simpleType>
+
+</schema>
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 <boris@codesynthesis.com>
+# 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 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:t="test" targetNamespace="test">
+
+ <!-- Multiple levels of forward reference. -->
+
+ <complexType name="type">
+ <attributeGroup ref="t:g1"/>
+ </complexType>
+
+ <attributeGroup name="g1">
+ <attributeGroup ref="t:g2"/>
+ <attributeGroup ref="t:g3"/>
+ </attributeGroup>
+
+ <attributeGroup name="g2">
+ <attribute ref="t:foo2"/>
+ <attribute ref="t:bar2" use="required"/>
+ </attributeGroup>
+
+ <attributeGroup name="g3">
+ <attribute ref="t:foo3"/>
+ <attribute ref="t:bar3" use="required"/>
+ </attributeGroup>
+
+ <attribute name="foo2" type="string"/>
+ <attribute name="bar2" type="string"/>
+
+ <attribute name="foo3" type="string"/>
+ <attribute name="bar3" type="string"/>
+
+</schema>
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 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:t="test" targetNamespace="test">
+
+ <!-- AnyAttribute in attribute groups. -->
+
+ <complexType name="type">
+ <attributeGroup ref="t:g1"/>
+ <attributeGroup ref="t:g2"/>
+ </complexType>
+
+ <attributeGroup name="g1">
+ <anyAttribute namespace="http://www.foo.com"/>
+ </attributeGroup>
+
+ <attributeGroup name="g2">
+ <attribute name="foo" type="string"/>
+ <anyAttribute namespace="http://www.bar.com"/>
+ </attributeGroup>
+
+</schema>
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 <boris@codesynthesis.com>
+# 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 @@
+<?xml version="1.0"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:t="test" xmlns:x="foo" targetNamespace="test">
+
+ <xs:complexType name="type">
+ <xs:sequence>
+ <xs:element name="e1" type="xs:int" default="123"/>
+ <xs:element name="e2" type="xs:int" fixed="456"/>
+
+ <xs:element name="e3" type="xs:QName" default="unqual"/>
+ <xs:element name="e4" type="xs:QName" fixed="t:foo"/>
+ <xs:element name="e5" type="xs:QName" default="x:bar"/>
+ </xs:sequence>
+ <xs:attribute name="a1" type="xs:int" default="123"/>
+ <xs:attribute name="a2" type="xs:int" fixed="456"/>
+
+ <xs:attribute name="a3" type="t:qname" default="x:bar"/>
+ </xs:complexType>
+
+ <xs:simpleType name="qname">
+ <xs:restriction base="xs:QName"/>
+ </xs:simpleType>
+
+</xs:schema>
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 @@
+<?xml version="1.0"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:t="test" xmlns="foo" targetNamespace="test">
+
+ <xs:complexType name="type">
+ <xs:sequence>
+ <xs:element name="e" type="xs:QName" default="unqual"/>
+ </xs:sequence>
+ <xs:attribute name="a" type="xs:QName" default="unqual"/>
+ </xs:complexType>
+
+</xs:schema>
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 <boris@codesynthesis.com>
+# 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 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:t="test" targetNamespace="test">
+
+ <!-- Multiple levels of forward reference. -->
+
+ <complexType name="type">
+ <sequence>
+ <group ref="t:g1" minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ </complexType>
+
+ <group name="g1">
+ <choice>
+ <group ref="t:g2" minOccurs="0"/>
+ <group ref="t:g3" maxOccurs="unbounded"/>
+ </choice>
+ </group>
+
+ <group name="g2">
+ <choice>
+ <element ref="t:foo2"/>
+ <element ref="t:bar2" minOccurs="0"/>
+ </choice>
+ </group>
+
+ <group name="g3">
+ <choice>
+ <element ref="t:foo3" maxOccurs="unbounded"/>
+ <element ref="t:bar3" minOccurs="0" maxOccurs="unbounded"/>
+ </choice>
+ </group>
+
+ <element name="foo2" type="string"/>
+ <element name="bar2" type="string"/>
+
+ <element name="foo3" type="string"/>
+ <element name="bar3" type="string"/>
+
+</schema>
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 <anonymous>
+ {
+ element foo
+ element bar
+ [1, 1] sequence
+ {
+ [1, 1] choice
+ {
+ [1, 1] element foo
+ {
+ complex <recursive-anonymous>
+ }
+ [1, 1] element bar
+ {
+ complex <anonymous>
+ {
+ element foo
+ element bar
+ [1, 1] sequence
+ {
+ [1, 1] choice
+ {
+ [1, 1] element foo
+ {
+ complex <recursive-anonymous>
+ }
+ [1, 1] element bar
+ {
+ complex <recursive-anonymous>
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ [1, 1] element bar
+ {
+ complex <anonymous>
+ {
+ element foo
+ element bar
+ [1, 1] sequence
+ {
+ [1, 1] choice
+ {
+ [1, 1] element foo
+ {
+ complex <anonymous>
+ {
+ element foo
+ element bar
+ [1, 1] sequence
+ {
+ [1, 1] choice
+ {
+ [1, 1] element foo
+ {
+ complex <recursive-anonymous>
+ }
+ [1, 1] element bar
+ {
+ complex <recursive-anonymous>
+ }
+ }
+ }
+ }
+ }
+ [1, 1] element bar
+ {
+ complex <recursive-anonymous>
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ element bar
+ {
+ complex <anonymous>
+ {
+ element foo
+ element bar
+ [1, 1] sequence
+ {
+ [1, 1] choice
+ {
+ [1, 1] element foo
+ {
+ complex <anonymous>
+ {
+ element foo
+ element bar
+ [1, 1] sequence
+ {
+ [1, 1] choice
+ {
+ [1, 1] element foo
+ {
+ complex <recursive-anonymous>
+ }
+ [1, 1] element bar
+ {
+ complex <recursive-anonymous>
+ }
+ }
+ }
+ }
+ }
+ [1, 1] element bar
+ {
+ complex <recursive-anonymous>
+ }
+ }
+ }
+ }
+ }
+ }
+}
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 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:t="test" targetNamespace="test">
+
+ <!-- Recursive reference: g1->element->type->g1 -->
+
+ <complexType name="type">
+ <sequence>
+ <group ref="t:g1"/>
+ </sequence>
+ </complexType>
+
+ <group name="g1">
+ <choice>
+ <element name="foo">
+ <complexType>
+ <sequence>
+ <group ref="t:g1"/>
+ </sequence>
+ </complexType>
+ </element>
+ <element ref="t:bar"/>
+ </choice>
+ </group>
+
+ <element name="bar">
+ <complexType>
+ <sequence>
+ <group ref="t:g1"/>
+ </sequence>
+ </complexType>
+ </element>
+
+</schema>
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 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:t="test" targetNamespace="test">
+
+ <!-- Any in groups. -->
+
+ <complexType name="type">
+ <sequence>
+ <group ref="t:g1" minOccurs="0" maxOccurs="unbounded"/>
+ <group ref="t:g2" minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ </complexType>
+
+ <group name="g1">
+ <sequence>
+ <any namespace="http://www.foo.com"/>
+ </sequence>
+ </group>
+
+ <group name="g2">
+ <sequence>
+ <element name="foo" type="int"/>
+ <any namespace="http://www.bar.com"/>
+ </sequence>
+ </group>
+
+</schema>
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 <boris@codesynthesis.com>
+# 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
+ {
+ <romance documentation>
+ 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
+ {
+ <romance documentation>
+ enumerator romance
+ enumerator fiction
+ enumerator horror
+ enumerator history
+ enumerator philosophy
+ }
+ <union1 documentation>
+ enumeration union1: test#common-base
+ {
+ <romance documentation>
+ 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 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:t="test" targetNamespace="test">
+
+ <!-- Enumeration synthesis -->
+
+ <simpleType name="common-base">
+ <restriction base="string"/>
+ </simpleType>
+
+ <simpleType name="base">
+ <restriction base="t:common-base"/>
+ </simpleType>
+
+ <simpleType name="one">
+ <restriction base="t:base">
+ <enumeration value="romance">
+ <annotation>
+ <documentation>romance documentation</documentation>
+ </annotation>
+ </enumeration>
+ <enumeration value="fiction"/>
+ <enumeration value="horror"/>
+ </restriction>
+ </simpleType>
+
+ <simpleType name="two">
+ <restriction base="t:common-base">
+ <enumeration value="horror"/>
+ <enumeration value="history"/>
+ <enumeration value="philosophy"/>
+ </restriction>
+ </simpleType>
+
+ <simpleType name="three">
+ <restriction base="anyURI">
+ <enumeration value="foo"/>
+ <enumeration value="bar"/>
+ </restriction>
+ </simpleType>
+
+ <simpleType name="union0">
+ <union memberTypes="t:one t:two t:union1"/>
+ </simpleType>
+
+ <simpleType name="union1">
+ <annotation>
+ <documentation>union1 documentation</documentation>
+ </annotation>
+ <union memberTypes="t:one t:two"/>
+ </simpleType>
+
+ <simpleType name="union2">
+ <union memberTypes="t:one t:union1 t:common-base"/>
+ </simpleType>
+
+ <simpleType name="union3">
+ <union memberTypes="t:one t:three"/>
+ </simpleType>
+
+ <complexType name="complex1">
+ <sequence>
+ <element name="a" type="t:union1"/>
+ </sequence>
+ </complexType>
+
+ <complexType name="complex2">
+ <simpleContent>
+ <extension base="t:union1"/>
+ </simpleContent>
+ </complexType>
+
+</schema>
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 <boris@codesynthesis.com>
+# 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 <boris@codesynthesis.com>
+# 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 <anonymous>: http://www.w3.org/2001/XMLSchema#token
+ {
+ enumerator one
+ }
+ }
+
+ {
+ enumeration <anonymous>: http://www.w3.org/2001/XMLSchema#string
+ {
+ enumerator two
+ }
+ }
+
+ union u3 http://www.w3.org/2001/XMLSchema#int test#u1
+ {
+ enumeration <anonymous>: http://www.w3.org/2001/XMLSchema#token
+ {
+ enumerator one
+ }
+ }
+
+ {
+ enumeration <anonymous>: 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 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:t="test" targetNamespace="test">
+
+ <simpleType name="u1">
+ <union memberTypes="int string"/>
+ </simpleType>
+
+ <simpleType name="u2">
+ <union>
+ <simpleType>
+ <restriction base="token">
+ <enumeration value="one"/>
+ </restriction>
+ </simpleType>
+ <simpleType>
+ <restriction base="string">
+ <enumeration value="two"/>
+ </restriction>
+ </simpleType>
+ </union>
+ </simpleType>
+
+ <simpleType name="u3">
+ <union memberTypes=" int
+
+t:u1 ">
+ <simpleType>
+ <restriction base="token">
+ <enumeration value="one"/>
+ </restriction>
+ </simpleType>
+ <simpleType>
+ <restriction base="string">
+ <enumeration value="two"/>
+ </restriction>
+ </simpleType>
+ </union>
+ </simpleType>
+
+</schema>
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 <anonymous> 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 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:t="test" targetNamespace="test">
+
+ <!-- Test resolution of anonymous argument types. -->
+
+ <simpleType name="list">
+ <list>
+ <simpleType>
+ <union memberTypes="int t:enum"/>
+ </simpleType>
+ </list>
+ </simpleType>
+
+ <simpleType name="enum">
+ <restriction base="string">
+ <enumeration value="male"/>
+ <enumeration value="female"/>
+ </restriction>
+ </simpleType>
+
+</schema>
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 <boris@codesynthesis.com>
+# 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 <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <xsd-frontend/types.hxx>
+#include <xsd-frontend/parser.hxx>
+#include <xsd-frontend/xml.hxx>
+#include <xsd-frontend/schema-dom-parser.hxx>
+
+#include <xsd-frontend/semantic-graph.hxx>
+#include <xsd-frontend/traversal.hxx>
+
+#include <cult/containers/map.hxx>
+#include <cult/containers/stack.hxx>
+#include <cult/containers/vector.hxx>
+#include <cult/rtti/type-id.hxx>
+
+//@@ Do i need this?
+//
+#include <xercesc/dom/DOM.hpp>
+
+#include <xercesc/sax/ErrorHandler.hpp>
+#include <xercesc/sax/SAXParseException.hpp>
+
+#include <xercesc/sax2/SAX2XMLReader.hpp>
+#include <xercesc/sax2/XMLReaderFactory.hpp>
+
+#include <xercesc/util/XMLUniDefs.hpp>
+#include <xercesc/util/XMLString.hpp>
+#include <xercesc/util/PlatformUtils.hpp>
+#include <xercesc/util/BinInputStream.hpp>
+#include <xercesc/util/BinFileInputStream.hpp>
+
+#include <xercesc/validators/common/Grammar.hpp>
+
+#include <xercesc/sax/InputSource.hpp>
+#include <xercesc/framework/LocalFileInputSource.hpp>
+#include <xercesc/framework/Wrapper4InputSource.hpp>
+
+#include <iostream>
+#include <sstream>
+#include <memory> // 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<String, CacheNodes> NodeMap;
+ typedef Cult::Containers::Map<String, NodeMap> NamespaceMap;
+ typedef Cult::Containers::Vector<SemanticGraph::Member*> DefaultValues;
+
+ template <typename X>
+ 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<X*> (j->second.first)) ||
+ (x = dynamic_cast<X*> (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<Namespace&> (nss.first->named ()));
+
+ Scope::NamesIteratorPair types (ns.find (uq_name));
+
+ for (; types.first != types.second; ++types.first)
+ {
+ if (X* x = dynamic_cast<X*> (&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<String, String> 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<UnionMemberType> 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<ElementGroupRef> 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<AttributeGroupRef> AttributeGroupRefs;
+
+
+ //
+ //
+ template <typename N, typename A>
+ struct NodeArgs
+ {
+ NodeArgs (N& node, A arg)
+ : node_ (node), arg_ (arg)
+ {
+ }
+
+ operator N& () const
+ {
+ return node_;
+ }
+
+ template <typename E>
+ Void
+ add_edge_left (E& e)
+ {
+ node_.add_edge_left (e, arg_);
+ }
+
+ template <typename E>
+ 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<String> ("substitution-ns-name"));
+ String uq_name (e.context ().get<String> ("substitution-uq-name"));
+
+ e.context ().remove ("substitution-ns-name");
+ e.context ().remove ("substitution-uq-name");
+
+ try
+ {
+ SemanticGraph::Element& root (
+ resolve<SemanticGraph::Element> (ns_name, uq_name, s_, cache_));
+
+ s_.new_edge<Substitutes> (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 () << "'" <<endl;
+ abort ();
+ }
+ }
+ }
+ }
+
+ Void
+ resolve_member (SemanticGraph::Member& m)
+ {
+ using SemanticGraph::Member;
+ using SemanticGraph::Element;
+ using SemanticGraph::Attribute;
+
+ try
+ {
+ String ns_name;
+ String uq_name;
+
+ if (m.context ().count ("type-ns-name"))
+ {
+ ns_name = m.context ().get<String> ("type-ns-name");
+ uq_name = m.context ().get<String> ("type-uq-name");
+
+ m.context ().remove ("type-ns-name");
+ m.context ().remove ("type-uq-name");
+ m.context ().remove ("edge-type-id");
+
+ s_.new_edge<Belongs> (
+ m, resolve<SemanticGraph::Type> (ns_name, uq_name, s_, cache_));
+ }
+ else if (m.context ().count ("instance-ns-name"))
+ {
+ ns_name = m.context ().get<String> ("instance-ns-name");
+ uq_name = m.context ().get<String> ("instance-uq-name");
+
+ m.context ().remove ("instance-ns-name");
+ m.context ().remove ("instance-uq-name");
+
+
+ Member& ref (resolve<Member> (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> ())
+ {
+ Element& m_e (dynamic_cast<Element&> (m));
+ Element& ref_e (dynamic_cast<Element&> (ref));
+
+ if (ref_e.substitutes_p ())
+ {
+ s_.new_edge<Substitutes> (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<String> ("substitution-ns-name"));
+
+ m_e.context ().set (
+ "substitution-uq-name",
+ ref_e.context ().get<String> ("substitution-uq-name"));
+ }
+ }
+
+ //
+ //
+ s_.new_edge<BelongsToNamespace> (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<Attribute*> (&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<Xerces::DOMElement*> ("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<Annotates> (ref.annotation (), m);
+
+ // Type info.
+ //
+ if (ref.typed_p ())
+ s_.new_edge<Belongs> (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 () << "'" <<endl;
+ abort ();
+ }
+ }
+ }
+
+ Void
+ traverse (SemanticGraph::Fundamental::IdRef& i)
+ {
+ ref_type (i);
+ }
+
+ Void
+ traverse (SemanticGraph::Fundamental::IdRefs& i)
+ {
+ ref_type (i);
+ }
+
+ Void
+ ref_type (SemanticGraph::Specialization& s)
+ {
+ if (s.context ().count ("type-ns-name"))
+ {
+ String ns_name (s.context ().get<String> ("type-ns-name"));
+ String uq_name (s.context ().get<String> ("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<Arguments> (
+ resolve<SemanticGraph::Type> (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<String> ("type-ns-name"));
+ String uq_name (l.context ().get<String> ("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<Arguments> (
+ resolve<SemanticGraph::Type> (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<UnionMemberTypes> ("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<Union, Union::ArgumentedIterator> na (
+ u, u.argumented_begin ());
+
+ s_.new_edge<Arguments> (
+ resolve<SemanticGraph::Type> (
+ 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<String> ("type-ns-name"));
+ String uq_name (c.context ().get<String> ("type-uq-name"));
+ TypeId edge_id (c.context ().get<TypeId> ("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<Extends> (
+ c, resolve<SemanticGraph::Type> (
+ ns_name, uq_name, s_, cache_));
+ }
+ else if (edge_id == typeid (Restricts))
+ {
+ Restricts& r (
+ s_.new_edge<Restricts> (
+ c, resolve<SemanticGraph::Type> (
+ ns_name, uq_name, s_, cache_)));
+
+ if (c.context ().count ("facets"))
+ {
+ Facets const& f (c.context ().get<Facets> ("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<AttributeGroupRefs> ("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<ElementGroupRef> ("element-group-ref"));
+
+ Compositor* comp (clone_element_group_content (c, ref));
+
+ // Create ContainsCompositor edge.
+ //
+ if (comp)
+ s_.new_edge<ContainsCompositor> (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<String> ("type-ns-name"));
+ String uq_name (e.context ().get<String> ("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<Restricts> (
+ e, resolve<SemanticGraph::Type> (
+ ns_name, uq_name, s_, cache_)));
+
+ if (e.context ().count ("facets"))
+ {
+ Facets const& f (e.context ().get<Facets> ("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<Element*> (&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<AttributeGroupRefs> ("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<ElementGroupRefs> ("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<Scope&> (j->contained_compositor ().container ()),
+ *i));
+
+ // Create ContainsParticle edge.
+ //
+ if (comp)
+ {
+ NodeArgs<Compositor, Compositor::ContainsIterator> na (
+ c, i->contains_pos);
+ s_.new_edge<ContainsParticle> (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<Compositor> ())
+ 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<ElementGroup> (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 &copy;
+ }
+ 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<All> ())
+ tmp = &s_.new_node<All> (c.file (), c.line (), c.column ());
+ else if (c.is_a<Choice> ())
+ tmp = &s_.new_node<Choice> (c.file (), c.line (), c.column ());
+ else if (c.is_a<Sequence> ())
+ tmp = &s_.new_node<Sequence> (c.file (), c.line (), c.column ());
+ else
+ assert (false);
+
+ Compositor& copy (*tmp);
+
+ // Copy annotation.
+ //
+ if (c.annotated_p ())
+ s_.new_edge<Annotates> (c.annotation (), copy);
+
+ for (Compositor::ContainsIterator i (c.contains_begin ());
+ i != c.contains_end (); ++i)
+ {
+ Particle& p (i->particle ());
+
+ if (p.is_a<Compositor> ())
+ {
+ Compositor& c (dynamic_cast<Compositor&> (p));
+ Compositor& cc (clone_compositor (c, scope, pos));
+
+ s_.new_edge<ContainsParticle> (copy, cc, i->min (), i->max ());
+ }
+ else if (p.is_a<Element> ())
+ {
+ Element& e (dynamic_cast<Element&> (p));
+ Element& ec (clone_element (e));
+
+ s_.new_edge<ContainsParticle> (copy, ec, i->min (), i->max ());
+
+ NodeArgs<Scope, Scope::NamesIterator> na (scope, pos);
+ s_.new_edge<Names> (na, ec, e.name ());
+ ++pos;
+ }
+ else if (p.is_a<Any> ())
+ {
+ Any& a (dynamic_cast<Any&> (p));
+ Any& ac (
+ s_.new_node<Any> (a.file (), a.line (), a.column (),
+ a.namespace_begin (), a.namespace_end ()));
+
+ ac.prototype (a);
+
+ s_.new_edge<ContainsParticle> (copy, ac, i->min (), i->max ());
+
+ // Transfer annotation.
+ //
+ if (a.annotated_p ())
+ s_.new_edge<Annotates> (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<UnsignedLong> ("any-name-count"));
+
+ std::basic_ostringstream<WideChar> os;
+ os << "any #" << count;
+
+ NodeArgs<Scope, Scope::NamesIterator> na (scope, pos);
+ s_.new_edge<Names> (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<Element> (
+ e.file (), e.line (), e.column (), e.global_p (), e.qualified_p ()));
+
+ if (e.qualified_p ())
+ s_.new_edge<BelongsToNamespace> (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<Xerces::DOMElement*> ("dom-node"));
+ default_values_.push_back (&copy);
+ }
+
+ // Transfer annotation.
+ //
+ if (e.annotated_p ())
+ s_.new_edge<Annotates> (e.annotation (), copy);
+
+ // Belongs edge.
+ //
+ if (e.typed_p ())
+ s_.new_edge<Belongs> (copy, e.type ());
+ else
+ assert (!valid_);
+
+ // Substitutes edge.
+ //
+ if (e.substitutes_p ())
+ s_.new_edge<Substitutes> (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<AttributeGroup> (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<Attribute*> (&i->named ()))
+ {
+ Attribute& a (
+ s_.new_node<Attribute> (p->file (),
+ p->line (),
+ p->column (),
+ p->optional_p (),
+ p->global_p (),
+ p->qualified_p ()));
+
+ NodeArgs<Scope, Scope::NamesIterator> na (s, pos);
+ s_.new_edge<Names> (na, a, p->name ());
+ ++pos;
+
+ if (p->qualified_p ())
+ s_.new_edge<BelongsToNamespace> (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<Xerces::DOMElement*> ("dom-node"));
+ default_values_.push_back (&a);
+ }
+
+ // Transfer annotation.
+ //
+ if (p->annotated_p ())
+ s_.new_edge<Annotates> (p->annotation (), a);
+
+ // Belongs edge.
+ //
+ if (p->typed_p ())
+ s_.new_edge<Belongs> (a, p->type ());
+ else
+ assert (!valid_);
+ }
+ else if (
+ AnyAttribute* p = dynamic_cast<AnyAttribute*> (&i->named ()))
+ {
+ AnyAttribute& any (
+ s_.new_node<AnyAttribute> (p->file (),
+ p->line (),
+ p->column (),
+ p->namespace_begin (),
+ p->namespace_end ()));
+
+ any.prototype (*p);
+
+ // Transfer annotation.
+ //
+ if (p->annotated_p ())
+ s_.new_edge<Annotates> (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<UnsignedLong> ("any-attribute-name-count"));
+
+ std::basic_ostringstream<WideChar> os;
+ os << "any-attribute #" << count;
+
+ NodeArgs<Scope, Scope::NamesIterator> na (s, pos);
+ s_.new_edge<Names> (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<Schema>
+ parse (Path const&);
+
+ Evptr<Schema>
+ parse (Paths const&);
+
+ Evptr<Schema>
+ xml_schema (Path const&);
+
+ private:
+ Void
+ fill_xml_schema (Schema&, Path const&);
+
+ private:
+ XML::AutoPtr<Xerces::DOMDocument>
+ 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<Xerces::DOMElement*> (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<WideChar> 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<WideChar> 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<Namespace&> (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<Complex*> (&t);
+
+ if (c != 0 && c->inherits_p ())
+ {
+ Type* b (&c->inherits ().base ());
+
+ while (true)
+ {
+ Complex* cb (dynamic_cast<Complex*> (b));
+
+ if (cb != 0 && cb->inherits_p ())
+ {
+ b = &cb->inherits ().base ();
+ continue;
+ }
+
+ break;
+ }
+
+ return *b;
+ }
+ else
+ return t;
+ }
+
+ private:
+ template <typename Edge, typename Node>
+ Edge*
+ set_type (String const& type, XML::Element const& e, Node& node);
+
+ private:
+ XML::PtrVector<Xerces::DOMDocument>* dom_docs_;
+
+ struct Iterator
+ {
+ Iterator (Xerces::DOMElement* e)
+ : l_ (e->getChildNodes ()), i_ (0)
+ {
+ }
+
+ Xerces::DOMNodeList* l_;
+ Size i_;
+ };
+
+ Cult::Containers::Stack<Iterator> 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<SemanticGraph::Scope*> scope_stack_;
+
+ //
+ //
+ Cult::Containers::Stack<SemanticGraph::Compositor*> 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<SchemaId, SemanticGraph::Schema*>
+ SchemaMap;
+
+ SchemaMap schema_map_;
+
+ // Path stack for diagnostic.
+ //
+ Cult::Containers::Stack<SemanticGraph::Path> 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<typename T> T&
+ add_type (Schema& s, Namespace& ns, String name)
+ {
+ Path path ("XMLSchema.xsd");
+ T& node (s.new_node<T> (path, 0, 0));
+ s.new_edge<Names> (ns, node, name);
+
+ return node;
+ }
+
+ Void Parser::Impl::
+ fill_xml_schema (Schema& s, Path const& path)
+ {
+ Namespace& ns (s.new_node<Namespace> (path, 1, 1));
+ s.new_edge<Names> (s, ns, xsd);
+
+ // anyType and & anySimpleType
+ //
+ AnyType& any_type (
+ add_type<AnyType> (s, ns, L"anyType"));
+ add_type<AnySimpleType> (s, ns, L"anySimpleType");
+
+ // Integers.
+ //
+ add_type<Fundamental::Byte> (s, ns, L"byte");
+ add_type<Fundamental::UnsignedByte> (s, ns, L"unsignedByte");
+ add_type<Fundamental::Short> (s, ns, L"short");
+ add_type<Fundamental::UnsignedShort> (s, ns, L"unsignedShort");
+ add_type<Fundamental::Int> (s, ns, L"int");
+ add_type<Fundamental::UnsignedInt> (s, ns, L"unsignedInt");
+ add_type<Fundamental::Long> (s, ns, L"long");
+ add_type<Fundamental::UnsignedLong> (s, ns, L"unsignedLong");
+ add_type<Fundamental::Integer> (s, ns, L"integer");
+ add_type<Fundamental::NonPositiveInteger> (s, ns, L"nonPositiveInteger");
+ add_type<Fundamental::NonNegativeInteger> (s, ns, L"nonNegativeInteger");
+ add_type<Fundamental::PositiveInteger> (s, ns, L"positiveInteger");
+ add_type<Fundamental::NegativeInteger> (s, ns, L"negativeInteger");
+
+ // Boolean.
+ //
+ add_type<Fundamental::Boolean> (s, ns, L"boolean");
+
+ // Floats.
+ //
+ add_type<Fundamental::Float> (s, ns, L"float");
+ add_type<Fundamental::Double> (s, ns, L"double");
+ add_type<Fundamental::Decimal> (s, ns, L"decimal");
+
+ // Strings
+ //
+ add_type<Fundamental::String> (s, ns, L"string");
+ add_type<Fundamental::NormalizedString> (s, ns, L"normalizedString");
+ add_type<Fundamental::Token> (s, ns, L"token");
+ add_type<Fundamental::Name> (s, ns, L"Name");
+ add_type<Fundamental::NameToken> (s, ns, L"NMTOKEN");
+ add_type<Fundamental::NameTokens> (s, ns, L"NMTOKENS");
+ add_type<Fundamental::NCName> (s, ns, L"NCName");
+ add_type<Fundamental::Language> (s, ns, L"language");
+
+ // ID/IDREF.
+ //
+ add_type<Fundamental::Id> (s, ns, L"ID");
+
+ Fundamental::IdRef& id_ref (
+ s.new_node<Fundamental::IdRef> (path, 0, 0));
+ s.new_edge<Names> (ns, id_ref, L"IDREF");
+ s.new_edge<Arguments> (any_type, id_ref);
+
+ Fundamental::IdRefs& id_refs (
+ s.new_node<Fundamental::IdRefs> (path, 0, 0));
+ s.new_edge<Names> (ns, id_refs, L"IDREFS");
+ s.new_edge<Arguments> (any_type, id_refs);
+
+ // URI.
+ //
+ add_type<Fundamental::AnyURI> (s, ns, L"anyURI");
+
+ // Qualified name.
+ //
+ add_type<Fundamental::QName> (s, ns, L"QName");
+
+ // Binary.
+ //
+ add_type<Fundamental::Base64Binary> (s, ns, L"base64Binary");
+ add_type<Fundamental::HexBinary> (s, ns, L"hexBinary");
+
+ // Date/time.
+ //
+ add_type<Fundamental::Date> (s, ns, L"date");
+ add_type<Fundamental::DateTime> (s, ns, L"dateTime");
+ add_type<Fundamental::Duration> (s, ns, L"duration");
+ add_type<Fundamental::Day> (s, ns, L"gDay");
+ add_type<Fundamental::Month> (s, ns, L"gMonth");
+ add_type<Fundamental::MonthDay> (s, ns, L"gMonthDay");
+ add_type<Fundamental::Year> (s, ns, L"gYear");
+ add_type<Fundamental::YearMonth> (s, ns, L"gYearMonth");
+ add_type<Fundamental::Time> (s, ns, L"time");
+
+ // Entity.
+ //
+ add_type<Fundamental::Entity> (s, ns, L"ENTITY");
+ add_type<Fundamental::Entities> (s, ns, L"ENTITIES");
+
+ // Notation.
+ //
+ add_type<Fundamental::Notation> (s, ns, L"NOTATION");
+ }
+
+
+ Evptr<Schema> Parser::Impl::
+ xml_schema (Path const& tu)
+ {
+ valid_ = true;
+
+ Evptr<Schema> rs (new Schema (tu, 1, 1));
+ fill_xml_schema (*rs, tu);
+
+ if (!valid_)
+ throw InvalidSchema ();
+
+ return rs;
+ }
+ Evptr<Schema> Parser::Impl::
+ parse (Path const& tu)
+ {
+ valid_ = true;
+ schema_map_.clear ();
+ default_values_.clear ();
+
+ XML::PtrVector<Xerces::DOMDocument> dom_docs;
+ dom_docs_ = &dom_docs;
+
+ NamespaceMap cache;
+ cache_ = &cache;
+
+ XML::AutoPtr<Xerces::DOMDocument> 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<Schema> rs (new Schema (tu, root.line (), root.column ()));
+
+ // Implied schema with fundamental types.
+ //
+ xml_schema_ = &rs->new_node<Schema> (xml_schema_path_, 1, 1);
+ rs->new_edge<Implies> (*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<Namespace> (
+ file (), root.line (), root.column ()));
+ s_->new_edge<Names> (*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<SemanticGraph::Fundamental::QName> ())
+ {
+ String v (m.value ());
+ Xerces::DOMElement* e (c.get<Xerces::DOMElement*> ("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<Schema> Parser::Impl::
+ parse (Paths const& paths)
+ {
+ valid_ = true;
+ schema_map_.clear ();
+ default_values_.clear ();
+
+ XML::PtrVector<Xerces::DOMDocument> dom_docs;
+ dom_docs_ = &dom_docs;
+
+ NamespaceMap cache;
+ cache_ = &cache;
+
+ Evptr<Schema> rs (new Schema ("", 0, 0));
+
+ // Implied schema with fundamental types.
+ //
+ xml_schema_ = &rs->new_node<Schema> (xml_schema_path_, 1, 1);
+ rs->new_edge<Implies> (*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<Xerces::DOMDocument> 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<Schema> (tu, root.line (), root.column ()));
+ s_->new_edge<Implies> (s, *xml_schema_, xml_schema_path_);
+ s_->new_edge<Imports> (*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<Namespace> (
+ file (), root.line (), root.column ()));
+ s_->new_edge<Names> (*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<SemanticGraph::Fundamental::QName> ())
+ {
+ String v (m.value ());
+ Xerces::DOMElement* e (c.get<Xerces::DOMElement*> ("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<Annotates> (*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 <import>.
+ //
+ 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<Imports> (*cur_, *schema_map_[schema_id], path);
+ return;
+ }
+
+ if (trace_)
+ wcout << "importing " << rel_path << endl;
+
+ if (XML::AutoPtr<Xerces::DOMDocument> 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<Schema> (rel_path, r.line (), r.column ()));
+ s_->new_edge<Implies> (s, *xml_schema_, xml_schema_path_);
+ s_->new_edge<Imports> (*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<Namespace> (file (), r.line (), r.column ()));
+ s_->new_edge<Names> (*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<Sources> ())
+ s_->new_edge<Sources> (*cur_, s, path);
+ else
+ s_->new_edge<Includes> (*cur_, s, path);
+
+ return;
+ }
+
+ if (trace_)
+ wcout << "including " << rel_path << endl;
+
+ if (XML::AutoPtr<Xerces::DOMDocument> d = dom (abs_path, false))
+ {
+ XML::Element r (d->getDocumentElement ());
+ String ns (r["targetNamespace"]), cur_ns;
+
+ Schema& s (s_->new_node<Schema> (rel_path, r.line (), r.column ()));
+ s_->new_edge<Implies> (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<Sources> (*cur_, s, path);
+ chameleon = true;
+
+ if (trace_)
+ wcout << "handling chameleon schema" << endl;
+ }
+ else
+ s_->new_edge<Includes> (*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<Namespace> (file (), r.line (), r.column ()));
+ s_->new_edge<Names> (*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<ElementGroup> (file (), g.line (), g.column ()));
+
+ s_->new_edge<Names> (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<ContainsCompositor> (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<ElementGroupRefs> (
+ "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<Annotates> (*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<List> (file (), t.line (), t.column ()));
+
+ if (String item_type = l["itemType"])
+ {
+ if (trace_)
+ wcout << "item type: " << fq_name (l, item_type) << endl;
+
+ set_type<Arguments> (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<Arguments> (*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<Names> (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<Union> (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<UnionMemberTypes> ("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<Arguments> (*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<Names> (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<Enumeration> (file (), t.line (), t.column ()));
+
+ if (base_type)
+ restricts = &s_->new_edge<Restricts> (node, *base_type);
+ else
+ restricts = set_type<Restricts> (base, r, node);
+
+ if (String name = t["name"])
+ s_->new_edge<Names> (scope (), static_cast<Nameable&> (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<Complex> (file (), t.line (), t.column ()));
+
+ if (base_type)
+ restricts = &s_->new_edge<Restricts> (node, *base_type);
+ else
+ restricts = set_type<Restricts> (base, r, node);
+
+ if (String name = t["name"])
+ s_->new_edge<Names> (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<Enumerator> (file (), e.line (), e.column ()));
+
+ s_->new_edge<Names> (scope (), node, value);
+ s_->new_edge<Belongs> (node, dynamic_cast<Type&>(scope ()));
+
+ if (a != 0)
+ s_->new_edge<Annotates> (*a, node);
+
+ }
+
+ Type* Parser::Impl::
+ complex_type (XML::Element const& t)
+ {
+ Type* r (0);
+
+ Complex& node (s_->new_node<Complex> (file (), t.line (), t.column ()));
+
+ node.mixed_p (t["mixed"] == L"true" || t["mixed"] == L"1");
+
+ if (String name = t["name"])
+ s_->new_edge<Names> (scope (), node, name);
+
+ r = &node;
+
+ push_scope (node);
+ push (t);
+
+ if (Annotation* a = annotation (true))
+ s_->new_edge<Annotates> (*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<ContainsCompositor> (
+ 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<All> (file (), a.line (), a.column ()));
+
+ push_compositor (node);
+ push (a);
+
+ if (Annotation* a = annotation (true))
+ s_->new_edge<Annotates> (*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<Choice> (file (), c.line (), c.column ()));
+
+ if (in_compositor)
+ {
+ s_->new_edge<ContainsParticle> (
+ compositor (), node,
+ parse_min (c["minOccurs"]), parse_max (c["maxOccurs"]));
+ }
+
+ push_compositor (node);
+ push (c);
+
+ if (Annotation* a = annotation (true))
+ s_->new_edge<Annotates> (*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<Sequence> (file (), s.line (), s.column ()));
+
+ if (in_compositor)
+ {
+ s_->new_edge<ContainsParticle> (
+ compositor (), node,
+ parse_min (s["minOccurs"]), parse_max (s["maxOccurs"]));
+ }
+
+ push_compositor (node);
+ push (s);
+
+ if (Annotation* a = annotation (true))
+ s_->new_edge<Annotates> (*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<Extends> (e["base"], e, dynamic_cast<Complex&> (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<Complex&> (scope ()));
+ Restricts* restricts = set_type<Restricts> (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<Extends> (e["base"], e, dynamic_cast<Complex&> (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<ContainsCompositor> (
+ 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<Restricts> (e["base"], e, dynamic_cast<Complex&> (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<ContainsCompositor> (
+ 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<Element> (
+ file (), e.line (), e.column (), global, qualified));
+
+ s_->new_edge<Names> (scope (), node, name);
+
+ if (qualified)
+ s_->new_edge<BelongsToNamespace> (node, cur_ns ());
+
+ if (!global)
+ {
+ s_->new_edge<ContainsParticle> (
+ 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<Belongs> (type, e, node);
+
+ // Parse annotation.
+ //
+ push (e);
+
+ if (Annotation* a = annotation (true))
+ s_->new_edge<Annotates> (*a, node);
+
+ pop ();
+ }
+ else
+ {
+ // Looks like an anonymous type.
+ //
+ push (e);
+
+ if (Annotation* a = annotation (true))
+ s_->new_edge<Annotates> (*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<Belongs> (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<Belongs> (type, e, node);
+ }
+
+ pop ();
+ }
+ }
+ else if (String ref = e["ref"])
+ {
+ Element& node (
+ s_->new_node<Element> (
+ file (), e.line (), e.column (), true, true));
+
+ // Ref can only be in compositor.
+ //
+ s_->new_edge<ContainsParticle> (
+ 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<Annotates> (*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<Names> (scope (), node, uq_name);
+
+ Element& prot (resolve<Element> (ns_name, uq_name, *s_, *cache_));
+ s_->new_edge<BelongsToNamespace> (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<String> ("substitution-ns-name"));
+
+ node.context ().set (
+ "substitution-uq-name",
+ prot.context ().get<String> ("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<Xerces::DOMElement*> ("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<Annotates> (prot.annotation (), node);
+
+ // Set type information.
+ //
+ if (prot.typed_p ())
+ {
+ s_->new_edge<Belongs> (node, prot.type ());
+ }
+ else if (prot.context ().count ("type-ns-name"))
+ {
+ String ns_name (prot.context ().get<String> ("type-ns-name"));
+ String uq_name (prot.context ().get<String> ("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<DOMText*> (n));
+ text += XML::transcode (t->getData ());
+ break;
+ }
+ case DOMNode::ELEMENT_NODE:
+ {
+ struc = true;
+ break;
+ }
+ default:
+ break; // ignore
+ }
+ }
+
+ if (struc)
+ continue;
+
+ r = &s_->new_node<Annotation> (
+ 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<Attribute> (
+ file (), a.line (), a.column (), optional, global, qualified));
+
+ s_->new_edge<Names> (scope (), node, name);
+
+ if (qualified)
+ s_->new_edge<BelongsToNamespace> (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<Belongs> (type, a, node);
+
+ // Parse annotation.
+ //
+ push (a);
+
+ if (Annotation* ann = annotation (true))
+ s_->new_edge<Annotates> (*ann, node);
+
+ pop ();
+ }
+ else
+ {
+ // Looks like an anonymous type.
+ //
+ push (a);
+
+ if (Annotation* ann = annotation (true))
+ s_->new_edge<Annotates> (*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<Belongs> (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<Belongs> (type, a, node);
+ }
+
+ pop ();
+ }
+ }
+ else if (String ref = a["ref"])
+ {
+ Attribute& node (
+ s_->new_node<Attribute> (
+ 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<Annotates> (*ann, node);
+
+ pop ();
+
+ try
+ {
+ String uq_name (unqualified_name (ref));
+ String ns_name (namespace_name (a, ref));
+
+ s_->new_edge<Names> (scope (), node, uq_name);
+
+ Attribute& prot (resolve<Attribute> (ns_name, uq_name, *s_, *cache_));
+ s_->new_edge<BelongsToNamespace> (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<Xerces::DOMElement*> ("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<Annotates> (prot.annotation (), node);
+
+ // Set type.
+ //
+ if (prot.typed_p ())
+ {
+ s_->new_edge<Belongs> (node, prot.type ());
+ }
+ else if (prot.context ().count ("type-ns-name"))
+ {
+ String ns_name (prot.context ().get<String> ("type-ns-name"));
+ String uq_name (prot.context ().get<String> ("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<AttributeGroup> (file (), g.line (), g.column ()));
+ s_->new_edge<Names> (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<AttributeGroupRefs> (
+ "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<Any> (file (), a.line (), a.column (), namespaces));
+
+ s_->new_edge<ContainsParticle> (
+ compositor (), any,
+ parse_min (a["minOccurs"]), parse_max (a["maxOccurs"]));
+
+ // Parse annotation.
+ //
+ push (a);
+
+ if (Annotation* ann = annotation (true))
+ s_->new_edge<Annotates> (*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<UnsignedLong> ("any-name-count"));
+
+ std::basic_ostringstream<WideChar> os;
+ os << "any #" << count;
+
+ s_->new_edge<Names> (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<AnyAttribute> (
+ file (), a.line (), a.column (), namespaces));
+
+ // Parse annotation.
+ //
+ push (a);
+
+ if (Annotation* ann = annotation (true))
+ s_->new_edge<Annotates> (*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<UnsignedLong> ("any-attribute-name-count"));
+
+ std::basic_ostringstream<WideChar> os;
+ os << "any-attribute #" << count;
+
+ s_->new_edge<Names> (scope (), any, os.str ());
+ }
+
+ // Some specializations to get edge orientations right.
+ //
+
+ template <typename Edge, typename Node>
+ struct Orientation
+ {
+ static Edge&
+ set_edge (Schema& s, Node& node, Type& type)
+ {
+ // By default it is node->edge
+ //
+ return s.template new_edge<Edge> (node, type);
+ }
+ };
+
+ template <typename Node>
+ struct Orientation<Arguments, Node>
+ {
+ static Arguments&
+ set_edge (Schema& s, Node& node, Type& type)
+ {
+ // For Arguments it is type->node.
+ //
+ return s.template new_edge<Arguments> (type, node);
+ }
+ };
+
+ template <typename Edge, typename Node>
+ 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<Type> (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<Fundamental::IdRef> (
+ file (), e.line (), e.column ());
+ else
+ spec = &s_->new_node<Fundamental::IdRefs> (
+ file (), e.line (), e.column ());
+
+ r = &Orientation<Edge, Node>::set_edge (*s_, node, *spec);
+
+ set_type<Arguments> (ref_type, e, *spec);
+ }
+ else
+ r = &Orientation<Edge, Node>::set_edge (*s_, node, t);
+ }
+ else
+ r = &Orientation<Edge, Node>::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<Path, Path, FilePathComparator> 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<Xerces::DOMDocument> 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<DOMImplementationLS*> (
+ DOMImplementationRegistry::getDOMImplementation (gLS)));
+
+ // Create a DOMBuilder.
+ //
+#if _XERCES_VERSION >= 30000
+ XML::AutoPtr<DOMLSParser> 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<DOMBuilder> 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<DOMDocument> (0);
+
+ // Now do our own parsing.
+ //
+ std::auto_ptr<XML::SchemaDOMParser> xsd_parser (
+ new (XMLPlatformUtils::fgMemoryManager) XML::SchemaDOMParser ());
+
+ xsd_parser->parse (input_source);
+
+ XML::AutoPtr<DOMDocument> 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<DOMDocument> (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<SemanticGraph::Schema> Parser::
+ parse (SemanticGraph::Path const& path)
+ {
+ return impl_->parse (path);
+ }
+
+ Evptr<SemanticGraph::Schema> Parser::
+ parse (SemanticGraph::Paths const& paths)
+ {
+ return impl_->parse (paths);
+ }
+
+ Evptr<SemanticGraph::Schema> 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 <boris@codesynthesis.com>
+// 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 <cult/types.hxx>
+#include <cult/containers/set.hxx>
+
+#include <xsd-frontend/semantic-graph/schema.hxx>
+
+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<NarrowString> 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<SemanticGraph::Schema>
+ 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<SemanticGraph::Schema>
+ 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<SemanticGraph::Schema>
+ xml_schema (SemanticGraph::Path const&);
+
+ private:
+ class Impl;
+ Evptr<Impl> 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 <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <xsd-frontend/schema-dom-parser.hxx>
+
+#include <xercesc/dom/DOMDocument.hpp>
+#include <xercesc/dom/DOMElement.hpp>
+#include <xercesc/dom/DOMAttr.hpp>
+#include <xercesc/dom/DOMText.hpp>
+
+#include <xercesc/framework/XMLValidityCodes.hpp>
+#include <xercesc/validators/schema/SchemaSymbols.hpp>
+
+#include <xercesc/util/XMLString.hpp>
+
+#include <xercesc/internal/XMLScanner.hpp>
+#include <xercesc/internal/ElemStack.hpp>
+
+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<XMLAttr>& 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<unsigned long> (info.lineNumber));
+ unsigned long c (static_cast<unsigned long> (info.colNumber));
+#else
+ unsigned long l (info.lineNumber == -1
+ ? 0UL
+ : static_cast<unsigned long> (info.lineNumber));
+
+ unsigned long c (info.colNumber == -1
+ ? 0UL
+ : static_cast<unsigned long> (info.colNumber));
+#endif
+
+ fCurrentNode->setUserData (line_key, reinterpret_cast<void*> (l), 0);
+ fCurrentNode->setUserData (column_key, reinterpret_cast<void*> (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 <boris@codesynthesis.com>
+// 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 <xercesc/parsers/XercesDOMParser.hpp>
+
+#include <xercesc/dom/DOMElement.hpp>
+
+#include <xercesc/validators/schema/XSDLocator.hpp>
+#include <xercesc/validators/schema/XSDErrorReporter.hpp>
+
+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<Xerces::XMLAttr>& 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 <boris@codesynthesis.com>
+// 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 <xsd-frontend/semantic-graph/annotation.hxx>
+#include <xsd-frontend/semantic-graph/any.hxx>
+#include <xsd-frontend/semantic-graph/any-attribute.hxx>
+#include <xsd-frontend/semantic-graph/attribute.hxx>
+#include <xsd-frontend/semantic-graph/attribute-group.hxx>
+#include <xsd-frontend/semantic-graph/complex.hxx>
+#include <xsd-frontend/semantic-graph/compositors.hxx>
+#include <xsd-frontend/semantic-graph/element.hxx>
+#include <xsd-frontend/semantic-graph/element-group.hxx>
+#include <xsd-frontend/semantic-graph/elements.hxx>
+#include <xsd-frontend/semantic-graph/enumeration.hxx>
+#include <xsd-frontend/semantic-graph/fundamental.hxx>
+#include <xsd-frontend/semantic-graph/list.hxx>
+#include <xsd-frontend/semantic-graph/namespace.hxx>
+#include <xsd-frontend/semantic-graph/particle.hxx>
+#include <xsd-frontend/semantic-graph/schema.hxx>
+#include <xsd-frontend/semantic-graph/union.hxx>
+
+#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 <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2010 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <xsd-frontend/semantic-graph/annotation.hxx>
+
+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 <boris@codesynthesis.com>
+// 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 <xsd-frontend/semantic-graph/elements.hxx>
+
+namespace XSDFrontend
+{
+ namespace SemanticGraph
+ {
+ //
+ //
+ class Annotation;
+
+ class Annotates: public virtual Edge
+ {
+ public:
+ Annotation&
+ annotation ()
+ {
+ return *annotation_;
+ }
+
+ protected:
+ friend class Bits::Graph<Node, Edge>;
+
+ 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<Node, Edge>;
+
+ 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 <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <xsd-frontend/semantic-graph/any-attribute.hxx>
+#include <xsd-frontend/semantic-graph/compositors.hxx>
+
+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<Namespace*> (&n));
+
+ return ns ? *ns : namespace_ (s);
+ }
+ else
+ {
+ Type& t (dynamic_cast<Type&> (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 <boris@codesynthesis.com>
+// 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 <cult/containers/vector.hxx>
+
+#include <xsd-frontend/semantic-graph/elements.hxx>
+#include <xsd-frontend/semantic-graph/namespace.hxx>
+
+namespace XSDFrontend
+{
+ namespace SemanticGraph
+ {
+ class AnyAttribute: public virtual Nameable
+ {
+ typedef
+ Cult::Containers::Vector<WideString>
+ 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<Node, Edge>;
+
+ 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 <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <xsd-frontend/semantic-graph/any.hxx>
+#include <xsd-frontend/semantic-graph/compositors.hxx>
+
+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<Namespace*> (&n));
+
+ return ns ? *ns : namespace_ (s);
+ }
+ else
+ {
+ Type& t (dynamic_cast<Type&> (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<Scope&> (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 <boris@codesynthesis.com>
+// 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 <cult/containers/vector.hxx>
+
+#include <xsd-frontend/semantic-graph/elements.hxx>
+#include <xsd-frontend/semantic-graph/particle.hxx>
+#include <xsd-frontend/semantic-graph/namespace.hxx>
+
+namespace XSDFrontend
+{
+ namespace SemanticGraph
+ {
+ class Any: public virtual Nameable,
+ public virtual Particle
+ {
+ typedef
+ Cult::Containers::Vector<WideString>
+ 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<Node, Edge>;
+
+ 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 <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2010 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <xsd-frontend/semantic-graph/attribute-group.hxx>
+
+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 <boris@codesynthesis.com>
+// 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 <xsd-frontend/semantic-graph/elements.hxx>
+
+namespace XSDFrontend
+{
+ namespace SemanticGraph
+ {
+ class AttributeGroup: public virtual Scope
+ {
+ protected:
+ friend class Bits::Graph<Node, Edge>;
+
+ 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 <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <xsd-frontend/semantic-graph/attribute.hxx>
+
+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 <boris@codesynthesis.com>
+// 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 <xsd-frontend/semantic-graph/elements.hxx>
+
+namespace XSDFrontend
+{
+ namespace SemanticGraph
+ {
+ class Attribute: public virtual Member
+ {
+ public:
+ Boolean
+ optional_p () const
+ {
+ return optional_;
+ }
+
+ protected:
+ friend class Bits::Graph<Node, Edge>;
+
+ 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 <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <xsd-frontend/semantic-graph/complex.hxx>
+
+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 <boris@codesynthesis.com>
+// 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 <xsd-frontend/semantic-graph/elements.hxx>
+#include <xsd-frontend/semantic-graph/compositors.hxx>
+
+#include <cult/containers/vector.hxx>
+
+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<Node, Edge>;
+
+ 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 <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2010 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <xsd-frontend/semantic-graph/compositors.hxx>
+
+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 <boris@codesynthesis.com>
+// 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 <cult/containers/list.hxx>
+
+#include <xsd-frontend/semantic-graph/elements.hxx>
+#include <xsd-frontend/semantic-graph/particle.hxx>
+
+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<Node, Edge>;
+
+ 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<ContainsParticle*>
+ ContainsList;
+
+ public:
+ typedef
+ Bits::PointerIterator<ContainsList::Iterator>
+ ContainsIterator;
+
+ typedef
+ Bits::PointerIterator<ContainsList::ConstIterator>
+ 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<Node, Edge>;
+
+ 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<Node, Edge>;
+
+ All (Path const& file, UnsignedLong line, UnsignedLong column);
+ };
+
+
+ //
+ //
+ class Choice: public virtual Compositor
+ {
+ protected:
+ friend class Bits::Graph<Node, Edge>;
+
+ Choice (Path const& file, UnsignedLong line, UnsignedLong column);
+ };
+
+
+ //
+ //
+ class Sequence: public virtual Compositor
+ {
+ protected:
+ friend class Bits::Graph<Node, Edge>;
+
+ 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 <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2010 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <xsd-frontend/semantic-graph/element-group.hxx>
+
+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 <boris@codesynthesis.com>
+// 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 <xsd-frontend/semantic-graph/elements.hxx>
+#include <xsd-frontend/semantic-graph/compositors.hxx>
+
+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<Node, Edge>;
+
+ 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 <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <xsd-frontend/semantic-graph/element.hxx>
+
+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 <boris@codesynthesis.com>
+// 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 <xsd-frontend/semantic-graph/elements.hxx>
+#include <xsd-frontend/semantic-graph/particle.hxx>
+
+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<Node, Edge>;
+
+ 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<Node, Edge>;
+
+ 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 <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <algorithm>
+
+#include <xsd-frontend/semantic-graph/elements.hxx>
+#include <xsd-frontend/semantic-graph/annotation.hxx>
+
+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 <boris@codesynthesis.com>
+// 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 <iosfwd>
+
+#include <boost/filesystem/path.hpp>
+#include <boost/filesystem/operations.hpp>
+#include <boost/filesystem/exception.hpp>
+
+#include <cult/types.hxx>
+
+#include <cult/rtti/type-info.hxx>
+
+#include <cult/containers/set.hxx>
+#include <cult/containers/map.hxx>
+#include <cult/containers/list.hxx>
+#include <cult/containers/pair.hxx>
+#include <cult/containers/graph.hxx>
+#include <cult/containers/vector.hxx>
+
+#include <frontend-elements/context.hxx>
+
+namespace XSDFrontend
+{
+ namespace SemanticGraph
+ {
+ using namespace Cult::Types;
+
+ namespace Bits
+ {
+ using Cult::Containers::Graph;
+
+ //@@ Should end up in Cult::Meta
+ //
+ template <typename X>
+ struct strip_pointer
+ {
+ typedef X Type;
+ };
+
+ template <typename X>
+ struct strip_pointer<X*>
+ {
+ typedef X Type;
+ };
+
+ template <typename I>
+ struct PointerIterator
+ {
+ typedef
+ typename strip_pointer<typename I::Value>::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 <typename I>
+ inline
+ Boolean
+ operator== (PointerIterator<I> const& a, PointerIterator<I> const& b)
+ {
+ return a.base () == b.base ();
+ }
+
+ template <typename I>
+ inline
+ Boolean
+ operator!= (PointerIterator<I> const& a, PointerIterator<I> const& b)
+ {
+ return a.base () != b.base ();
+ }
+
+ template <typename I>
+ inline
+ typename PointerIterator<I>::BaseIterator::difference_type
+ operator- (PointerIterator<I> const& a, PointerIterator<I> const& b)
+ {
+ return a.base () - b.base ();
+ }
+ }
+
+ //
+ //
+ typedef
+ boost::filesystem::filesystem_error
+ InvalidPath;
+
+ typedef
+ boost::filesystem::path
+ Path;
+
+ typedef
+ Cult::Containers::Vector<Path>
+ 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 <typename X>
+ Boolean
+ is_a () const
+ {
+ return dynamic_cast<X const*> (this) != 0;
+ }
+
+ protected:
+ friend class Bits::Graph<Node, Edge>;
+
+ 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 <typename X>
+ Boolean
+ is_a () const
+ {
+ return dynamic_cast<X const*> (this) != 0;
+ }
+
+ public:
+
+ virtual
+ ~Node ()
+ {
+ }
+
+ protected:
+ friend class Bits::Graph<Node, Edge>;
+
+ 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<Node, Edge>;
+
+ 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<Node, Edge>;
+
+ 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<Nameable*>
+ Nameables;
+
+
+ //
+ //
+ class Scope: public virtual Nameable
+ {
+ protected:
+ typedef
+ Cult::Containers::List<Names*>
+ NamesList;
+
+ typedef
+ Cult::Containers::Map<Names*, NamesList::Iterator>
+ ListIteratorMap;
+
+ typedef
+ Cult::Containers::Map<Name, NamesList>
+ NamesMap;
+
+ public:
+ typedef
+ Bits::PointerIterator<NamesList::Iterator>
+ NamesIterator;
+
+ typedef
+ Bits::PointerIterator<NamesList::ConstIterator>
+ NamesConstIterator;
+
+ typedef
+ Cult::Containers::Pair <NamesConstIterator, NamesConstIterator>
+ 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<Node, Edge>;
+
+ 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<Belongs*>
+ Classifies;
+
+ typedef
+ Cult::Containers::Vector<Inherits*>
+ Begets;
+
+ typedef
+ Cult::Containers::Set<Arguments*>
+ ArgumentsSet;
+
+ public:
+ typedef
+ Bits::PointerIterator<Classifies::ConstIterator>
+ 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<Begets::ConstIterator>
+ BegetsIterator;
+
+ BegetsIterator
+ begets_begin () const
+ {
+ return begets_.begin ();
+ }
+
+ BegetsIterator
+ begets_end () const
+ {
+ return begets_.end ();
+ }
+
+ //
+ //
+ typedef
+ Bits::PointerIterator<ArgumentsSet::ConstIterator>
+ ArgumentsIterator;
+
+ ArgumentsIterator
+ arguments_begin () const
+ {
+ return arguments_.begin ();
+ }
+
+ ArgumentsIterator
+ arguments_end () const
+ {
+ return arguments_.end ();
+ }
+
+ protected:
+ friend class Bits::Graph<Node, Edge>;
+
+ 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<Node, Edge>;
+
+ 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<Node, Edge>;
+
+ 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<Node, Edge>;
+
+ 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<Node, Edge>;
+
+ Extends ()
+ {
+ }
+ };
+
+ class Restricts: public virtual Inherits
+ {
+ protected:
+ typedef
+ Cult::Containers::Map<WideString, WideString>
+ 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<Node, Edge>;
+
+ 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<Node, Edge>;
+
+ 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<Node, Edge>;
+
+ 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<Arguments*>
+ Argumented;
+
+ public:
+ typedef
+ Bits::PointerIterator<Argumented::Iterator>
+ ArgumentedIterator;
+
+ typedef
+ Bits::PointerIterator<Argumented::ConstIterator>
+ 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<Node, Edge>;
+
+ 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<Node, Edge>;
+
+ 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<Node, Edge>;
+
+ 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<Node, Edge>;
+
+ 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 <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <xsd-frontend/semantic-graph/enumeration.hxx>
+
+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 <boris@codesynthesis.com>
+// 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 <xsd-frontend/semantic-graph/elements.hxx>
+#include <xsd-frontend/semantic-graph/complex.hxx>
+
+namespace XSDFrontend
+{
+ namespace SemanticGraph
+ {
+ class Enumeration: public virtual Complex
+ {
+ protected:
+ friend class Bits::Graph<Node, Edge>;
+
+ Enumeration (Path const& file, UnsignedLong line, UnsignedLong column);
+ };
+
+
+ class Enumerator: public virtual Instance
+ {
+ protected:
+ friend class Bits::Graph<Node, Edge>;
+
+ 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 <boris@codesynthesis.com>
+# 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 <boris@codesynthesis.com>
+// 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 <xsd-frontend/semantic-graph/fundamental.hxx>
+
+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 <boris@codesynthesis.com>
+# 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<Node, Edge>;
+
+ $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 <boris@codesynthesis.com>
+// 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 <xsd-frontend/semantic-graph/elements.hxx>
+
+namespace XSDFrontend
+{
+ namespace SemanticGraph
+ {
+ namespace Fundamental
+ {
+ //
+ //
+ class Type: public virtual SemanticGraph::Type
+ {
+ protected:
+ friend class Bits::Graph<Node, Edge>;
+
+ 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<Node, Edge>;
+
+ IdRef (Path const& file,
+ SemanticGraph::UnsignedLong line,
+ SemanticGraph::UnsignedLong column);
+ };
+
+
+ //
+ //
+ class IdRefs: public virtual Type,
+ public virtual Specialization
+ {
+ protected:
+ friend class Bits::Graph<Node, Edge>;
+
+ 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 <boris@codesynthesis.com>
+# 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 <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <xsd-frontend/semantic-graph/list.hxx>
+
+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 <boris@codesynthesis.com>
+// 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 <xsd-frontend/semantic-graph/elements.hxx>
+
+namespace XSDFrontend
+{
+ namespace SemanticGraph
+ {
+ class List: public virtual Specialization
+ {
+ protected:
+ friend class Bits::Graph<Node, Edge>;
+
+ 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 <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <xsd-frontend/semantic-graph/namespace.hxx>
+
+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 <boris@codesynthesis.com>
+// 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 <xsd-frontend/semantic-graph/elements.hxx>
+
+namespace XSDFrontend
+{
+ namespace SemanticGraph
+ {
+ class Namespace : public virtual Scope
+ {
+ protected:
+ friend class Bits::Graph<Node, Edge>;
+
+ 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 <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2010 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <xsd-frontend/semantic-graph/particle.hxx>
+
+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 <boris@codesynthesis.com>
+// 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 <xsd-frontend/semantic-graph/elements.hxx>
+
+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<Node, Edge>;
+
+ 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<Node, Edge>;
+
+ 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 <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <xsd-frontend/semantic-graph/schema.hxx>
+
+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 <boris@codesynthesis.com>
+// 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 <cult/containers/set.hxx>
+
+#include <xsd-frontend/semantic-graph/elements.hxx>
+#include <xsd-frontend/semantic-graph/namespace.hxx>
+
+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<Node, Edge>;
+
+ 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<Node, Edge>;
+
+ Implies (Path const& path)
+ : Uses (path)
+ {
+ }
+ };
+
+
+ //
+ //
+ class Sources: public virtual Uses
+ {
+ protected:
+ friend class Bits::Graph<Node, Edge>;
+
+ Sources (Path const& path)
+ : Uses (path)
+ {
+ }
+ };
+
+
+ //
+ //
+ class Includes: public virtual Uses
+ {
+ protected:
+ friend class Bits::Graph<Node, Edge>;
+
+ Includes (Path const& path)
+ : Uses (path)
+ {
+ }
+ };
+
+
+ //
+ //
+ class Imports: public virtual Uses
+ {
+ protected:
+ friend class Bits::Graph<Node, Edge>;
+
+ Imports (Path const& path)
+ : Uses (path)
+ {
+ }
+ };
+
+
+ //
+ //
+ class Schema: public virtual Scope,
+ private Bits::Graph<Node, Edge>,
+ public NonCopyable
+ {
+ typedef
+ Cult::Containers::Vector<Uses*>
+ UsesList;
+
+ typedef
+ Cult::Containers::Vector<Uses*>
+ UsedList;
+
+ public:
+ Schema (Path const& file, UnsignedLong line, UnsignedLong column)
+ : SemanticGraph::Node (file, line, column)
+ {
+ }
+
+ public:
+ typedef
+ Bits::PointerIterator<UsesList::ConstIterator>
+ UsesIterator;
+
+ UsesIterator
+ uses_begin () const
+ {
+ return uses_.begin ();
+ }
+
+ UsesIterator
+ uses_end () const
+ {
+ return uses_.end ();
+ }
+
+ typedef
+ Bits::PointerIterator<UsedList::ConstIterator>
+ 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<SemanticGraph::Node, Edge>::new_edge;
+ using Bits::Graph<SemanticGraph::Node, Edge>::reset_left_node;
+ using Bits::Graph<SemanticGraph::Node, Edge>::reset_right_node;
+ using Bits::Graph<SemanticGraph::Node, Edge>::add_edge_left;
+ using Bits::Graph<SemanticGraph::Node, Edge>::add_edge_right;
+ using Bits::Graph<SemanticGraph::Node, Edge>::delete_node;
+ using Bits::Graph<SemanticGraph::Node, Edge>::delete_edge;
+
+ template <typename T>
+ T&
+ new_node (Path const& file, UnsignedLong line, UnsignedLong column)
+ {
+ return graph ().new_node<T> (file, line, column);
+ }
+
+ template <typename T, typename A0>
+ T&
+ new_node (Path const& file, UnsignedLong line, UnsignedLong column,
+ A0 const& a0)
+ {
+ return graph ().new_node<T> (file, line, column, a0);
+ }
+
+ template <typename T, typename A0, typename A1>
+ T&
+ new_node (Path const& file, UnsignedLong line, UnsignedLong column,
+ A0 const& a0, A1 const& a1)
+ {
+ return graph ().new_node<T> (file, line, column, a0, a1);
+ }
+
+ template <typename T, typename A0, typename A1, typename A2>
+ T&
+ new_node (Path const& file, UnsignedLong line, UnsignedLong column,
+ A0 const& a0, A1 const& a1, A2 const& a2)
+ {
+ return graph ().new_node<T> (file, line, column, a0, a1, a2);
+ }
+
+ template <typename T, typename A0, typename A1, typename A2,
+ typename A3>
+ 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<T> (file, line, column, a0, a1, a2, a3);
+ }
+
+ protected:
+ //@@ gcc bug #21146
+ //
+ friend class Bits::Graph<SemanticGraph::Node, Edge>;
+
+ 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<SemanticGraph::Node, Edge>&
+ graph ()
+ {
+ return *this;
+ }
+
+ private:
+ UsesList uses_;
+ UsedList used_;
+
+ private:
+ typedef Cult::Containers::Set<Schema const*> 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 <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <xsd-frontend/semantic-graph/union.hxx>
+
+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 <boris@codesynthesis.com>
+// 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 <xsd-frontend/semantic-graph/elements.hxx>
+
+namespace XSDFrontend
+{
+ namespace SemanticGraph
+ {
+ class Union: public virtual Specialization
+ {
+ protected:
+ friend class Bits::Graph<Node, Edge>;
+
+ 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 <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2010 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <xsd-frontend/transformations/anonymous.hxx>
+
+#include <xsd-frontend/semantic-graph.hxx>
+#include <xsd-frontend/traversal.hxx>
+
+#include <iostream>
+#include <sstream>
+
+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<Schema&> (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<Namespace&> (nip.first->named ()));
+
+ Scope::NamesIteratorPair types (ns.find (name));
+
+ for (; types.first != types.second; ++types.first)
+ {
+ if (Type* t = dynamic_cast<Type*> (&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<Scope*> (&n)
+ ? dynamic_cast<Scope*> (&n) : &n.scope ());;
+ s = &s->scope ())
+ {
+ if ((schema = dynamic_cast<Schema*> (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<SemanticGraph::Namespace*> (&n) != 0)
+ return L"<namespace-level>"; // There is a bug if you see this.
+
+ assert (n.named_p ());
+
+ SemanticGraph::Scope& scope (n.scope ());
+
+ if (dynamic_cast<SemanticGraph::Namespace*> (&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<SemanticGraph::Fundamental::IdRef> () &&
+ !t.is_a<SemanticGraph::Fundamental::IdRefs> ())
+ {
+ 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<SemanticGraph::Names> (*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<SemanticGraph::Fundamental::IdRef> () &&
+ !t.is_a<SemanticGraph::Fundamental::IdRefs> ())
+ {
+ 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<SemanticGraph::Names> (*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<SemanticGraph::Fundamental::IdRef> () &&
+ !t.is_a<SemanticGraph::Fundamental::IdRefs> ())
+ {
+ 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<SemanticGraph::Names> (*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<SemanticGraph::Fundamental::IdRef> () &&
+ !t.is_a<SemanticGraph::Fundamental::IdRefs> ())
+ {
+ 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<SemanticGraph::Fundamental::IdRef> () &&
+ !t.is_a<SemanticGraph::Fundamental::IdRefs> ())
+ {
+ 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<SemanticGraph::Member> ())
+ {
+ // 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<SemanticGraph::Names> (*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 <boris@codesynthesis.com>
+// 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 <cult/types.hxx>
+
+#include <xsd-frontend/semantic-graph/elements.hxx> // Path
+#include <xsd-frontend/semantic-graph/schema.hxx>
+
+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 <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2010 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <xsd-frontend/transformations/enum-synthesis.hxx>
+
+#include <xsd-frontend/semantic-graph.hxx>
+#include <xsd-frontend/traversal.hxx>
+
+#include <cult/containers/set.hxx>
+
+namespace XSDFrontend
+{
+ using namespace Cult;
+ typedef WideString String;
+
+ namespace
+ {
+ typedef Cult::Containers::Set<String> 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<Type> (e.file (), e.line (), e.column ()));
+
+ schema_.new_edge<SemanticGraph::Names> (enum_, c, name);
+ schema_.new_edge<SemanticGraph::Belongs> (c, enum_);
+
+ if (e.annotated_p ())
+ schema_.new_edge<SemanticGraph::Annotates> (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<SemanticGraph::Union> ())
+ {
+ // 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<Enumeration> ())
+ 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<Enumeration> (
+ u.file (), u.line (), u.column ()));
+
+ schema_.new_edge<SemanticGraph::Restricts> (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 <boris@codesynthesis.com>
+// 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 <cult/types.hxx>
+
+#include <xsd-frontend/semantic-graph/elements.hxx> // Path
+#include <xsd-frontend/semantic-graph/schema.hxx>
+
+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 <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2010 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <xsd-frontend/transformations/restriction.hxx>
+
+#include <xsd-frontend/semantic-graph.hxx>
+#include <xsd-frontend/traversal.hxx>
+
+#include <cult/containers/vector.hxx>
+
+#include <iostream>
+
+using std::wcerr;
+using std::endl;
+
+namespace XSDFrontend
+{
+ using namespace Cult;
+
+ typedef WideString String;
+ typedef Transformations::Restriction::Failed Failed;
+ typedef Containers::Vector<SemanticGraph::Complex*> 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<Restricts> () &&
+ !c.inherits ().base ().is_a<AnyType> ())
+ {
+ // Go down our inheritance hierarchy until the end or the previous
+ // restriction.
+ //
+ Complex* base (&c);
+
+ while ((base = dynamic_cast<Complex*> (&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<Restricts> ())
+ 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<Compositor> ())
+ {
+ 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> ())
+ {
+ Compositor& rc (dynamic_cast<Compositor&> (r));
+ Compositor& bc (dynamic_cast<Compositor&> (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> ())
+ {
+ // Element
+ //
+ r.context ().set ("xsd-frontend-restriction-correspondence",
+ dynamic_cast<Element*> (&b));
+ }
+ else
+ {
+ // Wildcard
+ //
+ r.context ().set ("xsd-frontend-restriction-correspondence",
+ dynamic_cast<Any*> (&b));
+ }
+ }
+
+ Boolean
+ match (SemanticGraph::Particle& r, SemanticGraph::Particle& b)
+ {
+ using namespace SemanticGraph;
+
+ if (typeid (r) != typeid (b))
+ return false;
+
+ if (r.is_a<Compositor> ())
+ {
+ Compositor& rc (dynamic_cast<Compositor&> (r));
+ Compositor& bc (dynamic_cast<Compositor&> (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> ())
+ {
+ Element& re (dynamic_cast<Element&> (r));
+ Element& be (dynamic_cast<Element&> (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<Attribute*> (&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<Attribute*> (&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<Attribute> (prot->file (),
+ prot->line (),
+ prot->column (),
+ prot->optional_p (),
+ prot->global_p (),
+ prot->qualified_p ());
+
+ schema_.new_edge<Names> (c, *a, name);
+
+ // Transfer namespace.
+ //
+ if (prot->qualified_p ())
+ {
+ schema_.new_edge<BelongsToNamespace> (*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<Belongs> (*a, prot->type ());
+
+ // Transfer annotation.
+ //
+ if (prot->annotated_p ())
+ schema_.new_edge<Annotates> (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<AnyAttribute*> (&i->named ()));
+
+ if (a == 0)
+ continue;
+
+ AnyAttribute* p (0);
+
+ while (bi != be)
+ {
+ for (; si != (*bi)->names_end (); ++si)
+ {
+ p = dynamic_cast<AnyAttribute*> (&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 <boris@codesynthesis.com>
+// 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 <cult/types.hxx>
+
+#include <xsd-frontend/semantic-graph/elements.hxx> // Path
+#include <xsd-frontend/semantic-graph/schema.hxx>
+
+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 <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2010 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <xsd-frontend/transformations/schema-per-type.hxx>
+
+#include <xsd-frontend/semantic-graph.hxx>
+#include <xsd-frontend/traversal.hxx>
+
+#include <cult/containers/map.hxx>
+#include <cult/containers/set.hxx>
+#include <cult/containers/vector.hxx>
+
+#include <sstream>
+#include <iostream>
+
+#include <strings.h> // strcasecmp
+
+using std::wcerr;
+using std::endl;
+
+namespace XSDFrontend
+{
+ using namespace Cult;
+
+ typedef WideString String;
+ typedef Transformations::SchemaPerType::Failed Failed;
+
+ typedef Containers::Vector<SemanticGraph::Schema*> Schemas;
+ typedef Containers::Map<SemanticGraph::Type*,
+ SemanticGraph::Schema*> 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<NarrowString, FileComparator> 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<Namespace&> (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<Type> ())
+ {
+ 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<Schema> (path, 1, 1));
+ root.new_edge<Implies> (ts, xsd, xsd_path);
+
+ Namespace& tns (root.new_node<Namespace> (path, 1, 1));
+ root.new_edge<Names> (ts, tns, ns.name ());
+ root.new_edge<Names> (tns, n, name);
+
+ // Add include to the original schema and enter into the
+ // type-schema map.
+ //
+ root.new_edge<Includes> (s, ts, path);
+ tsm[&dynamic_cast<Type&> (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<Boolean> (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<Includes> (schema_, s, path);
+ else
+ u = &root_.new_edge<Imports> (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<SemanticGraph::Type*> 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<SemanticGraph::Path> ("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 <boris@codesynthesis.com>
+// 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 <cult/types.hxx>
+#include <cult/containers/vector.hxx>
+
+#include <xsd-frontend/semantic-graph/elements.hxx> // Path
+#include <xsd-frontend/semantic-graph/schema.hxx>
+
+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<SemanticGraph::Schema*>
+ 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 <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2010 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <xsd-frontend/transformations/simplifier.hxx>
+
+#include <xsd-frontend/semantic-graph.hxx>
+#include <xsd-frontend/traversal.hxx>
+
+#include <cult/containers/vector.hxx>
+
+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<Choice> ())
+ root_.delete_edge (com, c, c.contained_particle ());
+ }
+ else
+ {
+ Complex& con (
+ dynamic_cast<Complex&> (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 <boris@codesynthesis.com>
+// 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 <cult/types.hxx>
+
+#include <xsd-frontend/semantic-graph/elements.hxx> // Path
+#include <xsd-frontend/semantic-graph/schema.hxx>
+
+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 <boris@codesynthesis.com>
+// 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 <xsd-frontend/traversal/any.hxx>
+#include <xsd-frontend/traversal/any-attribute.hxx>
+#include <xsd-frontend/traversal/attribute.hxx>
+#include <xsd-frontend/traversal/attribute-group.hxx>
+#include <xsd-frontend/traversal/complex.hxx>
+#include <xsd-frontend/traversal/compositors.hxx>
+#include <xsd-frontend/traversal/element.hxx>
+#include <xsd-frontend/traversal/element-group.hxx>
+#include <xsd-frontend/traversal/elements.hxx>
+#include <xsd-frontend/traversal/enumeration.hxx>
+#include <xsd-frontend/traversal/fundamental.hxx>
+#include <xsd-frontend/traversal/list.hxx>
+#include <xsd-frontend/traversal/namespace.hxx>
+#include <xsd-frontend/traversal/particle.hxx>
+#include <xsd-frontend/traversal/schema.hxx>
+#include <xsd-frontend/traversal/union.hxx>
+
+#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 <boris@codesynthesis.com>
+// 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 <xsd-frontend/traversal/elements.hxx>
+#include <xsd-frontend/semantic-graph/any-attribute.hxx>
+
+namespace XSDFrontend
+{
+ namespace Traversal
+ {
+ typedef
+ Node<SemanticGraph::AnyAttribute>
+ 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 <boris@codesynthesis.com>
+// 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 <xsd-frontend/traversal/elements.hxx>
+#include <xsd-frontend/semantic-graph/any.hxx>
+
+namespace XSDFrontend
+{
+ namespace Traversal
+ {
+ typedef
+ Node<SemanticGraph::Any>
+ 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 <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2010 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <xsd-frontend/traversal/attribute-group.hxx>
+
+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 <boris@codesynthesis.com>
+// 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 <xsd-frontend/traversal/elements.hxx>
+#include <xsd-frontend/semantic-graph/attribute-group.hxx>
+
+namespace XSDFrontend
+{
+ namespace Traversal
+ {
+ struct AttributeGroup: ScopeTemplate<SemanticGraph::AttributeGroup>
+ {
+ 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 <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <xsd-frontend/traversal/attribute.hxx>
+
+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 <boris@codesynthesis.com>
+// 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 <xsd-frontend/traversal/elements.hxx>
+
+#include <xsd-frontend/semantic-graph/attribute.hxx>
+
+
+namespace XSDFrontend
+{
+ namespace Traversal
+ {
+ struct Attribute : Node<SemanticGraph::Attribute>
+ {
+ 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 <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <xsd-frontend/traversal/complex.hxx>
+
+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 <boris@codesynthesis.com>
+// 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 <xsd-frontend/traversal/elements.hxx>
+#include <xsd-frontend/semantic-graph/complex.hxx>
+
+namespace XSDFrontend
+{
+ namespace Traversal
+ {
+ struct Complex : ScopeTemplate<SemanticGraph::Complex>
+ {
+ 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 <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2010 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <xsd-frontend/traversal/compositors.hxx>
+
+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 <boris@codesynthesis.com>
+// 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 <xsd-frontend/traversal/elements.hxx>
+#include <xsd-frontend/semantic-graph/compositors.hxx>
+
+namespace XSDFrontend
+{
+ namespace Traversal
+ {
+ //
+ //
+ struct ContainsParticle: Edge<SemanticGraph::ContainsParticle>
+ {
+ ContainsParticle ()
+ {
+ }
+
+ ContainsParticle (NodeBase& n)
+ {
+ node_traverser (n);
+ }
+
+ virtual Void
+ traverse (Type&);
+ };
+
+
+ //
+ //
+ struct ContainsCompositor: Edge<SemanticGraph::ContainsCompositor>
+ {
+ ContainsCompositor ()
+ {
+ }
+
+ ContainsCompositor (NodeBase& n)
+ {
+ node_traverser (n);
+ }
+
+ virtual Void
+ traverse (Type&);
+ };
+
+ //
+ //
+ struct Compositor : Node<SemanticGraph::Compositor>
+ {
+ virtual Void
+ traverse (Type&);
+
+ virtual Void
+ pre (Type&);
+
+ virtual Void
+ contains (Type&);
+
+ virtual Void
+ contains (Type&, EdgeDispatcherBase&);
+
+ virtual Void
+ post (Type&);
+ };
+
+
+ //
+ //
+ struct All : Node<SemanticGraph::All>
+ {
+ virtual Void
+ traverse (Type&);
+
+ virtual Void
+ pre (Type&);
+
+ virtual Void
+ contains (Type&);
+
+ virtual Void
+ contains (Type&, EdgeDispatcherBase&);
+
+ virtual Void
+ post (Type&);
+ };
+
+
+ //
+ //
+ struct Choice : Node<SemanticGraph::Choice>
+ {
+ virtual Void
+ traverse (Type&);
+
+ virtual Void
+ pre (Type&);
+
+ virtual Void
+ contains (Type&);
+
+ virtual Void
+ contains (Type&, EdgeDispatcherBase&);
+
+ virtual Void
+ post (Type&);
+ };
+
+
+ //
+ //
+ struct Sequence : Node<SemanticGraph::Sequence>
+ {
+ 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 <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2010 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <xsd-frontend/traversal/element-group.hxx>
+
+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 <boris@codesynthesis.com>
+// 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 <xsd-frontend/traversal/elements.hxx>
+#include <xsd-frontend/semantic-graph/element-group.hxx>
+
+namespace XSDFrontend
+{
+ namespace Traversal
+ {
+ struct ElementGroup: ScopeTemplate<SemanticGraph::ElementGroup>
+ {
+ 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 <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <xsd-frontend/traversal/element.hxx>
+
+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 <boris@codesynthesis.com>
+// 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 <xsd-frontend/traversal/elements.hxx>
+#include <xsd-frontend/semantic-graph/element.hxx>
+
+namespace XSDFrontend
+{
+ namespace Traversal
+ {
+ struct Element : Node<SemanticGraph::Element>
+ {
+ 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 <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <xsd-frontend/traversal/elements.hxx>
+
+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 <boris@codesynthesis.com>
+// 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 <cult/types.hxx>
+
+#include <frontend-elements/traversal.hxx>
+
+#include <xsd-frontend/semantic-graph/elements.hxx>
+
+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<SemanticGraph::Node> NodeDispatcherBase;
+ typedef Bits::DispatcherBase<SemanticGraph::Edge> EdgeDispatcherBase;
+
+
+ //
+ //
+ struct NodeBase : virtual Bits::Dispatcher<SemanticGraph::Node>,
+ virtual Bits::Dispatcher<SemanticGraph::Edge>
+ {
+ Void
+ edge_traverser (EdgeDispatcherBase& d)
+ {
+ Bits::Dispatcher<SemanticGraph::Edge>::traverser (d);
+ }
+
+ EdgeDispatcherBase&
+ edge_traverser ()
+ {
+ return *this;
+ }
+
+ public:
+ using Bits::Dispatcher<SemanticGraph::Node>::dispatch;
+ using Bits::Dispatcher<SemanticGraph::Edge>::dispatch;
+
+ using Bits::Dispatcher<SemanticGraph::Node>::map;
+
+ using Bits::Dispatcher<SemanticGraph::Edge>::iterate_and_dispatch;
+ };
+
+
+ //
+ //
+ template <typename T>
+ struct Node : Bits::TraverserBase<SemanticGraph::Node>, virtual NodeBase
+ {
+ typedef
+ T
+ Type;
+
+ Node ()
+ {
+ map (typeid (Type), *this);
+ }
+
+ virtual Void
+ traverse (Type&) = 0;
+
+ virtual Void
+ trampoline (SemanticGraph::Node& i)
+ {
+ traverse (dynamic_cast<Type&> (i));
+ }
+
+ virtual Void
+ trampoline (SemanticGraph::Node const&)
+ {
+ abort ();
+ }
+ };
+
+
+ //
+ //
+ struct EdgeBase : virtual Bits::Dispatcher<SemanticGraph::Edge>,
+ virtual Bits::Dispatcher<SemanticGraph::Node>
+ {
+ Void
+ node_traverser (NodeDispatcherBase& d)
+ {
+ Bits::Dispatcher<SemanticGraph::Node>::traverser (d);
+ }
+
+ NodeDispatcherBase&
+ node_traverser ()
+ {
+ return *this;
+ }
+
+ public:
+ using Bits::Dispatcher<SemanticGraph::Edge>::dispatch;
+ using Bits::Dispatcher<SemanticGraph::Node>::dispatch;
+
+ using Bits::Dispatcher<SemanticGraph::Edge>::map;
+
+ using Bits::Dispatcher<SemanticGraph::Node>::iterate_and_dispatch;
+ };
+
+ template <typename T>
+ struct Edge : Bits::TraverserBase<SemanticGraph::Edge>, virtual EdgeBase
+ {
+ typedef
+ T
+ Type;
+
+ Edge ()
+ {
+ map (typeid (Type), *this);
+ }
+
+ virtual Void
+ traverse (Type&) = 0;
+
+ virtual Void
+ trampoline (SemanticGraph::Edge& i)
+ {
+ traverse (dynamic_cast<Type&> (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<SemanticGraph::Names>
+ {
+ Names ()
+ {
+ }
+
+ Names (NodeBase& n)
+ {
+ node_traverser (n);
+ }
+
+ virtual Void
+ traverse (Type& e)
+ {
+ dispatch (e.named ());
+ }
+ };
+
+
+ //
+ //
+ struct Belongs : Edge<SemanticGraph::Belongs>
+ {
+ Belongs ()
+ {
+ }
+
+ Belongs (NodeBase& n)
+ {
+ node_traverser (n);
+ }
+
+ virtual Void
+ traverse (Type& e)
+ {
+ dispatch (e.type ());
+ }
+ };
+
+
+ // Nodes
+ //
+
+
+ //
+ //
+ struct Nameable : Node<SemanticGraph::Nameable>
+ {
+ };
+
+
+ //
+ //
+ template <typename T>
+ struct ScopeTemplate : Node<T>
+ {
+ public:
+ virtual Void
+ traverse (T& s)
+ {
+ names (s);
+ }
+
+ template<typename X>
+ Void
+ names (T& s,
+ EdgeDispatcherBase& d,
+ Void (X::*pre_) (T&) = (Void (ScopeTemplate<T>::*)(T&)) (0),
+ Void (X::*post_) (T&) = (Void (ScopeTemplate<T>::*)(T&)) (0),
+ Void (X::*none_) (T&) = (Void (ScopeTemplate<T>::*)(T&)) (0),
+ Void (X::*next_) (T&) = (Void (ScopeTemplate<T>::*)(T&)) (0))
+ {
+ X* this_ (dynamic_cast<X*> (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<ScopeTemplate<T> > (s, d);
+ }
+
+ virtual Void
+ names (T& s)
+ {
+ names (s,
+ *this,
+ &ScopeTemplate<T>::names_pre,
+ &ScopeTemplate<T>::names_post,
+ &ScopeTemplate<T>::names_none,
+ &ScopeTemplate<T>::names_next);
+ }
+
+ virtual Void
+ names_pre (T&)
+ {
+ }
+
+ virtual Void
+ names_next (T&)
+ {
+ }
+
+ virtual Void
+ names_post (T&)
+ {
+ }
+
+ virtual Void
+ names_none (T&)
+ {
+ }
+ };
+
+
+ //
+ //
+ typedef
+ ScopeTemplate<SemanticGraph::Scope>
+ Scope;
+
+
+ //
+ //
+ struct Type : Node<SemanticGraph::Type>
+ {
+ virtual Void
+ traverse (SemanticGraph::Type&) = 0;
+ };
+
+
+ //
+ //
+ struct Instance : Node<SemanticGraph::Instance>
+ {
+ virtual Void
+ traverse (Type&);
+
+ virtual Void
+ pre (Type&);
+
+ virtual Void
+ belongs (Type&, EdgeDispatcherBase&);
+
+ virtual Void
+ belongs (Type&);
+
+ virtual Void
+ post (Type&);
+ };
+
+
+ //
+ //
+ struct Member : Node<SemanticGraph::Member>
+ {
+ virtual Void
+ traverse (Type&);
+
+ virtual Void
+ pre (Type&);
+
+ virtual Void
+ belongs (Type&, EdgeDispatcherBase&);
+
+ virtual Void
+ belongs (Type&);
+
+ virtual Void
+ post (Type&);
+ };
+
+
+ //
+ //
+ struct Inherits : Edge<SemanticGraph::Inherits>
+ {
+ Inherits ()
+ {
+ }
+
+ Inherits (NodeBase& n)
+ {
+ node_traverser (n);
+ }
+
+ virtual Void
+ traverse (Type& e)
+ {
+ dispatch (e.base ());
+ }
+ };
+
+
+ //
+ //
+ struct Extends : Edge<SemanticGraph::Extends>
+ {
+ Extends ()
+ {
+ }
+
+ Extends (NodeBase& n)
+ {
+ node_traverser (n);
+ }
+
+ virtual Void
+ traverse (Type& e)
+ {
+ dispatch (e.base ());
+ }
+ };
+
+
+ //
+ //
+ struct Restricts : Edge<SemanticGraph::Restricts>
+ {
+ Restricts ()
+ {
+ }
+
+ Restricts (NodeBase& n)
+ {
+ node_traverser (n);
+ }
+
+ virtual Void
+ traverse (Type& e)
+ {
+ dispatch (e.base ());
+ }
+ };
+
+
+ //
+ //
+ struct Argumented : Edge<SemanticGraph::Arguments>
+ {
+ Argumented ()
+ {
+ }
+
+ Argumented (NodeBase& n)
+ {
+ node_traverser (n);
+ }
+
+ virtual Void
+ traverse (Type& a)
+ {
+ dispatch (a.type ());
+ }
+ };
+
+
+ /*
+ //
+ //
+ struct Contains : Edge<SemanticGraph::Contains>
+ {
+ virtual Void
+ traverse (Type& e)
+ {
+ dispatch (e.element ());
+ }
+ };
+ */
+
+ //
+ //
+ typedef
+ Node<SemanticGraph::AnyType>
+ AnyType;
+
+
+ //
+ //
+ typedef
+ Node<SemanticGraph::AnySimpleType>
+ AnySimpleType;
+ }
+}
+
+#include <xsd-frontend/traversal/elements.txx>
+
+#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 <boris@codesynthesis.com>
+// 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 <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <xsd-frontend/traversal/enumeration.hxx>
+
+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 <boris@codesynthesis.com>
+// 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 <xsd-frontend/traversal/elements.hxx>
+#include <xsd-frontend/semantic-graph/enumeration.hxx>
+
+namespace XSDFrontend
+{
+ namespace Traversal
+ {
+ struct Enumeration : ScopeTemplate<SemanticGraph::Enumeration>
+ {
+ 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<SemanticGraph::Enumerator>
+ {
+ 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 <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <xsd-frontend/traversal/fundamental.hxx>
+
+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 <boris@codesynthesis.com>
+// 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 <xsd-frontend/traversal/elements.hxx>
+#include <xsd-frontend/semantic-graph/fundamental.hxx>
+
+namespace XSDFrontend
+{
+ namespace Traversal
+ {
+ namespace Fundamental
+ {
+ typedef
+ Node<SemanticGraph::Fundamental::Type>
+ Type;
+
+ // Integers.
+ //
+ typedef
+ Node<SemanticGraph::Fundamental::Byte>
+ Byte;
+
+ typedef
+ Node<SemanticGraph::Fundamental::UnsignedByte>
+ UnsignedByte;
+
+ typedef
+ Node<SemanticGraph::Fundamental::Short>
+ Short;
+
+ typedef
+ Node<SemanticGraph::Fundamental::UnsignedShort>
+ UnsignedShort;
+
+ typedef
+ Node<SemanticGraph::Fundamental::Int>
+ Int;
+
+ typedef
+ Node<SemanticGraph::Fundamental::UnsignedInt>
+ UnsignedInt;
+
+ typedef
+ Node<SemanticGraph::Fundamental::Long>
+ Long;
+
+ typedef
+ Node<SemanticGraph::Fundamental::UnsignedLong>
+ UnsignedLong;
+
+ typedef
+ Node<SemanticGraph::Fundamental::Integer>
+ Integer;
+
+ typedef
+ Node<SemanticGraph::Fundamental::NonPositiveInteger>
+ NonPositiveInteger;
+
+ typedef
+ Node<SemanticGraph::Fundamental::NonNegativeInteger>
+ NonNegativeInteger;
+
+ typedef
+ Node<SemanticGraph::Fundamental::PositiveInteger>
+ PositiveInteger;
+
+ typedef
+ Node<SemanticGraph::Fundamental::NegativeInteger>
+ NegativeInteger;
+
+
+ // Boolean.
+ //
+ typedef
+ Node<SemanticGraph::Fundamental::Boolean>
+ Boolean;
+
+
+ // Floats.
+ //
+ typedef
+ Node<SemanticGraph::Fundamental::Float>
+ Float;
+
+ typedef
+ Node<SemanticGraph::Fundamental::Double>
+ Double;
+
+ typedef
+ Node<SemanticGraph::Fundamental::Decimal>
+ Decimal;
+
+
+ // Strings.
+ //
+ typedef
+ Node<SemanticGraph::Fundamental::String>
+ String;
+
+ typedef
+ Node<SemanticGraph::Fundamental::NormalizedString>
+ NormalizedString;
+
+ typedef
+ Node<SemanticGraph::Fundamental::Token>
+ Token;
+
+ typedef
+ Node<SemanticGraph::Fundamental::Name>
+ Name;
+
+ typedef
+ Node<SemanticGraph::Fundamental::NameToken>
+ NameToken;
+
+ typedef
+ Node<SemanticGraph::Fundamental::NameTokens>
+ NameTokens;
+
+ typedef
+ Node<SemanticGraph::Fundamental::NCName>
+ NCName;
+
+ typedef
+ Node<SemanticGraph::Fundamental::Language>
+ Language;
+
+
+ // Qualified name.
+ //
+ typedef
+ Node<SemanticGraph::Fundamental::QName>
+ QName;
+
+
+ // ID/IDREF.
+ //
+ typedef
+ Node<SemanticGraph::Fundamental::Id>
+ Id;
+
+ typedef
+ Node<SemanticGraph::Fundamental::IdRef>
+ IdRef;
+
+ typedef
+ Node<SemanticGraph::Fundamental::IdRefs>
+ IdRefs;
+
+
+ // URI.
+ //
+ typedef
+ Node<SemanticGraph::Fundamental::AnyURI>
+ AnyURI;
+
+
+ // Binary.
+ //
+ typedef
+ Node<SemanticGraph::Fundamental::Base64Binary>
+ Base64Binary;
+
+ typedef
+ Node<SemanticGraph::Fundamental::HexBinary>
+ HexBinary;
+
+
+ // Date/time.
+ //
+ typedef
+ Node<SemanticGraph::Fundamental::Date>
+ Date;
+
+ typedef
+ Node<SemanticGraph::Fundamental::DateTime>
+ DateTime;
+
+ typedef
+ Node<SemanticGraph::Fundamental::Duration>
+ Duration;
+
+ typedef
+ Node<SemanticGraph::Fundamental::Day>
+ Day;
+
+ typedef
+ Node<SemanticGraph::Fundamental::Month>
+ Month;
+
+ typedef
+ Node<SemanticGraph::Fundamental::MonthDay>
+ MonthDay;
+
+ typedef
+ Node<SemanticGraph::Fundamental::Year>
+ Year;
+
+ typedef
+ Node<SemanticGraph::Fundamental::YearMonth>
+ YearMonth;
+
+ typedef
+ Node<SemanticGraph::Fundamental::Time>
+ Time;
+
+
+ // Entity.
+ //
+ typedef
+ Node<SemanticGraph::Fundamental::Entity>
+ Entity;
+
+ typedef
+ Node<SemanticGraph::Fundamental::Entities>
+ Entities;
+
+
+ // Notation.
+ //
+ typedef
+ Node<SemanticGraph::Fundamental::Notation>
+ 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 <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <xsd-frontend/traversal/list.hxx>
+
+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 <boris@codesynthesis.com>
+// 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 <xsd-frontend/traversal/elements.hxx>
+#include <xsd-frontend/semantic-graph/list.hxx>
+
+namespace XSDFrontend
+{
+ namespace Traversal
+ {
+ struct List: Node<SemanticGraph::List>
+ {
+ 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 <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <xsd-frontend/traversal/namespace.hxx>
+
+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 <boris@codesynthesis.com>
+// 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 <xsd-frontend/traversal/elements.hxx>
+#include <xsd-frontend/semantic-graph/namespace.hxx>
+
+namespace XSDFrontend
+{
+ namespace Traversal
+ {
+ struct Namespace: ScopeTemplate<SemanticGraph::Namespace>
+ {
+ 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 <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2010 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <xsd-frontend/traversal/particle.hxx>
+
+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 <boris@codesynthesis.com>
+// 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 <xsd-frontend/traversal/elements.hxx>
+#include <xsd-frontend/semantic-graph/particle.hxx>
+
+namespace XSDFrontend
+{
+ namespace Traversal
+ {
+ struct Particle : Node<SemanticGraph::Particle>
+ {
+ 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 <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <xsd-frontend/traversal/schema.hxx>
+
+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 <boris@codesynthesis.com>
+// 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 <xsd-frontend/traversal/elements.hxx>
+#include <xsd-frontend/semantic-graph/schema.hxx>
+
+namespace XSDFrontend
+{
+ namespace Traversal
+ {
+ //
+ //
+ struct Uses: Edge<SemanticGraph::Uses>
+ {
+ Uses ()
+ {
+ }
+
+ Uses (NodeBase& n)
+ {
+ node_traverser (n);
+ }
+
+ virtual Void
+ traverse (Type& e)
+ {
+ dispatch (e.schema ());
+ }
+ };
+
+ //
+ //
+ struct Implies: Edge<SemanticGraph::Implies>
+ {
+ Implies ()
+ {
+ }
+
+ Implies (NodeBase& n)
+ {
+ node_traverser (n);
+ }
+
+ virtual Void
+ traverse (Type& e)
+ {
+ dispatch (e.schema ());
+ }
+ };
+
+
+ //
+ //
+ struct Sources: Edge<SemanticGraph::Sources>
+ {
+ Sources ()
+ {
+ }
+
+ Sources (NodeBase& n)
+ {
+ node_traverser (n);
+ }
+
+ virtual Void
+ traverse (Type& e)
+ {
+ dispatch (e.schema ());
+ }
+ };
+
+
+ //
+ //
+ struct Includes: Edge<SemanticGraph::Includes>
+ {
+ Includes ()
+ {
+ }
+
+ Includes (NodeBase& n)
+ {
+ node_traverser (n);
+ }
+
+ virtual Void
+ traverse (Type& e)
+ {
+ dispatch (e.schema ());
+ }
+ };
+
+
+ //
+ //
+ struct Imports: Edge<SemanticGraph::Imports>
+ {
+ Imports ()
+ {
+ }
+
+ Imports (NodeBase& n)
+ {
+ node_traverser (n);
+ }
+
+ virtual Void
+ traverse (Type& e)
+ {
+ dispatch (e.schema ());
+ }
+ };
+
+
+ //
+ //
+ struct Schema: ScopeTemplate<SemanticGraph::Schema>
+ {
+ 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 <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <xsd-frontend/traversal/union.hxx>
+
+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 <boris@codesynthesis.com>
+// 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 <xsd-frontend/traversal/elements.hxx>
+#include <xsd-frontend/semantic-graph/union.hxx>
+
+namespace XSDFrontend
+{
+ namespace Traversal
+ {
+ struct Union: Node<SemanticGraph::Union>
+ {
+ 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 <boris@codesynthesis.com>
+// 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 <cult/types.hxx>
+
+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 <boris@codesynthesis.com>
+// 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 <ostream>
+
+#include <xercesc/dom/DOM.hpp>
+#include <xercesc/util/XMLString.hpp>
+
+#include <cult/containers/vector.hxx>
+
+#include <xsd-frontend/types.hxx>
+#include <xsd-frontend/schema-dom-parser.hxx>
+
+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<WideChar*> (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<const WideChar*> (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<XMLCh> (((w - 0x10000) >> 10) + 0xD800);
+ *ir++ = static_cast<XMLCh> ((w & 0x3FF) + 0xDC00);
+ }
+ else
+ *ir++ = static_cast<XMLCh> (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<XMLCh> (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<UnsignedLong> (e_->getUserData (line_key));
+ }
+
+ UnsignedLong
+ column () const
+ {
+ //@@ cache
+ //
+ return reinterpret_cast<UnsignedLong> (e_->getUserData (column_key));
+ }
+
+ public:
+ Element
+ parent () const
+ {
+ return dynamic_cast<Xerces::DOMElement*>(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 <typename X>
+ struct AutoPtrRef
+ {
+ X* x_;
+
+ explicit
+ AutoPtrRef (X* x)
+ : x_ (x)
+ {
+ }
+ };
+
+ template <typename X>
+ struct AutoPtr
+ {
+ ~AutoPtr ()
+ {
+ reset ();
+ }
+
+ explicit
+ AutoPtr (X* x = 0)
+ : x_ (x)
+ {
+ }
+
+ AutoPtr (AutoPtr& y)
+ : x_ (y.release ())
+ {
+ }
+
+ AutoPtr (AutoPtrRef<X> r)
+ : x_ (r.x_)
+ {
+ }
+
+ AutoPtr&
+ operator= (AutoPtr& y)
+ {
+ if (this != &y)
+ {
+ reset (y.release ());
+ }
+
+ return *this;
+ }
+
+ AutoPtr&
+ operator= (AutoPtrRef<X> r)
+ {
+ if (r.x_ != x_)
+ {
+ reset (r.x_);
+ }
+
+ return *this;
+ }
+
+ operator AutoPtrRef<X> ()
+ {
+ return AutoPtrRef<X> (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<X>::operator-> : 0;
+ }
+
+ private:
+ X* x_;
+ };
+
+ template <typename X>
+ struct PtrVector: Cult::Containers::Vector<X*>
+ {
+ typedef Cult::Containers::Vector<X*> Base;
+
+ ~PtrVector ()
+ {
+ for (typename Base::Iterator i (this->begin ()), e (this->end ());
+ i != e; ++i)
+ {
+ if (*i)
+ (*i)->release ();
+ }
+ }
+
+ Void
+ push_back (AutoPtr<X>& 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