pax_global_header00006660000000000000000000000064147262320110014510gustar00rootroot0000000000000052 comment=68f99087a3811ab4993d74b41c3be9b4810afe6a libkode-master/000077500000000000000000000000001472623201100137565ustar00rootroot00000000000000libkode-master/.clang-format000066400000000000000000000056401472623201100163360ustar00rootroot00000000000000# Copyright (C) 2016 Olivier Goffart # # You may use this file under the terms of the 3-clause BSD license. # See the file LICENSE from this package for details. # This is the clang-format configuration style to be used by Qt, # based on the rules from https://wiki.qt.io/Qt_Coding_Style and # https://wiki.qt.io/Coding_Conventions --- # Webkit style was loosely based on the Qt style BasedOnStyle: WebKit Standard: Cpp11 # Column width is limited to 100 in accordance with Qt Coding Style. # https://wiki.qt.io/Qt_Coding_Style # Note that this may be changed at some point in the future. ColumnLimit: 100 # How much weight do extra characters after the line length limit have. # PenaltyExcessCharacter: 4 # Disable reflow of qdoc comments: indentation rules are different. # Translation comments are also excluded. CommentPragmas: "^!|^:" # We want a space between the type and the star for pointer types. PointerBindsToType: false # We use template< without space. SpaceAfterTemplateKeyword: false # We want to break before the operators, but not before a '='. BreakBeforeBinaryOperators: NonAssignment # Braces are usually attached, but not after functions or class declarations. BreakBeforeBraces: Custom BraceWrapping: AfterClass: true AfterControlStatement: false AfterEnum: false AfterFunction: true AfterNamespace: false AfterObjCDeclaration: false AfterStruct: true AfterUnion: false BeforeCatch: false BeforeElse: false IndentBraces: false # When constructor initializers do not fit on one line, put them each on a new line. ConstructorInitializerAllOnOneLineOrOnePerLine: true # Indent initializers by 4 spaces ConstructorInitializerIndentWidth: 4 # Indent width for line continuations. ContinuationIndentWidth: 8 # No indentation for namespaces. NamespaceIndentation: None # Allow indentation for preprocessing directives (if/ifdef/endif). https://reviews.llvm.org/rL312125 IndentPPDirectives: AfterHash # Horizontally align arguments after an open bracket. # The coding style does not specify the following, but this is what gives # results closest to the existing code. AlignAfterOpenBracket: true AlwaysBreakTemplateDeclarations: true # Ideally we should also allow less short function in a single line, but # clang-format does not handle that. AllowShortFunctionsOnASingleLine: Inline # The coding style specifies some include order categories, but also tells to # separate categories with an empty line. It does not specify the order within # the categories. Since the SortInclude feature of clang-format does not # re-order includes separated by empty lines, the feature is not used. SortIncludes: false # macros for which the opening brace stays attached. ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH, forever, Q_FOREVER, QBENCHMARK, QBENCHMARK_ONCE ] # Break constructor initializers before the colon and after the commas. BreakConstructorInitializers: BeforeColon libkode-master/.github/000077500000000000000000000000001472623201100153165ustar00rootroot00000000000000libkode-master/.github/workflows/000077500000000000000000000000001472623201100173535ustar00rootroot00000000000000libkode-master/.github/workflows/build.yml000066400000000000000000000025161472623201100212010ustar00rootroot00000000000000name: build on: push: branches: - master pull_request: branches: - master jobs: build: runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: os: - ubuntu-latest - windows-latest - macos-latest config: - qt_version: 5.15.2 macos_architectures: "x86_64" - qt_version: 6.6.2 macos_architectures: "x86_64;arm64" steps: - name: Checkout uses: actions/checkout@v4 - name: Install Qt uses: jurplel/install-qt-action@v4 with: aqtversion: null # use whatever the default is modules: ${{ matrix.config.qt_modules }} version: ${{ matrix.config.qt_version }} cache: true - name: Install ninja-build tool (must be after Qt due PATH changes) uses: turtlesec-no/get-ninja@main - name: Make sure MSVC is found when Ninja generator is in use if: ${{ runner.os == 'Windows' }} uses: ilammy/msvc-dev-cmd@v1 - name: Configure project run: > cmake -S . -B ./build -G Ninja -DCMAKE_OSX_ARCHITECTURES="${{ matrix.config.macos_architectures }}" -Dlibkode_QT6=${{ startsWith(matrix.config.qt_version, '6.') }} - name: Build project run: cmake --build ./build libkode-master/.github/workflows/clang_formatter.yml000066400000000000000000000004241472623201100232450ustar00rootroot00000000000000name: test-clang-format on: [push, pull_request] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v1 - uses: DoozyX/clang-format-lint-action@v0.5 with: source: '.' extensions: 'h,cpp' clangFormatVersion: 9 libkode-master/.gitignore000066400000000000000000000016731472623201100157550ustar00rootroot00000000000000# CMake.gitignore: # https://github.com/github/gitignore/blob/master/CMake.gitignore CMakeCache.txt CMakeFiles CMakeScripts Testing Makefile cmake_install.cmake cmake_uninstall.cmake install_manifest.txt compile_commands.json CTestTestfile.cmake CMakeTmp/* # Qt.gitignore: # https://github.com/github/gitignore/blob/master/Qt.gitignore # C++ objects and libs *.slo *.lo *.o *.a *.la *.lai *.so *.so.* *.dll *.dylib # Qt-es object_script.*.Release object_script.*.Debug *_plugin_import.cpp /.qmake.cache /.qmake.stash *.pro.user *.pro.user.* *.qbs.user *.qbs.user.* *.moc moc_*.cpp moc_*.h qrc_*.cpp ui_*.h *.qmlc *.jsc Makefile* *build-* # Qt unit tests target_wrapper.* # QtCreator *.autosave # QtCtreator Qml *.qmlproject.user *.qmlproject.user.* # QtCtreator CMake CMakeLists.txt.user* # own additions *automoc.cpp* *.creator.user* *.shell #kde show hidden files marker .directory mocs* kxml_compiler/kxml_compiler* # test generated codes libkode-master/CMakeLists.txt000066400000000000000000000021031472623201100165120ustar00rootroot00000000000000# Pass the following variables to cmake to control the build: # # -Dlibkode_QT6=[true|false] # Build against Qt6 rather than Qt5 # Default=false (Qt5 will be used even if Qt6 is available) cmake_minimum_required(VERSION 3.11) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) project(libkode) option(${PROJECT_NAME}_QT6 "Build against Qt 6" OFF) if(${PROJECT_NAME}_QT6) find_package(Qt6 6.0.0 CONFIG REQUIRED COMPONENTS Core Network Xml Test) set(QT_MAJOR_VERSION 6) set(libkode_LIBRARY_QTID "-qt6") else() # Qt 5.9 required for QNetworkRequest::NoLessSafeRedirectPolicy find_package(Qt5 5.9.0 CONFIG REQUIRED COMPONENTS Core Network Xml Test) set(QT_MAJOR_VERSION 5) set(libkode_LIBRARY_QTID "") endif() set(CMAKE_AUTOMOC ON) set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) include_directories(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/code_generation ) enable_testing() add_subdirectory(code_generation) add_subdirectory(common) add_subdirectory(schema) add_subdirectory(autotests) libkode-master/LICENSE.txt000066400000000000000000000612661472623201100156140ustar00rootroot00000000000000 GNU LIBRARY GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1991 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the library GPL. It is numbered 2 because it goes with version 2 of the ordinary GPL.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Library General Public License, applies to some specially designated Free Software Foundation software, and to any other libraries whose authors decide to use it. You can use it for your libraries, 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 library, or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link a program with the library, you must provide complete object files to the recipients so that they can relink them with the library, after making changes to the library and recompiling it. And you must show them these terms so they know their rights. Our method of protecting your rights has two steps: (1) copyright the library, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the library. Also, for each distributor's protection, we want to make certain that everyone understands that there is no warranty for this free library. If the library is modified by someone else and passed on, we want its recipients to know that what they have is not the original version, 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 companies distributing free software will individually obtain patent licenses, thus in effect transforming the program into proprietary software. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License, which was designed for utility programs. This license, the GNU Library General Public License, applies to certain designated libraries. This license is quite different from the ordinary one; be sure to read it in full, and don't assume that anything in it is the same as in the ordinary license. The reason we have a separate public license for some libraries is that they blur the distinction we usually make between modifying or adding to a program and simply using it. Linking a program with a library, without changing the library, is in some sense simply using the library, and is analogous to running a utility program or application program. However, in a textual and legal sense, the linked executable is a combined work, a derivative of the original library, and the ordinary General Public License treats it as such. Because of this blurred distinction, using the ordinary General Public License for libraries did not effectively promote software sharing, because most developers did not use the libraries. We concluded that weaker conditions might promote sharing better. However, unrestricted linking of non-free programs would deprive the users of those programs of all benefit from the free status of the libraries themselves. This Library General Public License is intended to permit developers of non-free programs to use free libraries, while preserving your freedom as a user of such programs to change the free libraries that are incorporated in them. (We have not seen how to achieve this as regards changes in header files, but we have achieved it as regards changes in the actual functions of the Library.) The hope is that this will lead to faster development of free libraries. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, while the latter only works together with the library. Note that it is possible for a library to be covered by the ordinary General Public License rather than by this special one. GNU LIBRARY GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Library General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, 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 library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete 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 distribute a copy of this License along with the Library. 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 Library or any portion of it, thus forming a work based on the Library, 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) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, 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 Library, 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 Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you 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. If distribution of 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 satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also compile or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. c) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. d) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. 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. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library 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. 9. 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 Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library 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. 11. 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 Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library 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 Library. 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. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library 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. 13. The Free Software Foundation may publish revised and/or new versions of the Library 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 Library 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 Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, 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 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "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 LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. 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 LIBRARY 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 LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), 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 Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that everyone can redistribute and change. You can do so by permitting redistribution under these terms (or, alternatively, under the terms of the ordinary General Public License). To apply these terms, attach the following notices to the library. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, see . Also add information on how to contact you by electronic and paper mail. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the library, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the library `Frob' (a library for tweaking knobs) written by James Random Hacker. , 1 April 1990 Moe Ghoul, President of Vice That's all there is to it! libkode-master/README.md000066400000000000000000000017761472623201100152500ustar00rootroot00000000000000### libkode This repository contains C++/Qt code mainly for C++ code generation and XML/XSD parsing. The code was originally part of the [kode](https://github.com/cornelius/kode) and the [KDSOAP](https://github.com/KDAB/KDSoap) project. Later we moved it to a separate repository to ease the developent between the two projects. #### Code generation The goal of these codes to ease generation of C++ code from Qt based applications. The code generator is designed to support generating C++11 and onwards compliant code. #### Projects using this code * [kode](https://github.com/cornelius/kode) - Qt based XML meta programming tool * [KDSOAP](https://github.com/KDAB/KDSoap) - A Qt-based client-side and server-side SOAP component * [nut-codegen](https://github.com/martonmiklos/nut_codegen) - code generator for the [Nut ORM](https://github.com/HamedMasafi/Nut) If you would like to get your public project using libkode listed here please let us know in an [issue](https://github.com/cornelius/libkode/issues). libkode-master/autotests/000077500000000000000000000000001472623201100160115ustar00rootroot00000000000000libkode-master/autotests/CMakeLists.txt000066400000000000000000000005641472623201100205560ustar00rootroot00000000000000macro(xmlschema_add_test _target) add_executable(${_target} ${_global_add_executable_param} ${ARGN}) target_link_libraries(${_target} xmlschema Qt${QT_MAJOR_VERSION}::Test) add_test(${_target} ${_target}) endmacro() xmlschema_add_test(tst_xmlelement tst_xmlelement.cpp) xmlschema_add_test(tst_element tst_element.cpp) xmlschema_add_test(tst_group tst_group.cpp) libkode-master/autotests/tst_element.cpp000066400000000000000000000015221472623201100210400ustar00rootroot00000000000000#include "element.h" #include using namespace XSD; class ElementTest : public QObject { Q_OBJECT private Q_SLOTS: void constructors(); void assignment(); }; void ElementTest::constructors() { Element e("ns1"); e.setName("elem"); e.setMinOccurs(3); Element copy(e); QCOMPARE(copy.name(), "elem"); QCOMPARE(copy.minOccurs(), 3); Element moved = std::move(e); QCOMPARE(moved.name(), "elem"); QCOMPARE(moved.minOccurs(), 3); } void ElementTest::assignment() { Element e("ns1"); e.setName("elem"); e.setNillable(true); Element copy; copy = e; QCOMPARE(copy.name(), "elem"); QVERIFY(copy.nillable()); Element moved; moved = std::move(e); QCOMPARE(moved.name(), "elem"); QVERIFY(moved.nillable()); } QTEST_MAIN(ElementTest) #include "tst_element.moc" libkode-master/autotests/tst_group.cpp000066400000000000000000000022321472623201100205420ustar00rootroot00000000000000#include "group.h" #include using namespace XSD; class GroupTest : public QObject { Q_OBJECT private Q_SLOTS: void constructors(); void assignment(); }; void GroupTest::constructors() { Group group; group.setName("group"); group.setReference(QName("ns", "local")); Group copy(group); QCOMPARE(copy.name(), "group"); QCOMPARE(copy.reference().nameSpace(), "ns"); QCOMPARE(copy.reference().localName(), "local"); Group moved = std::move(group); QCOMPARE(moved.name(), "group"); QCOMPARE(moved.reference().nameSpace(), "ns"); QCOMPARE(moved.reference().localName(), "local"); } void GroupTest::assignment() { Group group; group.setName("group"); group.setReference(QName("ns", "local")); Group copy; copy = group; QCOMPARE(copy.name(), "group"); QCOMPARE(copy.reference().nameSpace(), "ns"); QCOMPARE(copy.reference().localName(), "local"); Group moved; moved = std::move(group); QCOMPARE(moved.name(), "group"); QCOMPARE(moved.reference().nameSpace(), "ns"); QCOMPARE(moved.reference().localName(), "local"); } QTEST_MAIN(GroupTest) #include "tst_group.moc" libkode-master/autotests/tst_xmlelement.cpp000066400000000000000000000013461472623201100215650ustar00rootroot00000000000000#include "xmlelement.h" #include using namespace XSD; class XmlElementTest : public QObject { Q_OBJECT private Q_SLOTS: void constructors(); void assignment(); }; void XmlElementTest::constructors() { XmlElement e("ns1"); e.setName("elem"); XmlElement copy(e); QCOMPARE(copy.name(), QString("elem")); XmlElement moved = std::move(e); QCOMPARE(moved.name(), QString("elem")); } void XmlElementTest::assignment() { XmlElement e("ns1"); e.setName("elem"); XmlElement copy; copy = e; QCOMPARE(copy.name(), QString("elem")); XmlElement moved; moved = std::move(e); QCOMPARE(moved.name(), QString("elem")); } QTEST_MAIN(XmlElementTest) #include "tst_xmlelement.moc" libkode-master/code_generation/000077500000000000000000000000001472623201100171035ustar00rootroot00000000000000libkode-master/code_generation/CMakeLists.txt000066400000000000000000000013131472623201100216410ustar00rootroot00000000000000set(CODE_GENERATION_SOURCES class.cpp code.cpp enum.cpp file.cpp function.cpp include.cpp license.cpp membervariable.cpp namer.cpp printer.cpp statemachine.cpp style.cpp typedef.cpp variable.cpp ) set(CODE_GENERATION_HEADERS class.h code.h enum.h file.h function.h include.h kode_export.h license.h membervariable.h namer.h printer.h statemachine.h style.h typedef.h variable.h ) add_library(kode STATIC ${CODE_GENERATION_SOURCES} ${CODE_GENERATION_HEADERS} ) target_link_libraries(kode Qt${QT_MAJOR_VERSION}::Core ) target_include_directories(kode PUBLIC Qt${QT_MAJOR_VERSION}::Core ) set_target_properties(kode PROPERTIES OUTPUT_NAME "kode${kode_LIBRARY_QTID}") libkode-master/code_generation/class.cpp000066400000000000000000000301631472623201100207170ustar00rootroot00000000000000/* This file is part of kdepim. Copyright (c) 2004 Cornelius Schumacher Copyright (c) 2010 David Faure This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "class.h" #include using namespace KODE; class Class::Private { public: QString mName; QString mNameSpace; QString mExportDeclaration; QString mDPointer; bool mUseSharedData = false; bool mCanBeCopied = false; Function::List mFunctions; MemberVariable::List mMemberVariables; QStringList mIncludes; QStringList mForwardDeclarations; Include::List mHeaderIncludes; Class::List mBaseClasses; Typedef::List mTypedefs; Enum::List mEnums; QString mDocs; Class::List mNestedClasses; QString mParentClassName; QStringList mDeclMacros; bool mIsQGadget = false; bool mIsQObject = false; }; Class::Class() : d(new Private) {} Class::Class(const Class &other) : d(new Private) { *d = *other.d; } Class::Class(const QString &name, const QString &nameSpace) : d(new Private) { Q_ASSERT(!name.isEmpty()); d->mName = name; d->mNameSpace = nameSpace; } Class::~Class() { delete d; } Class &Class::operator=(const Class &other) { if (this == &other) return *this; *d = *other.d; return *this; } void Class::setName(const QString &name) { Q_ASSERT(!name.isEmpty()); d->mName = name; } QString Class::name() const { return d->mName; } void Class::setNameSpace(const QString &nameSpace) { d->mNameSpace = nameSpace; } QString Class::nameSpace() const { return d->mNameSpace; } QString Class::qualifiedName() const { if (d->mNameSpace.isEmpty()) return d->mName; return d->mNameSpace + QLatin1String("::") + d->mName; } void Class::setExportDeclaration(const QString &name) { addHeaderInclude(name.toLower() + "_export.h"); if (name.contains("/")) { d->mExportDeclaration = name.split("/").value(1); } else { d->mExportDeclaration = name; } } QString Class::exportDeclaration() const { return d->mExportDeclaration; } void Class::setUseDPointer(bool useDPointer, const QString &dPointer) { d->mDPointer = useDPointer ? dPointer : QString(); } bool Class::useDPointer() const { return !d->mDPointer.isEmpty(); } void Class::setUseSharedData(bool b, const QString &dPointer) { d->mUseSharedData = b; if (b) { setUseDPointer(true, dPointer); d->mCanBeCopied = true; } } bool Class::useSharedData() const { return d->mUseSharedData; } void Class::setCanBeCopied(bool b) { d->mCanBeCopied = b; } bool Class::canBeCopied() const { return d->mCanBeCopied; } void Class::addInclude(const QString &include, const QString &forwardDeclaration) { if (!include.isEmpty() && !d->mIncludes.contains(include)) d->mIncludes.append(include); if (!forwardDeclaration.isEmpty() && !d->mForwardDeclarations.contains(forwardDeclaration)) d->mForwardDeclarations.append(forwardDeclaration); } void Class::addIncludes(const QStringList &files, const QStringList &forwardDeclarations) { for (int i = 0; i < files.count(); ++i) { if (!d->mIncludes.contains(files[i])) if (!files[i].isEmpty()) d->mIncludes.append(files[i]); } for (int i = 0; i < forwardDeclarations.count(); ++i) { if (!d->mForwardDeclarations.contains(forwardDeclarations[i])) d->mForwardDeclarations.append(forwardDeclarations[i]); } } QStringList Class::includes() const { return d->mIncludes; } QStringList Class::forwardDeclarations() const { return d->mForwardDeclarations; } void Class::addHeaderInclude(const QString &include, Include::IncludeType type) { auto newInclude = Include(include, type); if (include.isEmpty() || d->mHeaderIncludes.contains(newInclude)) return; d->mHeaderIncludes.append(newInclude); } void Class::addHeaderIncludes(const QStringList &includes, Include::IncludeType type) { QStringList::ConstIterator it; for (it = includes.constBegin(); it != includes.constEnd(); ++it) addHeaderInclude(*it, type); } Include::List Class::headerIncludes() const { return d->mHeaderIncludes; } void Class::addBaseClass(const Class &c) { d->mBaseClasses.append(c); } Class::List Class::baseClasses() const { return d->mBaseClasses; } void Class::addFunction(const Function &function) { d->mFunctions.append(function); if (!d->mIsQObject) { if (function.access() & Function::Signal || function.access() & Function::Slot) d->mIsQObject = true; } } Function::List Class::functions() const { return d->mFunctions; } void Class::addMemberVariable(const MemberVariable &v) { d->mMemberVariables.append(v); } MemberVariable::List Class::memberVariables() const { return d->mMemberVariables; } void Class::addTypedef(const Typedef &typeDefinition) { d->mTypedefs.append(typeDefinition); } Typedef::List Class::typedefs() const { return d->mTypedefs; } void Class::addEnum(const Enum &enumValue) { d->mEnums.append(enumValue); } Enum::List Class::enums() const { return d->mEnums; } bool Class::hasEnum(const QString &name) const { for (const Enum &e : std::as_const(d->mEnums)) { if (e.name() == name) return true; } return false; } bool Class::isValid() const { return !d->mName.isEmpty(); } bool Class::hasFunction(const QString &functionName) const { Function::List::ConstIterator it; for (it = d->mFunctions.constBegin(); it != d->mFunctions.constEnd(); ++it) { if ((*it).name() == functionName) return true; } return false; } void Class::setQObject(bool isQObject) { d->mIsQObject = isQObject; } bool Class::isQObject() const { return d->mIsQObject; } bool Class::isQGadget() const { return d->mIsQGadget; } void Class::setQGadget(const bool isQGadget) { d->mIsQGadget = isQGadget; } void Class::setDocs(const QString &str) { d->mDocs = str; } QString Class::docs() const { return d->mDocs; } void Class::addNestedClass(const Class &nestedClass) { Class addedClass = nestedClass; addedClass.setParentClassName(name()); d->mNestedClasses.append(addedClass); } Class::List Class::nestedClasses() const { return d->mNestedClasses; } QString Class::parentClassName() const { return d->mParentClassName; } void Class::setParentClassName(const QString &parentClassName) { d->mParentClassName = parentClassName; } QString Class::dPointerName() const { return d->mDPointer; } //// // Returns what a class depends on: its base class(es) and any by-value member var static QStringList dependenciesForClass(const Class &aClass, const QStringList &allClasses, const QStringList &excludedClasses) { QStringList lst; Q_FOREACH (const Class &baseClass, aClass.baseClasses()) { const QString baseName = baseClass.qualifiedName(); if (!baseName.startsWith('Q') && !excludedClasses.contains(baseName)) lst.append(baseClass.name()); } if (!aClass.useDPointer()) { Q_FOREACH (const MemberVariable &member, aClass.memberVariables()) { const QString type = member.type(); if (allClasses.contains(type)) { lst.append(type); } } } return lst; } static bool allKnown(const QStringList &deps, const QStringList &classNames) { Q_FOREACH (const QString &dep, deps) { if (!classNames.contains(dep)) { return false; } } return true; } static bool classLessThan(const Class &c1, const Class &c2) { return c1.qualifiedName() < c2.qualifiedName(); } /** * This method sorts a list of classes in a way that the base class * of a class, as well as the classes it use by value in member vars, * always appear before the class itself. */ static Class::List sortByDependenciesHelper(const Class::List &classes, const QStringList &excludedClasses) { Class::List allClasses(classes); std::sort(allClasses.begin(), allClasses.end(), classLessThan); // make result deterministic QStringList allClassNames; Q_FOREACH (const Class &c, allClasses) allClassNames.append(c.qualifiedName()); Class::List retval; QStringList classNames; // copy all classes without dependencies Class::List::Iterator it = allClasses.begin(); while (it != allClasses.end()) { if (dependenciesForClass(*it, allClassNames, excludedClasses).isEmpty()) { retval.append(*it); classNames.append((*it).qualifiedName()); it = allClasses.erase(it); } else { ++it; } } while (!allClasses.isEmpty()) { const int currentCount = allClasses.count(); // copy all classes which have a class from retval/classNames (i.e. already written out) // as base class - or as member variable for (it = allClasses.begin(); it != allClasses.end();) { const QStringList deps = dependenciesForClass(*it, allClassNames, excludedClasses); if (allKnown(deps, classNames)) { retval.append(*it); classNames.append((*it).qualifiedName()); it = allClasses.erase(it); } else { ++it; } } if (allClasses.count() == currentCount) { // We didn't resolve anything this time around, so let's not loop forever qDebug() << "ERROR: Couldn't find class dependencies (base classes, member vars) for " "classes" << allClasses.classNames(); Q_FOREACH (const Class &c, allClasses) { qDebug() << c.qualifiedName() << "depends on" << dependenciesForClass(c, allClassNames, excludedClasses); } return retval; } } return retval; } void ClassList::sortByDependencies(const QStringList &excludedClasses) { *this = sortByDependenciesHelper(*this, excludedClasses); } void ClassList::sortAlphabetically() { std::sort(begin(), end(), classLessThan); } ClassList::const_iterator ClassList::findClass(const QString &qualifiedName) const { ClassList::const_iterator it = begin(); for (; it != end(); ++it) if ((*it).qualifiedName() == qualifiedName) break; return it; } QStringList KODE::ClassList::classNames() const { QStringList names; ClassList::const_iterator it = begin(); for (; it != end(); ++it) names.append((*it).name()); return names; } void KODE::ClassList::addClass(const Class &cl) { const QString qn = cl.qualifiedName(); ClassList::iterator it = begin(); for (; it != end(); ++it) { if ((*it).qualifiedName() == qn) { qWarning() << "ERROR: Already having a class called" << qn; } } *this += cl; } void KODE::Class::addDeclarationMacro(const QString ¯o) { d->mDeclMacros.append(macro); } QStringList KODE::Class::declarationMacros() const { return d->mDeclMacros; } void KODE::Class::setNamespaceAndName(const QString &name) { d->mName = name; d->mNameSpace.clear(); while (d->mName.contains("::")) { const int pos = d->mName.indexOf("::"); if (!d->mNameSpace.isEmpty()) d->mNameSpace += QLatin1String("::"); d->mNameSpace += d->mName.left(pos); d->mName = d->mName.mid(pos + 2); } } libkode-master/code_generation/class.h000066400000000000000000000241451472623201100203670ustar00rootroot00000000000000/* This file is part of kdepim. Copyright (c) 2004 Cornelius Schumacher This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KODE_CLASS_H #define KODE_CLASS_H #include #include #include "enum.h" #include "include.h" #include "function.h" #include "membervariable.h" #include "typedef.h" #include namespace KODE { class ClassList; /** * This class abstracts a class object with functions, * member variables etc. */ class KODE_EXPORT Class { public: typedef ClassList List; /** * Creates a new class object. */ Class(); /** * Creates a new class object from @param other. */ Class(const Class &other); /** * Creates a new class object with a given @param name. * * @param nameSpace The namespace the class object should be part of. */ Class(const QString &name, const QString &nameSpace = QString()); /** * Destroys the class object. */ ~Class(); /** * Assignment operator. */ Class &operator=(const Class &other); /** * Returns whether this class object is valid. */ bool isValid() const; /** * Sets the name of the class object, possibly splitting out the namespace part of it. * E.g. Foo::Bar will set namespace = Bar, class name = Foo. * * This will treat anything except the last substring, as a namespace. * So this is not suited for nested classes. Use Class(A::B, NS) for nested classes. */ void setNamespaceAndName(const QString &name); /** * Sets the @param name of the class object. */ void setName(const QString &name); /** * Returns the name of the class object. */ QString name() const; /** * Sets the namespace the class object should be part of. */ void setNameSpace(const QString &nameSpace); /** * Returns the namespace the class object is part of. */ QString nameSpace() const; /** * Returns the fully qualified class name including namespaces, e.g. NS1::NS2::ClassName */ QString qualifiedName() const; /** Set export declaration with given name. This adds an include of a file name_export.h and a prefix to class declaration of NAME_EXPORT. */ void setExportDeclaration(const QString &name); /** Return name of export declaration. */ QString exportDeclaration() const; /** * Sets whether the class object shall use a d-pointer to store * its member variables. */ void setUseDPointer(bool useDPointer, const QString &dPointer = "d"); /** * Returns whether the class object uses a d-pointer. */ bool useDPointer() const; /** * Returns the name of the d pointer. * Usually d, but can be set to something else to avoid clashes with a d() method for instance. */ QString dPointerName() const; /** * Sets whether the class object shall use a QSharedDataPointer d-pointer * and a private class that derives from QSharedData. * This is for implicitly-shared value classes (classes that can be copied). * * Setting this to true automatically sets canBeCopied to true and useDPointer to true. */ void setUseSharedData(bool b, const QString &dPointer = "d"); /** * Returns whether the class object uses a QSharedDataPointer d-pointer. */ bool useSharedData() const; /** * Sets whether the class can be copied (generates a copy constructor * and an operator= implementations, in case a d pointer is used). */ void setCanBeCopied(bool b); /** * Returns whether the class instances can be copied. */ bool canBeCopied() const; /** * Adds an include to the class object. * * @param file The include file like 'qfile.h' which will be * printed as '#include ' in the header file. * @param forwardDeclaration The forward declaration like 'QFile' */ void addInclude(const QString &file, const QString &forwardDeclaration = QString()); /** * Adds several includes to the class object. * * @param files A list of include files like 'qfile.h' * @param forwardDeclaration A list of forward declarations like 'QFile' */ void addIncludes(const QStringList &files, const QStringList &forwardDeclarations = QStringList()); /** * Returns the list of includes. */ QStringList includes() const; /** * Returns the list of forward declarations. */ QStringList forwardDeclarations() const; /** * Adds a header include to the class object. * * @param file The header include file like 'qfile.h' which * will be printed as '#include "qfile.h"' in the * implementation. */ void addHeaderInclude(const QString &file, Include::IncludeType type = Include::Global); /** * Adds a list of header includes to the class object. */ void addHeaderIncludes(const QStringList &files, Include::IncludeType type = Include::Global); /** * Returns the list of header includes. */ Include::List headerIncludes() const; /** * Adds a @param function to the class object. */ void addFunction(const Function &function); /** * Returns the list of all functions. */ Function::List functions() const; /** * Adds a member @param variable to the class object. */ void addMemberVariable(const MemberVariable &variable); /** * Returns the list of all member variables. */ MemberVariable::List memberVariables() const; /** * Adds a base class definition to the class object. * * @param baseClass A class object which describes the base class. */ void addBaseClass(const Class &baseClass); /** * Returns the list of all base classes. */ Class::List baseClasses() const; /** * Adds a typedef to the class object. */ void addTypedef(const Typedef &typedefValue); /** * Returns the list of all typedefs. */ Typedef::List typedefs() const; /** * Adds an enum to the class object. */ void addEnum(const Enum &enumValue); /** * Returns the list of all enums. */ Enum::List enums() const; /** * Returns true, if the enum with the given name already exists. Returns * false, if not. */ bool hasEnum(const QString &name) const; /** * Sets the @param documentation of the class object. */ void setDocs(const QString &documentation); /** * Returns the documentation of the class object. */ QString docs() const; /** * Returns whether the class object has a function with * the given @param name. */ bool hasFunction(const QString &name) const; /** * Sets whether the Q_OBJECT macro should be generated at the first private * section. The Q_OBJECT macro will be generated if any signals or slots * added to the class, so this function is mainly useful when generating * intermediate classes derived from QObject, but not having any added signals * or slots. */ void setQObject(bool isQObject); /** * Returns whether the class object is a QObject. * * That's the case when one of its functions has the Signal * or Slot flag set. */ bool isQObject() const; /** * Returns whether the class should have a Q_GADGET macro */ bool isQGadget() const; /** * Sets whether the Q_GADGET macro should be generated at the first private * section. Please note if isQObject is set only the Q_OBJECT macro will * be genrated since adding Q_GADGET is useless this case. */ void setQGadget(const bool isQGadget); /** * Adds a nested class to this class. */ void addNestedClass(const Class &nestedClass); /** * Return the list of all nested classes. */ Class::List nestedClasses() const; /** * Return the name of the parent class name in a nested class. */ QString parentClassName() const; /** * Set the name of the parent class in a nested class. */ void setParentClassName(const QString &name); /** * Adds a declaration macro at the top of the class, like Q_PROPERTY(...) * or Q_INTERFACES(...). */ void addDeclarationMacro(const QString ¯o); /** * Returns the list of declaration macros added by addDeclarationMacro() */ QStringList declarationMacros() const; private: class Private; Private *d; }; class ClassList : public QList { public: /** * Sort the classes so that the result compiles, i.e. so that a class using another * (via member vars or via inheritance) is after it in the list. * * @param excludedClasses list of base classes which can be excluded from the search * for dependencies, usually because them come from underlying libraries. * All classes starting with Q are automatically excluded */ void sortByDependencies(const QStringList &excludedClasses = QStringList()); // maybe we could have a bool ignoreUnknownClasses, too, for people who write bugfree code... void sortAlphabetically(); void addClass(const Class &cl); QStringList classNames() const; const_iterator findClass(const QString &qualifiedName) const; }; } #endif libkode-master/code_generation/code.cpp000066400000000000000000000115601472623201100205240ustar00rootroot00000000000000/* This file is part of kdepim. Copyright (c) 2004 Cornelius Schumacher This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "code.h" using namespace KODE; static int s_defaultIndentation = 2; class Code::Private { public: Private() : mIndent(0) {} QString mText; int mIndent; }; Code::Code() : d(new Private) {} Code::Code(const Code &other) : d(new Private) { *d = *other.d; } Code::Code(int indent) : d(new Private) { d->mIndent = indent; } Code::~Code() { delete d; } Code &Code::operator=(const Code &other) { if (this == &other) return *this; *d = *other.d; return *this; } void Code::clear() { d->mIndent = 0; d->mText.clear(); } bool Code::isEmpty() const { return d->mText.isEmpty(); } void Code::setIndent(int indent) { d->mIndent = indent; } void Code::indent() { d->mIndent += s_defaultIndentation; } void Code::unindent() { d->mIndent -= s_defaultIndentation; if (d->mIndent < 0) d->mIndent = 0; } QString Code::text() const { return d->mText; } void Code::addLine(const QString &line) { d->mText += spaces(d->mIndent); d->mText += line; d->mText += QLatin1Char('\n'); } void Code::addLine(const char c) { d->mText += spaces(d->mIndent); d->mText += QLatin1Char(c); d->mText += QLatin1Char('\n'); } void Code::newLine() { d->mText += QLatin1Char('\n'); } QString Code::spaces(int count) { QString str; for (int i = 0; i < count; ++i) str += QLatin1Char(' '); return str; } void Code::addBlock(const QString &block) { QStringList lines = block.split(QLatin1String("\n")); if (!lines.isEmpty() && lines.last().isEmpty()) { lines.pop_back(); } QStringList::ConstIterator it; for (it = lines.constBegin(); it != lines.constEnd(); ++it) { if (!(*it).isEmpty()) d->mText += spaces(d->mIndent); d->mText += *it; d->mText += QLatin1Char('\n'); } } void Code::addBlock(const QString &block, int indent) { int tmp = d->mIndent; d->mIndent = indent; addBlock(block); d->mIndent = tmp; } void Code::addBlock(const Code &c) { addBlock(c.text()); } void Code::addWrappedText(const QString &txt) { int maxWidth = 80 - d->mIndent; int pos = 0; while (pos < txt.length()) { QString line = txt.mid(pos, maxWidth); addLine(line); pos += maxWidth; } } void Code::addFormattedText(const QString &text) { int maxWidth = 80 - d->mIndent; int lineLength = 0; QString line; #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) const QStringList words = text.split(QLatin1Char(' '), Qt::SkipEmptyParts); #else const QStringList words = text.split(QLatin1Char(' '), QString::SkipEmptyParts); #endif QStringList::ConstIterator it; for (it = words.constBegin(); it != words.constEnd(); ++it) { if ((*it).length() + lineLength >= maxWidth) { line = line.trimmed(); addLine(line); line.truncate(0); lineLength = 0; } int pos = (*it).indexOf(QLatin1String("\n")); if (pos != -1) { line += (*it).left(pos); line = line.trimmed(); addLine(line); line = (*it).mid(pos + 1) + QLatin1Char(' '); lineLength = (*it).length() - pos; } else { line += *it + QLatin1Char(' '); lineLength += (*it).length() + 1; } } line = line.trimmed(); addLine(line); } Code &Code::operator+=(const QString &str) { addLine(str); return *this; } Code &Code::operator+=(const QByteArray &str) { addLine(QString::fromLocal8Bit(str.data(), str.size())); return *this; } Code &Code::operator+=(const char *str) { addLine(QString::fromLocal8Bit(str)); return *this; } Code &Code::operator+=(const char c) { addLine(c); return *this; } Code &Code::operator+=(const Code &code) { d->mText += code.d->mText; return *this; } void Code::setDefaultIndentation(int indent) { s_defaultIndentation = indent; } int Code::defaultIndentation() { return s_defaultIndentation; } libkode-master/code_generation/code.h000066400000000000000000000105401472623201100201660ustar00rootroot00000000000000/* This file is part of kdepim. Copyright (c) 2004 Cornelius Schumacher This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KODE_CODE_H #define KODE_CODE_H #include #include namespace KODE { /** * This class encapsulates a code block. */ class KODE_EXPORT Code { public: /** * Creates a new code block. */ Code(); /** * Creates a new code block from @param other. */ Code(const Code &other); /** * Creates a new code block with the given @param indent. */ Code(int indent); /** * Destroys the code block. */ ~Code(); /** * Assignment operator. */ Code &operator=(const Code &other); /** * Clears all lines from the code block. */ void clear(); /** * Returns whether the code block is empty. */ bool isEmpty() const; /** * Sets the @param indent of the code block. */ void setIndent(int indent); /** * Indents the code block by one level. */ void indent(); /** * Unindents the code block by one level. */ void unindent(); /** * Returns the textual presentation of the code block. */ QString text() const; /** * Adds the given @param line to the code block. */ void addLine(const QString &line); /** * Adds the given @param line to the code block. */ void addLine(const char line); /** * Adds the given @param block to the code block. * The current indent will be prepended before every line of the block. */ void addBlock(const Code &block); /** * Adds the given @param block to the code block. * The current indent will be prepended before every line of the block. */ void addBlock(const QString &block); /** * Adds the given @param block with the given indent * to the code block. */ void addBlock(const QString &block, int indent); /** * Adds the given @param text to the code block and wrapps * it if it's too long. */ void addWrappedText(const QString &text); /** * Adds the given @param text to the code block and wrapps * it at word boundaries if it's too long. */ void addFormattedText(const QString &text); /** * Adds a new line to the code block. */ void newLine(); /** * Adds the given @param line to the code block * and appends a '\r\n' automatically. */ Code &operator+=(const QString &line); /** * Adds the given @param line to the code block * and appends a '\r\n' automatically. */ Code &operator+=(const QByteArray &line); /** * Adds the given @param line to the code block * and appends a '\r\n' automatically. */ Code &operator+=(const char *line); /** * Adds the given @param line to the code block * and appends a '\r\n' automatically. */ Code &operator+=(const char line); /** * Adds the given @param block to the code block. * @param block is supposed to be fully indented already * (otherwise, use addBlock) */ Code &operator+=(const Code &block); /** * Returns a string filled up with spaces, depending on * the level @param count and the indent value. */ static QString spaces(int count); /** * Sets the default indentation used by indent(). */ static void setDefaultIndentation(int indent); /** * Returns the default indentation used by indent(). */ static int defaultIndentation(); private: class Private; Private *d; }; } #endif libkode-master/code_generation/code_generation.pri000066400000000000000000000011711472623201100227440ustar00rootroot00000000000000HEADERS += \ $$PWD/class.h \ $$PWD/code.h \ $$PWD/enum.h \ $$PWD/file.h \ $$PWD/function.h \ $$PWD/include.h \ $$PWD/kode_export.h \ $$PWD/license.h \ $$PWD/membervariable.h \ $$PWD/namer.h \ $$PWD/printer.h \ $$PWD/statemachine.h \ $$PWD/style.h \ $$PWD/typedef.h \ $$PWD/variable.h SOURCES += \ $$PWD/class.cpp \ $$PWD/code.cpp \ $$PWD/enum.cpp \ $$PWD/file.cpp \ $$PWD/function.cpp \ $$PWD/include.cpp \ $$PWD/license.cpp \ $$PWD/membervariable.cpp \ $$PWD/namer.cpp \ $$PWD/printer.cpp \ $$PWD/statemachine.cpp \ $$PWD/style.cpp \ $$PWD/typedef.cpp \ $$PWD/variable.cpp libkode-master/code_generation/code_generation.pro000066400000000000000000000003661472623201100227570ustar00rootroot00000000000000TEMPLATE = lib CONFIG += staticlib TARGET = kode include(code_generation.pri) QT -= gui INCLUDEPATH += $${PWD} include($${PWD}/../variables.pri) DEFINES -= QT_NO_CAST_TO_ASCII QBA_NO_CAST_TO_VOID QBA_NO_CAST_TO_ASCII QT_NO_CAST_FROM_ASCII libkode-master/code_generation/enum.cpp000066400000000000000000000047141472623201100205610ustar00rootroot00000000000000/* This file is part of KDE. Copyright (c) 2005 Tobias Koenig This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "enum.h" #include "code.h" using namespace KODE; class Enum::Private { public: QString mName; QStringList mEnums; bool mCombinable = false; bool mIsQENUM = false; }; Enum::Enum() : d(new Private) {} Enum::Enum(const Enum &other) : d(new Private) { *d = *other.d; } Enum::Enum(const QString &name, const QStringList &enums, bool combinable) : d(new Private) { d->mName = name; d->mEnums = enums; d->mCombinable = combinable; } Enum::~Enum() { delete d; } Enum &Enum::operator=(const Enum &other) { if (this == &other) return *this; *d = *other.d; return *this; } QString Enum::name() const { return d->mName; } void Enum::printDeclaration(Code &code) const { code.addLine(QStringLiteral("enum %1 {").arg(d->mName)); code.indent(); auto last = (d->mEnums.count() - 1); for (int value = 0; value <= last; value++) { if (d->mCombinable) { if (value != last) code.addLine(QString::fromLatin1("%1 = %2,").arg(d->mEnums[value]).arg(1 << value)); else code.addLine(QString::fromLatin1("%1 = %2").arg(d->mEnums[value]).arg(1 << value)); } else { if (value != last) code.addLine(d->mEnums[value] + QLatin1String(", ")); else code.addLine(d->mEnums[value]); } } code.unindent(); code.addLine("};"); if (d->mIsQENUM) code.addLine(QStringLiteral("Q_ENUM(%1)").arg(d->mName)); code.newLine(); } void Enum::setIsQENUM(bool qenum) { d->mIsQENUM = qenum; } libkode-master/code_generation/enum.h000066400000000000000000000046301472623201100202230ustar00rootroot00000000000000/* This file is part of KDE. Copyright (c) 2005 Tobias Koenig This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KODE_ENUM_H #define KODE_ENUM_H #include #include namespace KODE { class Code; class KODE_EXPORT Enum { public: typedef QList List; /** * Creates a new enum. */ Enum(); /** * Creates a new enum from @param other. */ Enum(const Enum &other); /** * Creates a new enum with the given name and enum values. * * @param name The name of the enum. * @param enums The values of the enum. * @param combinable If true the integer associations will be a power of two, * so the enum flags will be combinable. */ Enum(const QString &name, const QStringList &enums, bool combinable = false); /** * Destroys the enum. */ ~Enum(); /** * Assignment operator. */ Enum &operator=(const Enum &other); /** * Return name of enum. */ QString name() const; /** * Prints the declaration of the enum to the code */ void printDeclaration(Code &code) const; /** * @brief setIsQENUM * This method can be used to mark enums to have a Q_ENUM(enumname) macro generated after the * declaration. If you add an enum with isQENUM set to a class make sure that the isQGadget * or the isQObject property of the class is set before code generation. * (The latter got set automatically if a signal or slot declaration to the class.) * @param qenum */ void setIsQENUM(bool qenum = true); private: class Private; Private *d; }; } #endif libkode-master/code_generation/file.cpp000066400000000000000000000135401472623201100205310ustar00rootroot00000000000000/* This file is part of kdepim. Copyright (c) 2004 Cornelius Schumacher This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "file.h" #include using namespace KODE; class File::Private { public: Private() : mProject() {} QString mHeaderFilename; QString mImplFilename; QString mNameSpace; QString mProject; QStringList mCopyrightStrings; License mLicense; QStringList mIncludes; Class::List mClasses; Variable::List mFileVariables; Function::List mFileFunctions; Enum::List mFileEnums; QStringList mExternCDeclarations; Code mFileCode; }; File::File() : d(new Private) {} File::File(const File &other) : d(new Private) { *d = *other.d; } File::~File() { delete d; } File &File::operator=(const File &other) { if (this == &other) return *this; *d = *other.d; return *this; } void File::setFilename(const QString &filename) { d->mImplFilename = filename + ".cpp"; d->mHeaderFilename = filename + ".h"; } void File::setImplementationFilename(const QString &filename) { d->mImplFilename = filename; } void File::setHeaderFilename(const QString &filename) { d->mHeaderFilename = filename; } QString File::filenameHeader() const { if (!d->mHeaderFilename.isEmpty()) return d->mHeaderFilename; if (!d->mClasses.isEmpty()) { QString className = d->mClasses[0].name(); return className.toLower() + ".h"; } return QString(); } QString File::filenameImplementation() const { if (!d->mImplFilename.isEmpty()) return d->mImplFilename; if (!d->mClasses.isEmpty()) { QString className = d->mClasses[0].name(); return className.toLower() + ".cpp"; } return QString(); } void File::setNameSpace(const QString &nameSpace) { d->mNameSpace = nameSpace; } QString File::nameSpace() const { return d->mNameSpace; } void File::setProject(const QString &project) { if (project.isEmpty()) return; d->mProject = project; } QString File::project() const { return d->mProject; } void File::addCopyright(int year, const QString &name, const QString &email) { QString str = "Copyright (c) " + QString::number(year) + ' ' + name + " <" + email + '>'; d->mCopyrightStrings.append(str); } QStringList File::copyrightStrings() const { return d->mCopyrightStrings; } void File::setLicense(const License &license) { d->mLicense = license; } License File::license() const { return d->mLicense; } void File::addInclude(const QString &_include) { QString include = _include; if (!include.endsWith(".h")) include.append(".h"); if (!d->mIncludes.contains(include)) d->mIncludes.append(include); } QStringList File::includes() const { return d->mIncludes; } void File::insertClass(const Class &newClass) { Q_ASSERT(!newClass.name().isEmpty()); Class::List::Iterator it; for (it = d->mClasses.begin(); it != d->mClasses.end(); ++it) { if ((*it).qualifiedName() == newClass.qualifiedName()) { // This happens often, probably due to usage of shared types // qDebug() << "WARNING: Already having class" << newClass.qualifiedName() << "in file" // << filenameHeader() << filenameImplementation(); it = d->mClasses.erase(it); d->mClasses.insert(it, newClass); return; } } d->mClasses.append(newClass); } Class::List File::classes() const { return d->mClasses; } bool File::hasClass(const QString &name) { Class::List::ConstIterator it; for (it = d->mClasses.constBegin(); it != d->mClasses.constEnd(); ++it) { if ((*it).name() == name) break; } return it != d->mClasses.constEnd(); } Class File::findClass(const QString &name) { Class::List::ConstIterator it; for (it = d->mClasses.constBegin(); it != d->mClasses.constEnd(); ++it) { if ((*it).name() == name) return *it; } return Class(); } void File::addFileVariable(const Variable &variable) { d->mFileVariables.append(variable); } Variable::List File::fileVariables() const { return d->mFileVariables; } void File::addFileFunction(const Function &function) { d->mFileFunctions.append(function); } Function::List File::fileFunctions() const { return d->mFileFunctions; } void File::addFileEnum(const Enum &enumValue) { d->mFileEnums.append(enumValue); } Enum::List File::fileEnums() const { return d->mFileEnums; } void File::addExternCDeclaration(const QString &externalCDeclaration) { d->mExternCDeclarations.append(externalCDeclaration); } QStringList File::externCDeclarations() const { return d->mExternCDeclarations; } void File::addFileCode(const Code &code) { d->mFileCode = code; } Code File::fileCode() const { return d->mFileCode; } void File::clearClasses() { d->mClasses.clear(); } void File::clearFileFunctions() { d->mFileFunctions.clear(); } void File::clearFileVariables() { d->mFileVariables.clear(); } void File::clearCode() { clearClasses(); clearFileFunctions(); clearFileVariables(); } libkode-master/code_generation/file.h000066400000000000000000000120331472623201100201720ustar00rootroot00000000000000/* This file is part of kdepim. Copyright (c) 2004 Cornelius Schumacher This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KODE_FILE_H #define KODE_FILE_H #include "class.h" #include "code.h" #include "license.h" #include "variable.h" #include namespace KODE { /** * This class represents a file. */ class KODE_EXPORT File { public: /** * Creates a new file. */ File(); /** * Creates a new file from @param other. */ File(const File &other); /** * Destroys the file. */ ~File(); /** * Assignment operator. */ File &operator=(const File &other); /** * Sets the filenames of both the .h and .cpp file. * The extensions will be automatically added. */ void setFilename(const QString &baseName); /** * Sets the @param filename of the cpp file. */ void setImplementationFilename(const QString &filename); /** * Sets the @param filename of the header file. */ void setHeaderFilename(const QString &filename); /** Return filename of header file. */ QString filenameHeader() const; /** Return filename of implementation file. */ QString filenameImplementation() const; /** * Sets the name space of the file. */ void setNameSpace(const QString &nameSpace); /** * Returns the name space of the file. */ QString nameSpace() const; /** * Sets the @param project name of the file. */ void setProject(const QString &project); /** * Returns the project name of the file. */ QString project() const; /** * Add copyright statement to the file. * * @param year The year of participation. * @param name The name of the author. * @param email The email address of the author. */ void addCopyright(int year, const QString &name, const QString &email); /** * Returns the list of all copyright statements. */ QStringList copyrightStrings() const; /** * Sets the @param license of the file. */ void setLicense(const License &license); /** * Returns the license of the file. */ License license() const; /** * Adds an include to the file. */ void addInclude(const QString &include); /** * Returns the list of all includes. */ QStringList includes() const; /** * Inserts a class to the file. */ void insertClass(const Class &newClass); /** * Returns a list of all classes. */ Class::List classes() const; /** * Returns whether the file contains a class * with the given @param name. */ bool hasClass(const QString &name); /** * Returns the class with the given @param name. */ Class findClass(const QString &name); /** * Removes all classes from the file. */ void clearClasses(); /** * Removes all file functions from the file. */ void clearFileFunctions(); /** * Removes all file variables from the file. */ void clearFileVariables(); /** * Removes all file code from the file. */ void clearCode(); /** * Adds a file @param variable to the file. */ void addFileVariable(const Variable &variable); /** * Returns the list of all file variables. */ Variable::List fileVariables() const; /** * Adds a file @param function to the file. */ void addFileFunction(const Function &function); /** * Returns the list of all file functions. */ Function::List fileFunctions() const; /** * Adds a file enum to the file. */ void addFileEnum(const Enum &enumValue); /** * Returns the list of all file enums. */ Enum::List fileEnums() const; /** * Adds an external C declaration to the file. */ void addExternCDeclaration(const QString &externalCDeclaration); /** * Returns the list of all external C declarations. */ QStringList externCDeclarations() const; /** * Adds a file @param code block to the file. */ void addFileCode(const Code &code); /** * Returns the file code block. */ Code fileCode() const; private: class Private; Private *d; }; } #endif libkode-master/code_generation/function.cpp000066400000000000000000000133671472623201100214460ustar00rootroot00000000000000/* This file is part of kdepim. Copyright (c) 2004 Cornelius Schumacher Copyright (c) 2009 David Faure This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include "function.h" using namespace KODE; class Function::Argument::ArgumentPrivate { public: QString declaration; QString defaultArgument; }; Function::Argument::Argument(const QString &declaration, const QString &defaultArgument) : d(new ArgumentPrivate) { d->declaration = declaration; d->defaultArgument = defaultArgument; } Function::Argument::Argument(const Function::Argument &other) : d(new ArgumentPrivate) { *d = *other.d; } QString Function::Argument::headerDeclaration() const { if (d->defaultArgument.isEmpty()) { return d->declaration; } else { return d->declaration + QLatin1String(" = ") + d->defaultArgument; } } QString Function::Argument::bodyDeclaration() const { return d->declaration; } Function::Argument &Function::Argument::operator=(const Function::Argument &other) { if (this == &other) return *this; *d = *other.d; return *this; } Function::Argument::~Argument() { delete d; } class Function::FunctionPrivate { public: int mAccess = Public; bool mIsConst = false; bool mIsStatic = false; bool mIsExplicit = false; QString mReturnType; QString mName; Argument::List mArguments; QStringList mInitializers; QString mBody; QString mDocs; Function::VirtualMode mVirtualMode = NotVirtual; }; Function::Function() : d(new FunctionPrivate) {} Function::Function(const Function &other) : d(new FunctionPrivate) { *d = *other.d; } Function::Function(const QString &name, const QString &returnType, int access, bool isStatic) : d(new FunctionPrivate) { d->mAccess = access; d->mIsStatic = isStatic; d->mName = name; setReturnType(returnType); } Function::~Function() { delete d; } Function &Function::operator=(const Function &other) { if (this == &other) return *this; *d = *other.d; return *this; } void Function::setConst(bool isConst) { d->mIsConst = isConst; } bool Function::isConst() const { return d->mIsConst; } void Function::setStatic(bool isStatic) { d->mIsStatic = isStatic; } bool Function::isStatic() const { return d->mIsStatic; } void Function::addArgument(const Function::Argument &argument) { d->mArguments.append(argument); } void Function::addArgument(const QString &argument) { d->mArguments.append(Argument(argument)); } void Function::setArgumentString(const QString &argumentString) { d->mArguments.clear(); const QStringList arguments = argumentString.split(QLatin1String(",")); QStringList::ConstIterator it; for (it = arguments.constBegin(); it != arguments.constEnd(); ++it) { addArgument(*it); } } Function::Argument::List Function::arguments() const { return d->mArguments; } void Function::addInitializer(const QString &initializer) { d->mInitializers.append(initializer); } QStringList Function::initializers() const { return d->mInitializers; } void Function::setBody(const QString &body) { d->mBody = body; } void Function::setBody(const Code &body) { d->mBody = body.text(); } void Function::addBodyLine(const QString &bodyLine) { d->mBody.append(bodyLine); if (bodyLine.right(1) != QLatin1String("\n")) d->mBody.append(QLatin1Char('\n')); } QString Function::body() const { return d->mBody; } void Function::setAccess(int access) { d->mAccess = access; } int Function::access() const { return d->mAccess; } QString Function::accessAsString() const { QString access; if (d->mAccess & Public) access = QLatin1String("public"); if (d->mAccess & Protected) access = QLatin1String("protected"); if (d->mAccess & Private) access = QLatin1String("private"); if (d->mAccess & Signal) access = QLatin1String("Q_SIGNALS"); if (d->mAccess & Slot) access += QLatin1String(" Q_SLOTS"); return access; } void Function::setReturnType(const QString &returnType) { Q_ASSERT(returnType != QLatin1String("*")); d->mReturnType = returnType; } QString Function::returnType() const { return d->mReturnType; } void Function::setName(const QString &name) { d->mName = name; } QString Function::name() const { return d->mName; } void Function::setDocs(const QString &docs) { d->mDocs = docs; } QString Function::docs() const { return d->mDocs; } bool Function::isExplicit() const { return d->mIsExplicit; } void Function::setExplicit(bool isExplicit) { d->mIsExplicit = isExplicit; } bool Function::hasArguments() const { return !d->mArguments.isEmpty(); } void Function::setVirtualMode(Function::VirtualMode v) { d->mVirtualMode = v; } Function::VirtualMode Function::virtualMode() const { return d->mVirtualMode; } QDebug operator<<(QDebug dbg, const Function &func) { dbg << func.name(); return dbg; } libkode-master/code_generation/function.h000066400000000000000000000136611472623201100211100ustar00rootroot00000000000000/* This file is part of kdepim. Copyright (c) 2004 Cornelius Schumacher Copyright (c) 2009 David Faure This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KODE_FUNCTION_H #define KODE_FUNCTION_H #include #include "code.h" #include namespace KODE { /** * This class represents a function. */ class KODE_EXPORT Function { public: class Argument { public: typedef QList List; Argument(const QString &declaration, const QString &defaultArgument = QString()); Argument(const Argument &other); ~Argument(); Argument &operator=(const Argument &other); QString headerDeclaration() const; QString bodyDeclaration() const; private: class ArgumentPrivate; ArgumentPrivate *d; }; typedef QList List; /** * The different access specifiers. * * @li Public - Public access * @li Protected - Protected access * @li Private - Private access * @li Signal - Qt Signal * @li Slot - Qt Slot */ enum AccessSpecifier { Public = 1, Protected = 2, Private = 4, Signal = 8, Slot = 16 }; /** * Creates a new function. */ Function(); /** * Creates a new function from @param other. */ Function(const Function &other); /** * Creates a new function with the given @param name. * * @param returnType The return type. * @param access The access type (@see AccessSpecifier). * @param isStatic If true, the function is marked as static. */ Function(const QString &name, const QString &returnType = QString(), int access = Public, bool isStatic = false); /** * Destroys the function. */ ~Function(); /** * Assignment operator. */ Function &operator=(const Function &other); /** * Sets the @param name of the function. */ void setName(const QString &name); /** * Returns the name of the function. */ QString name() const; /** * Sets the return type of the function. */ void setReturnType(const QString &returnType); /** * Returns the return type of the function. */ QString returnType() const; /** * Sets whether the function is marked as const. */ void setConst(bool isConst); /** * Returns whether the function is marked as const. */ bool isConst() const; /** * Sets whether the function is marked as static. */ void setStatic(bool isStatic); /** * Returns whether the function is marked as static. */ bool isStatic() const; enum VirtualMode { NotVirtual, Virtual, PureVirtual, Override, Final }; /** * Sets whether the function is marked as virtual or pure virtual. */ void setVirtualMode(VirtualMode v); /** * Returns whether the function is marked as virtual or pure virtual. */ VirtualMode virtualMode() const; /** * Adds an @param argument to the function. */ void addArgument(const Function::Argument &argument); /** * Adds an @param argument to the function. */ void addArgument(const QString &argument); /** * Sets the complete argument string of the function. * This method does not support default values currently. */ void setArgumentString(const QString &argumentString); /** * Returns the list of all arguments. * @param forImplementation if true, default values are omitted */ Argument::List arguments() const; /** * @return whether the function has any arguments */ bool hasArguments() const; /** * Adds an initializer to the function. */ void addInitializer(const QString &initializer); /** * Returns the list of all initializers. */ QStringList initializers() const; /** * Sets the @param body code of the function. */ void setBody(const QString &body); /** * Sets the @param body code of the function. */ void setBody(const Code &body); /** * Adds a @param line to the body code of the function. */ void addBodyLine(const QString &line); /** * Returns the body code of the function. */ QString body() const; /** * Sets the access @param specifier of the function. */ void setAccess(int specifier); /** * Returns the access specifier of the function. */ int access() const; /** * Returns access specifier of the function as string. */ QString accessAsString() const; /** * Sets the @param documentation of the function. */ void setDocs(const QString &documentation); /** * Returns the documentation of the function. */ QString docs() const; /** * Sets whether the function is marked with explicit specifier. */ void setExplicit(bool isExplicit = true); /** * Returns whether the function is marked with explicit specifier. */ bool isExplicit() const; private: class FunctionPrivate; FunctionPrivate *d; }; } QDebug operator<<(QDebug dbg, const KODE::Function &func); #endif libkode-master/code_generation/include.cpp000066400000000000000000000022411472623201100212310ustar00rootroot00000000000000/* This file is part of libkode. Copyright (c) 2020 Miklos Marton This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "include.h" using namespace KODE; Include::Include(const QString &fileName, Include::IncludeType type_) : includeFileName(fileName), type(type_) { } bool Include::operator==(const Include &other) const { return type == other.type && includeFileName == other.includeFileName; } libkode-master/code_generation/include.h000066400000000000000000000025321472623201100207010ustar00rootroot00000000000000/* This file is part of libkode. Copyright (c) 2020 Miklos Marton This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef INCLUDE_H #define INCLUDE_H #include #include #include namespace KODE { class KODE_EXPORT Include { public: enum IncludeType { Global, Relative }; Include() = default; Include(const QString &fileName, IncludeType type_ = Global); bool operator==(const Include &other) const; QString includeFileName; IncludeType type = Global; typedef QVector List; }; } // end namespace KODE #endif // INCLUDE_H libkode-master/code_generation/kode_export.h000066400000000000000000000002151472623201100215750ustar00rootroot00000000000000/* We use static libs, no need for export macros */ #define KODE_EXPORT #define KXMLCOMMON_EXPORT #define KWSDL_EXPORT #define SCHEMA_EXPORT libkode-master/code_generation/license.cpp000066400000000000000000000144121472623201100212330ustar00rootroot00000000000000/* This file is part of kdepim. Copyright (c) 2004 Cornelius Schumacher This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "license.h" using namespace KODE; class License::Private { public: Private() : mType(License::NoLicense), mQtException(false) {} Type mType; bool mQtException; }; License::License() : d(new Private) {} License::License(const License &other) : d(new Private) { *d = *other.d; } License::License(Type type) : d(new Private) { d->mType = type; } License::~License() { delete d; } License &License::operator=(const License &other) { if (this == &other) return *this; *d = *other.d; return *this; } void License::setQtException(bool v) { d->mQtException = v; } QString License::text() const { QString txt; switch (d->mType) { case GPL: txt += "This program is free software; you can redistribute it and/or modify\n" "it under the terms of the GNU General Public License as published by\n" "the Free Software Foundation; either version 2 of the License, or\n" "(at your option) any later version.\n" "\n" "This program is distributed in the hope that it will be useful,\n" "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" "GNU General Public License for more details.\n" "\n" "You should have received a copy of the GNU General Public License\n" "along with this program; if not, write to the Free Software\n" "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,\n" "USA.\n"; if (d->mQtException) { txt += '\n'; txt += "As a special exception, permission is given to link this program\n" "with any edition of Qt, and distribute the resulting executable,\n" "without including the source code for Qt in the source distribution.\n"; } break; case LGPL: txt += "This library is free software; you can redistribute it and/or\n" "modify it under the terms of the GNU Library General Public\n" "License as published by the Free Software Foundation; either\n" "version 2 of the License, or (at your option) any later version.\n" "\n" "This library is distributed in the hope that it will be useful,\n" "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n" "Library General Public License for more details.\n" "\n" "You should have received a copy of the GNU Library General Public License\n" "along with this library; see the file COPYING.LIB. If not, write to\n" "the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,\n" "Boston, MA 02110-1301, USA.\n"; break; case BSD: txt += "Permission is hereby granted, free of charge, to any person obtaining\n" "a copy of this software and associated documentation files (the\n" "\"Software\"), to deal in the Software without restriction, including\n" "without limitation the rights to use, copy, modify, merge, publish,\n" "distribute, sublicense, and/or sell copies of the Software, and to\n" "permit persons to whom the Software is furnished to do so, subject to\n" "the following conditions:\n" "\n" "The above copyright notice and this permission notice shall be\n" "included in all copies or substantial portions of the Software.\n" "\n" "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n" "EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n" "MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\n" "IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n" "OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,\n" "ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n" "OTHER DEALINGS IN THE SOFTWARE."; break; case GeneratedNoRestriction: txt += "You may use and relicense this generated file without restriction."; default: break; } return txt; } License::Type License::type() const { return d->mType; } QString License::typeName() const { QMetaEnum metaEnum = QMetaEnum::fromType(); return metaEnum.valueToKey(d->mType); } License License::licenseByTypeName(const QString &typeName) { bool result; QMetaEnum metaEnum = QMetaEnum::fromType(); License::Type license_enum = static_cast( metaEnum.keyToValue(typeName.toLatin1().constData(), &result)); if (result) { return License(license_enum); } else { return License(License::Type::NoLicense); } } QStringList License::getSupportedLicenses() { QStringList result; QMetaEnum metaEnum = QMetaEnum::fromType(); result.reserve(metaEnum.keyCount()); for (int i = 0; i < metaEnum.keyCount(); i++) { result << metaEnum.valueToKey(i); } return result; } libkode-master/code_generation/license.h000066400000000000000000000057251472623201100207070ustar00rootroot00000000000000/* This file is part of kdepim. Copyright (c) 2004 Cornelius Schumacher This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KODE_LICENSE_H #define KODE_LICENSE_H #include #include #include namespace KODE { /** * @brief Represent a license clause. * Use this class to setup a license clause for your generated file. * * @author Cornelius Schumacher */ class KODE_EXPORT License { Q_GADGET public: /** * Possible types of licenses * @li GPL - The GNU General Public License. * @li LGPL - The GNU Lesser/Library General Public License. * @li BSD - Berkeley Software Distribution * @li GeneratedNoRestriction - Generated code with no restrictions. * @li NoLicense - No license specified */ enum Type { GPL, LGPL, BSD, GeneratedNoRestriction, NoLicense }; Q_ENUM(Type) /** * Creates a new license. */ License(); /** * Create a new license of the given @param type. */ License(Type type); /** * Creates a new license from @param other. */ License(const License &other); /** * Destroys the license. */ ~License(); /** * Assignment operator. */ License &operator=(const License &other); /** * Sets whether a Qt expection should be appended to * the license statement. * * This is only useful for Qt3 based code. */ void setQtException(bool useQtException); /** * Returns the textual presentation of the license. */ QString text() const; /** * Returns type of license. */ Type type() const; /** * Return license name. * @return name of license */ QString typeName() const; /** * Returns license Type element by name. If there no such license, * NoLicense will be returned * @param license_string Name of license * @return one of Type elements */ static License licenseByTypeName(const QString &typeName); /** * Returns list of supported licenses * @return vector of license names */ static QStringList getSupportedLicenses(); private: class Private; Private *d; }; } #endif libkode-master/code_generation/membervariable.cpp000066400000000000000000000041311472623201100225630ustar00rootroot00000000000000/* This file is part of kdepim. Copyright (c) 2004 Cornelius Schumacher This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "membervariable.h" #include "style.h" using namespace KODE; class MemberVariable::Private { public: }; MemberVariable::MemberVariable() : Variable(), d(nullptr) {} MemberVariable::MemberVariable(const MemberVariable &other) : Variable(other), d(nullptr) { // *d = *other.d; } MemberVariable::MemberVariable(const QString &name, const QString &type, bool isStatic) : Variable(name, type, isStatic), d(nullptr) { setName(memberVariableName(name)); } MemberVariable::~MemberVariable() { delete d; } MemberVariable &MemberVariable::operator=(const MemberVariable &other) { if (this == &other) return *this; Variable::operator=(other); // *d = *other.d; return *this; } QString MemberVariable::memberVariableName(const QString &name) { QString n; if (name.isEmpty()) { n = QLatin1String("mUndefined"); } else if (name.length() >= 2 && name[0] == QLatin1Char('m') && (name[1].toUpper() == name[1])) { n = name; } else if (name == QLatin1String("q") || name == QLatin1String("d")) { n = name; } else { n = QLatin1String("m"); n += name[0].toUpper(); n += name.mid(1); } return Style::makeIdentifier(n); } libkode-master/code_generation/membervariable.h000066400000000000000000000043441472623201100222360ustar00rootroot00000000000000/* This file is part of kdepim. Copyright (c) 2004 Cornelius Schumacher This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KODE_MEMBERVARIABLE_H #define KODE_MEMBERVARIABLE_H #include #include #include "variable.h" #include namespace KODE { /** * This class represents a member variable. * * It's basically a @see Variable with a * special formatted name. */ class KODE_EXPORT MemberVariable : public Variable { public: typedef QList List; /** * Creates a new member variable. */ MemberVariable(); /** * Creates a new member variable from @param other. */ MemberVariable(const MemberVariable &other); /** * Creates a new member variable of the given @param type * and with the given @param name. * * @param isStatic If true the variable is marked as static. */ MemberVariable(const QString &name, const QString &type, bool isStatic = false); /** * Destroys the member variable. */ ~MemberVariable(); /** * Assignment operator. */ MemberVariable &operator=(const MemberVariable &other); /** * Returns the name that will be used for a member variable. * This is the same result as creating a MemberVariable(inputName, someType) and extracting the * name() afterwards. */ static QString memberVariableName(const QString &inputName); private: class Private; Private *d; }; } #endif libkode-master/code_generation/namer.cpp000066400000000000000000000232541472623201100207170ustar00rootroot00000000000000/* This file is part of KDE. Copyright (c) 2004,2010 Cornelius Schumacher This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "namer.h" #include "style.h" #include QStringList Namer::m_reservedKeywords = QStringList() << "alignas" << "alignof" << "and" << "and_eq" << "asm" << "atomic_cancel" << "atomic_commit" << "atomic_noexcept" << "audit" << "auto" << "axiom" << "bitand" << "bitor" << "bool" << "break" << "case" << "catch" << "char" << "char16_t" << "char32_t" << "class" << "co_await" << "co_return" << "co_yield" << "compl" << "concept" << "const" << "const_cast" << "constexpr" << "continue" << "decltype" << "default" << "define" << "defined" << "delete" << "do" << "double" << "dynamic_cast" << "elif" << "else" << "endif" << "enum" << "error" << "explicit" << "export" << "extern" << "false" << "final" << "float" << "for" << "friend" << "goto" << "if" << "ifdef" << "ifndef" << "import" << "include" << "inline" << "int" << "line" << "long" << "module" << "mutable" << "namespace" << "new" << "noexcept" << "not" << "not_eq" << "nullptr" << "operator" << "or" << "or_eq" << "override" << "pragma" << "private" << "protected" << "public" << "reflexpr" << "register" << "reinterpret_cast" << "requires" << "return" << "short" << "signals" << "signed" << "sizeof" << "slots" << "static" << "static_assert" << "static_cast" << "struct" << "switch" << "synchronized" << "template" << "this" << "thread_local" << "throw" << "transaction_safe" << "transaction_safe_dynamic" << "true" << "try" << "typedef" << "typeid" << "typename" << "undef" << "union" << "unsigned" << "using" << "virtual" << "void" << "volatile" << "wchar_t" << "while" << "xor" << "xor_eq"; QString Namer::upperFirst(const QString &str) { return KODE::Style::upperFirst(str); } QString Namer::lowerFirst(const QString &str) { return KODE::Style::lowerFirst(str); } QString Namer::getClassName(const QString &elementName) { QString name; const auto parts = removeInvalidCharacters(elementName).split("_"); for (const QString &part : parts) { name += upperFirst(part); } return name; } QString Namer::getAccessor(const QString &elementName) { return substituteKeywords(lowerFirst(getClassName(elementName))); } QString Namer::getListAccessor(const QString &elementName) { return QString("%1List").arg(lowerFirst(getClassName(elementName))); } QString Namer::getMutator(const QString &elementName) { return "set" + getClassName(elementName); } QString Namer::removeInvalidCharacters(const QString &name) { QString ret = name; return ret.replace(QRegularExpression("[\\;\\-\\:\\,\\+\\*\\/\\<\\>\\|]"), "_"); } QString Namer::substituteKeywords(const QString &name) { if (m_reservedKeywords.contains(name)) { QString ret = name; return ret.append("_"); } return name; } QString Namer::sanitize(const QString &name) { return substituteKeywords(removeInvalidCharacters(name)); } libkode-master/code_generation/namer.h000066400000000000000000000041501472623201100203560ustar00rootroot00000000000000/* This file is part of KDE. Copyright (c) 2010 Cornelius Schumacher This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef NAMER_H #define NAMER_H #include class Namer { public: static QString getClassName(const QString &); static QString getAccessor(const QString &); static QString getListAccessor(const QString &); static QString getMutator(const QString &); /** * Replaces the characters which are forbidden * in the C type/varaible names with an underscore (_) * in the @param name. */ static QString removeInvalidCharacters(const QString &name); /** * If the @param name is a reserved C/C++/Qt keyword it suffixes * with an underscore (_) */ static QString substituteKeywords(const QString &name); /** * Returns a new version of @param name converted to a format * which could be compiled to a valid C type or variable name. * * The sanitization includes: * - If the given string is a reserved keyword it will be * suffixed with and underscore (_) * - The non valid characters will be replaced with an * underscore */ static QString sanitize(const QString &name); protected: static QString upperFirst(const QString &str); static QString lowerFirst(const QString &str); private: static QStringList m_reservedKeywords; }; #endif libkode-master/code_generation/printer.cpp000066400000000000000000000742251472623201100213040ustar00rootroot00000000000000/* This file is part of kdepim. Copyright (c) 2004 Cornelius Schumacher Copyright (c) 2010 David Faure This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) # include #endif #include #include #include #include "printer.h" using namespace KODE; class Printer::Private { public: Private(Printer *parent) : mParent(parent) {} void addLabel(Code &code, const QString &label); QString classHeader(const Class &classObject, bool publicMembers, bool nestedClass = false); QString classImplementation(const Class &classObject, bool nestedClass = false); void addFunctionHeaders(Code &code, const Function::List &functions, const QString &className, int access); QString formatType(const QString &type) const; Printer *mParent; Style mStyle; bool mCreationWarning = false; bool mLabelsDefineIndent = true; bool mIndentLabels = true; QString mGenerator = QStringLiteral("libkode"); QString mOutputDirectory; QString mSourceFile; QStringList mStatementsAfterIncludes; /** * @brief printCodeIntoFile * Writes the string passed through the code parameter to the file referenced * by the file parameter in the case if it differs from the content of the file pointed by the * file parameter. * @param code reference to a Code object which contents needs to be printed * @param file the target file in unopened state with filename set */ void printCodeIntoFile(const Code &code, QFile *file); }; void Printer::Private::addLabel(Code &code, const QString &label) { if (!mIndentLabels) code.unindent(); code += label; if (!mIndentLabels) code.indent(); } QString Printer::Private::formatType(const QString &type) const { QString s = type; if (s.endsWith('*') || s.endsWith('&')) { if (s.at(s.length() - 2) != ' ') { // Turn "Foo*" into "Foo *" for readability s.insert(s.length() - 1, ' '); } } else { s += ' '; } return s; } QString Printer::Private::classHeader(const Class &classObject, bool publicMembers, bool nestedClass) { Code code; int numNamespaces = 0; if (!classObject.nameSpace().isEmpty()) { const QStringList nsList = classObject.nameSpace().split("::"); Q_FOREACH (const QString &ns, nsList) { code += "namespace " + ns + " {"; code.indent(); ++numNamespaces; } } if (nestedClass) code.indent(); if (!classObject.docs().isEmpty()) { code += "/**"; code.indent(); code.addFormattedText(classObject.docs()); code.unindent(); code += " */"; } QString txt = "class "; if (!classObject.exportDeclaration().isEmpty()) { txt += classObject.exportDeclaration().toUpper() + "_EXPORT "; } txt += classObject.name(); Class::List baseClasses = classObject.baseClasses(); if (!baseClasses.isEmpty()) { txt += " : "; Class::List::ConstIterator it; for (it = baseClasses.constBegin(); it != baseClasses.constEnd(); ++it) { Class bc = *it; if (it != baseClasses.constBegin()) txt += ", "; txt += "public "; if (!bc.nameSpace().isEmpty()) txt += bc.nameSpace() + "::"; txt += bc.name(); } } code += txt; if (nestedClass) { code.indent(); code += '{'; } else { code += '{'; // We always want to indent here; so that Q_OBJECT and enums etc. are indented. // However with mIndentLabels=false, we'll unindent before printing out "public:". code.indent(); } if (classObject.isQObject()) { code += "Q_OBJECT"; code.newLine(); } else { if (classObject.isQGadget()) { code += "Q_GADGET"; code.newLine(); } } Q_FOREACH (const QString &declMacro, classObject.declarationMacros()) { code += declMacro; code.newLine(); } Class::List nestedClasses = classObject.nestedClasses(); // Generate nestedclasses if (!classObject.nestedClasses().isEmpty()) { addLabel(code, "public:"); Class::List::ConstIterator it, itEnd = nestedClasses.constEnd(); for (it = nestedClasses.constBegin(); it != itEnd; ++it) { code += classHeader((*it), false, true); } code.newLine(); } Typedef::List typedefs = classObject.typedefs(); if (typedefs.count() > 0) { addLabel(code, "public:"); if (mLabelsDefineIndent) code.indent(); Typedef::List::ConstIterator it; for (it = typedefs.constBegin(); it != typedefs.constEnd(); ++it) code += (*it).declaration(); if (mLabelsDefineIndent) code.unindent(); code.newLine(); } Enum::List enums = classObject.enums(); if (enums.count() > 0) { addLabel(code, "public:"); if (mLabelsDefineIndent) code.indent(); Enum::List::ConstIterator it; for (it = enums.constBegin(); it != enums.constEnd(); ++it) (*it).printDeclaration(code); if (mLabelsDefineIndent) code.unindent(); code.newLine(); } Function::List functions = classObject.functions(); addFunctionHeaders(code, functions, classObject.name(), Function::Public); if (classObject.canBeCopied() && classObject.useDPointer() && !classObject.memberVariables().isEmpty()) { Function cc(classObject.name()); cc.addArgument("const " + classObject.name() + '&'); Function op("operator=", classObject.name() + '&'); op.addArgument("const " + classObject.name() + '&'); Function::List list; list << cc << op; addFunctionHeaders(code, list, classObject.name(), Function::Public); } addFunctionHeaders(code, functions, classObject.name(), Function::Public | Function::Slot); addFunctionHeaders(code, functions, classObject.name(), Function::Signal); addFunctionHeaders(code, functions, classObject.name(), Function::Protected); addFunctionHeaders(code, functions, classObject.name(), Function::Protected | Function::Slot); addFunctionHeaders(code, functions, classObject.name(), Function::Private); addFunctionHeaders(code, functions, classObject.name(), Function::Private | Function::Slot); if (!classObject.memberVariables().isEmpty()) { Function::List::ConstIterator it; // Do we have any private function? bool hasPrivateFunc = false; bool hasPrivateSlot = false; for (it = functions.constBegin(); it != functions.constEnd(); ++it) { if ((*it).access() == Function::Private) { hasPrivateFunc = true; } else if ((*it).access() == (Function::Private | Function::Slot)) { hasPrivateSlot = true; } } if (publicMembers) addLabel(code, "public:"); else if (!hasPrivateFunc || hasPrivateSlot) addLabel(code, "private:"); if (mLabelsDefineIndent) code.indent(); if (classObject.useDPointer() && !classObject.memberVariables().isEmpty()) { code += "class PrivateDPtr;"; if (classObject.useSharedData()) code += "QSharedDataPointer " + classObject.dPointerName() + ";"; else code += "PrivateDPtr *" + classObject.dPointerName() + ";"; } else { MemberVariable::List variables = classObject.memberVariables(); MemberVariable::List::ConstIterator it2; for (it2 = variables.constBegin(); it2 != variables.constEnd(); ++it2) { MemberVariable v = *it2; QString decl; if (v.isStatic()) decl += "static "; decl += formatType(v.type()); decl += v.name() + ';'; code += decl; } } if (mLabelsDefineIndent) code.unindent(); } code.unindent(); code += "};"; for (int i = 0; i < numNamespaces; ++i) { code.unindent(); code += "} // namespace end"; } return code.text(); } QString Printer::Private::classImplementation(const Class &classObject, bool nestedClass) { Code code; bool needNewLine = false; QString functionClassName = classObject.name(); if (nestedClass) functionClassName.prepend(classObject.parentClassName() + QLatin1String("::")); else if (!classObject.nameSpace().isEmpty()) functionClassName.prepend(classObject.nameSpace() + QLatin1String("::")); // Generate private class if (classObject.useDPointer() && !classObject.memberVariables().isEmpty()) { Class privateClass(functionClassName + "::PrivateDPtr"); if (classObject.useSharedData()) { privateClass.addBaseClass(Class("QSharedData")); } MemberVariable::List vars = classObject.memberVariables(); MemberVariable::List::ConstIterator it; Function ctor("PrivateDPtr"); bool hasInitializers = false; for (it = vars.constBegin(); it != vars.constEnd(); ++it) { const MemberVariable v = *it; privateClass.addMemberVariable(v); if (!v.initializer().isEmpty()) { ctor.addInitializer(v.name() + '(' + v.initializer() + ')'); hasInitializers = true; } } if (hasInitializers) privateClass.addFunction(ctor); code += classHeader(privateClass, true /*publicMembers*/); if (hasInitializers) code += classImplementation(privateClass); } // Generate static vars MemberVariable::List vars = classObject.memberVariables(); MemberVariable::List::ConstIterator itV; for (itV = vars.constBegin(); itV != vars.constEnd(); ++itV) { const MemberVariable v = *itV; if (!v.isStatic()) continue; // ## I thought the static int foo = 42; syntax was not portable? code += v.type() + functionClassName + "::" + v.name() + " = " + v.initializer() + ';'; needNewLine = true; } if (needNewLine) code.newLine(); Function::List functions = classObject.functions(); Function::List::ConstIterator it; for (it = functions.constBegin(); it != functions.constEnd(); ++it) { Function f = *it; // Omit signals if (f.access() == Function::Signal) continue; // Omit pure virtuals without a body if (f.virtualMode() == Function::PureVirtual && f.body().isEmpty()) continue; code += mParent->functionSignature(f, functionClassName, true); QStringList inits = f.initializers(); if (classObject.useDPointer() && !classObject.memberVariables().isEmpty() && f.name() == classObject.name()) { inits.append(classObject.dPointerName() + "(new PrivateDPtr)"); } if (!classObject.useDPointer() && f.name() == classObject.name() && f.arguments().isEmpty()) { // Default constructor: add initializers for variables for (itV = vars.constBegin(); itV != vars.constEnd(); ++itV) { const MemberVariable v = *itV; if (!v.initializer().isEmpty()) { inits.append(v.name() + '(' + v.initializer() + ')'); } } } if (!inits.isEmpty()) { code.indent(); code += ": " + inits.join(", "); code.unindent(); } code += '{'; code.addBlock(f.body(), Code::defaultIndentation()); if (classObject.useDPointer() && !classObject.useSharedData() && !classObject.memberVariables().isEmpty() && f.name() == '~' + classObject.name()) { // Delete d pointer code.newLine(); code.indent(); code += "delete " + classObject.dPointerName() + ";"; code += classObject.dPointerName() + " = nullptr;"; code.unindent(); } code += '}'; code.newLine(); } if (classObject.useDPointer() && classObject.canBeCopied() && !classObject.memberVariables().isEmpty()) { // print copy constructor Function cc(classObject.name()); cc.addArgument("const " + functionClassName + "& other"); Code body; if (!classObject.useSharedData()) { body += classObject.dPointerName() + " = new PrivateDPtr;"; body += "*" + classObject.dPointerName() + " = *other." + classObject.dPointerName() + ";"; } cc.setBody(body); code += mParent->functionSignature(cc, functionClassName, true); // call copy constructor of base classes QStringList list; Class::List baseClasses = classObject.baseClasses(); for (int i = 0; i < baseClasses.count(); ++i) { list.append(baseClasses[i].name() + "( other )"); } if (classObject.useSharedData()) { list.append(classObject.dPointerName() + "( other." + classObject.dPointerName() + " )"); } if (!list.isEmpty()) { code.indent(); code += ": " + list.join(", "); code.unindent(); } code += '{'; code.addBlock(cc.body(), Code::defaultIndentation()); code += '}'; code.newLine(); // print assignment operator Function op("operator=", functionClassName + "& "); op.addArgument("const " + functionClassName + "& other"); body.clear(); body += "if ( this == &other )"; body.indent(); body += "return *this;"; body.unindent(); body.newLine(); if (classObject.useSharedData()) body += classObject.dPointerName() + " = other." + classObject.dPointerName() + ";"; else body += "*" + classObject.dPointerName() + " = *other." + classObject.dPointerName() + ";"; for (int i = 0; i < baseClasses.count(); ++i) { body += QLatin1String("* static_cast<") + baseClasses[i].name() + QLatin1String(" *>(this) = other;"); } body.newLine(); body += "return *this;"; op.setBody(body); code += mParent->functionSignature(op, functionClassName, true); code += '{'; code.addBlock(op.body(), Code::defaultIndentation()); code += '}'; code.newLine(); } // Generate nested class functions const auto nestedClasses = classObject.nestedClasses(); if (!nestedClasses.isEmpty()) { for (const Class &nested : nestedClasses) { code += classImplementation(nested, true); } } return code.text(); } void Printer::Private::addFunctionHeaders(Code &code, const Function::List &functions, const QString &className, int access) { bool needNewLine = false; bool hasAccess = false; Function::List::ConstIterator it; for (it = functions.constBegin(); it != functions.constEnd(); ++it) { Function f = *it; if (f.access() == access) { if (!hasAccess) { addLabel(code, f.accessAsString() + ':'); hasAccess = true; } if (mLabelsDefineIndent) code.indent(); if (!(*it).docs().isEmpty()) { code += "/**"; code.indent(); code.addFormattedText((*it).docs()); code.unindent(); code += " */"; } code += mParent->functionSignature(*it, className, false) + ';'; if (mLabelsDefineIndent) code.unindent(); needNewLine = true; } } if (needNewLine) code.newLine(); } Printer::Printer() : d(new Private(this)) {} Printer::Printer(const Printer &other) : d(new Private(this)) { *d = *other.d; d->mParent = this; } Printer::Printer(const Style &style) : d(new Private(this)) { d->mStyle = style; } Printer::~Printer() { delete d; } Printer &Printer::operator=(const Printer &other) { if (this == &other) return *this; *d = *other.d; d->mParent = this; return *this; } void Printer::setCreationWarning(bool v) { d->mCreationWarning = v; } void Printer::setGenerator(const QString &generator) { d->mGenerator = generator; } void Printer::setOutputDirectory(const QString &outputDirectory) { d->mOutputDirectory = outputDirectory; } void Printer::setSourceFile(const QString &sourceFile) { d->mSourceFile = sourceFile; } void Printer::setLabelsDefineIndent(bool b) { d->mLabelsDefineIndent = b; } void Printer::setIndentLabels(bool b) { d->mIndentLabels = b; } QString Printer::functionSignature(const Function &function, const QString &className, bool forImplementation) { QString s; if (function.isStatic() && !forImplementation) { s += QStringLiteral("static "); } if (function.virtualMode() != Function::NotVirtual && !forImplementation) { s += QStringLiteral("virtual "); } if (function.isExplicit() && !forImplementation) { s += QStringLiteral("explicit "); } QString ret = function.returnType(); if (!ret.isEmpty()) { s += d->formatType(ret); } if (forImplementation) s += className + "::"; s += function.name(); s += '('; if (function.hasArguments()) { QStringList arguments; for (Function::Argument &argument : function.arguments()) { if (!forImplementation) { arguments.append(argument.headerDeclaration()); } else { arguments.append(argument.bodyDeclaration()); } } s += ' ' + arguments.join(", ") + ' '; } s += ')'; if (function.isConst()) s += " const"; if (function.virtualMode() == Function::Override && !forImplementation) { s += " override"; } if (function.virtualMode() == Function::Final && !forImplementation) { s += " final"; } if (function.virtualMode() == Function::PureVirtual) s += " = 0"; return s; } QString Printer::creationWarning() const { // Create warning about generated file QString str = "// This file is generated by " + d->mGenerator; if (!d->mSourceFile.isEmpty()) str += " from " + d->mSourceFile; str += ".\n"; str += "// All changes you do to this file will be lost."; return str; } QString Printer::licenseHeader(const File &file) const { Code code; const QStringList copyrights = file.copyrightStrings(); if (!file.project().isEmpty() || !copyrights.isEmpty() || !file.license().text().isEmpty()) { code += "/*"; code.setIndent(4); if (!file.project().isEmpty()) { code += "This file is part of " + file.project() + '.'; code.newLine(); } if (!copyrights.isEmpty()) { code.addBlock(copyrights.join("\n")); code.newLine(); } code.addBlock(file.license().text()); code.setIndent(0); code += "*/"; } return code.text(); } void Printer::setStatementsAfterIncludes(const QStringList &statements) { d->mStatementsAfterIncludes = statements; } static QStringList commonLeft(const QStringList &l1, const QStringList &l2) { QStringList r; const int l = qMin(l1.size(), l2.size()); for (int i = 0; i < l; ++i) if (l1.at(i) == l2.at(i)) r.append(l1.at(i)); else return r; return r; } void Printer::printHeader(const File &file) { Code out; if (d->mCreationWarning) out += creationWarning(); out.addBlock(licenseHeader(file)); // Create include guard QString className = file.filenameHeader(); QFileInfo headerInfo(className); className = headerInfo.fileName(); // remove path, keep only filename className.replace('-', "_"); out.addLine(QStringLiteral("#pragma once")); out.newLine(); // Create includes Include::List processedIncludes; const Class::List classes = file.classes(); Q_FOREACH (const Class &cl, classes) { Q_ASSERT(!cl.name().isEmpty()); Include::List includes = cl.headerIncludes(); if (cl.useSharedData()) includes.append(Include("QtCore/QSharedData")); // qDebug() << "includes=" << includes; for (auto include : std::as_const(includes)) { if (!processedIncludes.contains(include)) { if (include.type == Include::Relative) out += "#include \"" + include.includeFileName + '"'; else out += "#include <" + include.includeFileName + '>'; processedIncludes.append(include); } } } if (!processedIncludes.isEmpty()) out.newLine(); for (const QString &statement : d->mStatementsAfterIncludes) { out += statement; } // Create enums Enum::List enums = file.fileEnums(); Enum::List::ConstIterator enumIt; for (enumIt = enums.constBegin(); enumIt != enums.constEnd(); ++enumIt) { (*enumIt).printDeclaration(out); } // Create forward declarations QSet processed; Class::List::ConstIterator it; for (it = classes.constBegin(); it != classes.constEnd(); ++it) { const QStringList decls = (*it).forwardDeclarations(); #if QT_VERSION > QT_VERSION_CHECK(5, 14, 0) auto newProcessed = QSet(decls.begin(), decls.end()); processed += newProcessed; #else processed += decls.toSet(); #endif } auto fwdClasses = processed.values(); fwdClasses.sort(); fwdClasses += QString(); // for proper closing of the namespace blocks below QStringList prevNS; Q_FOREACH (const QString &fwd, fwdClasses) { // handle namespaces by opening and closing namespace blocks accordingly // the sorting will ensure sensible grouping const QStringList seg = fwd.split(QLatin1String("::")); const QStringList ns = seg.mid(0, seg.size() - 1); const QString clas = seg.isEmpty() ? QString() : seg.last(); const QStringList common = commonLeft(ns, prevNS); for (int i = common.size(); i < prevNS.size(); ++i) { out.unindent(); out += "}"; out.newLine(); } for (int i = common.size(); i < ns.size(); ++i) { out += "namespace " + ns.at(i) + " {"; out.indent(); } if (!clas.isEmpty()) { const bool isQtClass = clas.startsWith(QLatin1Char('Q')) && !clas.contains(QLatin1Char('_')); if (isQtClass) out += QLatin1String("QT_BEGIN_NAMESPACE"); out += "class " + clas + ';'; if (isQtClass) out += QLatin1String("QT_END_NAMESPACE"); } prevNS = ns; } if (!processed.isEmpty()) out.newLine(); if (!file.nameSpace().isEmpty()) { out += "namespace " + file.nameSpace() + " {"; out.newLine(); } // Create content for (it = classes.constBegin(); it != classes.constEnd(); ++it) { out.addBlock(d->classHeader(*it, false)); out.newLine(); } if (!file.nameSpace().isEmpty()) { out += '}'; out.newLine(); } // Print to file QString filename = file.filenameHeader(); if (!d->mOutputDirectory.isEmpty()) filename.prepend(d->mOutputDirectory + '/'); // KSaveFile::simpleBackupFile( filename, QString(), ".backup" ); QFile header(filename); d->printCodeIntoFile(out, &header); } void Printer::printImplementation(const File &file, bool createHeaderInclude) { Code out; if (d->mCreationWarning) out += creationWarning(); out.addBlock(licenseHeader(file)); out.newLine(); // Create includes if (createHeaderInclude) { out += "#include \"" + file.filenameHeader() + "\""; out.newLine(); } QStringList includes = file.includes(); QStringList::ConstIterator it2; for (it2 = includes.constBegin(); it2 != includes.constEnd(); ++it2) out += "#include <" + *it2 + '>'; if (!includes.isEmpty()) out.newLine(); // Create class includes QStringList processed; Class::List classes = file.classes(); Class::List::ConstIterator it; for (it = classes.constBegin(); it != classes.constEnd(); ++it) { QStringList includes = (*it).includes(); QStringList::ConstIterator it2; for (it2 = includes.constBegin(); it2 != includes.constEnd(); ++it2) { if (!processed.contains(*it2)) { out += "#include <" + *it2 + '>'; processed.append(*it2); } } } if (!processed.isEmpty()) out.newLine(); if (!file.nameSpace().isEmpty()) { out += "namespace " + file.nameSpace() + " {"; out.newLine(); } // 'extern "C"' declarations const QStringList externCDeclarations = file.externCDeclarations(); if (!externCDeclarations.isEmpty()) { out += "extern \"C\" {"; QStringList::ConstIterator it; for (it = externCDeclarations.constBegin(); it != externCDeclarations.constEnd(); ++it) { out += *it + ';'; } out += '}'; out.newLine(); } // File variables Variable::List vars = file.fileVariables(); Variable::List::ConstIterator itV; for (itV = vars.constBegin(); itV != vars.constEnd(); ++itV) { Variable v = *itV; QString str; if (v.isStatic()) str += "static "; str += v.type() + ' ' + v.name() + ';'; out += str; } if (!vars.isEmpty()) out.newLine(); // File code if (!file.fileCode().isEmpty()) { out += file.fileCode(); out.newLine(); } // File functions Function::List funcs = file.fileFunctions(); Function::List::ConstIterator itF; for (itF = funcs.constBegin(); itF != funcs.constEnd(); ++itF) { Function f = *itF; out += functionSignature(f); out += '{'; out.addBlock(f.body(), Code::defaultIndentation()); out += '}'; out.newLine(); } // Classes #ifdef KDAB_DELETED bool containsQObject = false; #endif for (it = classes.constBegin(); it != classes.constEnd(); ++it) { #ifdef KDAB_DELETED if ((*it).isQObject()) containsQObject = true; #endif QString str = d->classImplementation(*it); if (!str.isEmpty()) out += d->classImplementation(*it); } if (!file.nameSpace().isEmpty()) { out += "}"; out.newLine(); } // KDAB: removed; 1) for removing .filename(), and 2) qmake would want moc_foo.cpp anyway #ifdef KDAB_DELETED if (containsQObject) { out.newLine(); // out += "#include \"" + file.filename() + ".moc\""; } #endif // Print to file QString filename = file.filenameImplementation(); if (!d->mOutputDirectory.isEmpty()) filename.prepend(d->mOutputDirectory + '/'); QFile implementation(filename); d->printCodeIntoFile(out, &implementation); } void Printer::Private::printCodeIntoFile(const Code &code, QFile *file) { const QString outText = code.text(); static bool s_compareOutput = qEnvironmentVariableIsSet("LIBKODE_COMPARE_OUTPUT"); bool identical = false; if (s_compareOutput && file->exists()) { if (!file->open(QIODevice::ReadOnly)) { qWarning("Can't open '%s' for reading.", qPrintable(file->fileName())); return; } QTextStream fileReaderStream(file); #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) fileReaderStream.setCodec(QTextCodec::codecForName("UTF-8")); #endif QTextStream codeStream(outText.toUtf8()); QString fileLine, outLine; identical = true; while (fileReaderStream.readLineInto(&fileLine) && codeStream.readLineInto(&outLine)) { if (fileLine != outLine) { identical = false; break; } } if (identical) identical = fileReaderStream.atEnd() && codeStream.atEnd(); file->close(); } if (!identical) { if (!file->open(QIODevice::WriteOnly)) { qWarning("Can't open '%s' for writing.", qPrintable(file->fileName())); return; } QTextStream fileWriterStream(file); #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) fileWriterStream.setCodec(QTextCodec::codecForName("UTF-8")); #endif fileWriterStream << outText; file->close(); } else { qDebug("Skip generating %s because its content did not change", qPrintable(file->fileName())); } } #if 0 // TODO: port to cmake void Printer::printAutoMakefile( const AutoMakefile &am ) { QString filename = "Makefile.am"; if ( !d->mOutputDirectory.isEmpty() ) filename.prepend( d->mOutputDirectory + '/' ); // KSaveFile::simpleBackupFile( filename, QString(), ".backup" ); QFile file( filename ); if ( !file.open( QIODevice::WriteOnly ) ) { qWarning( "Can't open '%s' for writing.", qPrintable( filename ) ); return; } QTextStream ts( &file ); ts << am.text(); } #endif libkode-master/code_generation/printer.h000066400000000000000000000110621472623201100207370ustar00rootroot00000000000000/* This file is part of kdepim. Copyright (c) 2004 Cornelius Schumacher This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KODE_PRINTER_H #define KODE_PRINTER_H #include "code.h" #include "file.h" #include "style.h" #include namespace KODE { /** * This class prints the abstract class definitions * as C++ code to a file. */ class KODE_EXPORT Printer { public: /** * Creates a new printer. */ Printer(); /** * Creates a new printer from @param other. */ Printer(const Printer &other); /** * Creates a new printer, which uses the given @param style * to format the C++ code. */ Printer(const Style &style); /** * Destroys the printer. */ virtual ~Printer(); /** * Assignment operator. */ Printer &operator=(const Printer &other); /** * Sets whether the implementation shall contain a comment * which warns about changing the C++ code manually. */ void setCreationWarning(bool value); /** * Sets the name of the @param generator which shall be * included in the C++ code. */ void setGenerator(const QString &generator); /** * Sets the directory where the decleration and implementation * files shall be stored. If now directory is set, the current * working directory is used. */ void setOutputDirectory(const QString &outputDirectory); /** * Sets the name of the source file which is included in * the generator statement. */ void setSourceFile(const QString &sourceFile); /** * Sets whether labels (public:, private: etc.) should define * an indentation level. I.e. they are indented and then their * contents are indented even more. */ void setLabelsDefineIndent(bool b); /** * Sets whether labels should be indented. * * setIndentLabels(true) + setLabelsDefineIndent(false) -> label at same level as contents * setIndentLabels(false) + setLabelsDefineIndent(false) -> Qt coding style * setIndentLabels(true) + setLabelsDefineIndent(true) -> kdepim coding style, default here. * setIndentLabels(false) + setLabelsDefineIndent(true) -> doesn't really make sense. */ void setIndentLabels(bool b); /** * Prints the header of the class definitions in @param file. */ void printHeader(const File &file); /** * Prints the implementation of the class definitions in @param file. * * @param createHeaderInclude If true, the header for the declaration of * this implementation is included. */ void printImplementation(const File &file, bool createHeaderInclude = true); /** * Prints a automake file as defined by @param autoMakefile. */ // void printAutoMakefile( const AutoMakefile &autoMakefile ); /** * Returns the function signature for the given @param function * with class name @param className. * * If @param forImplementation is true, the class qualifier * is part of the signature as well, and default args are removed. */ QString functionSignature(const Function &function, const QString &className = QString(), bool forImplementation = false); /** * For #undef hacks for instance */ void setStatementsAfterIncludes(const QStringList &statements); protected: /** * Returns the creation warning. * * Reimplement this method to provide a custom warning. */ virtual QString creationWarning() const; /** * Returns the license header for the given @param file. * * Reimplement this method to provide a custom license * header. */ virtual QString licenseHeader(const File &file) const; private: class Private; Private *d; }; } #endif libkode-master/code_generation/statemachine.cpp000066400000000000000000000054101472623201100222540ustar00rootroot00000000000000/* This file is part of KDE. Copyright (c) 2004 Cornelius Schumacher This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include "statemachine.h" using namespace KODE; class StateMachine::Private { public: QMap mStateMap; QString mInitialState; }; StateMachine::StateMachine() : d(new Private) {} StateMachine::StateMachine(const StateMachine &other) : d(new Private) { *d = *other.d; } StateMachine::~StateMachine() { delete d; } StateMachine &StateMachine::operator=(const StateMachine &other) { if (this == &other) return *this; *d = *other.d; return *this; } void StateMachine::setState(const QString &state, const Code &code) { d->mStateMap.insert(state, code); if (d->mInitialState.isEmpty()) d->mInitialState = state; } void StateMachine::setInitialState(const QString &state) { d->mInitialState = state; } Code StateMachine::stateDefinition() const { Code code; QStringList states; QMap::ConstIterator it; for (it = d->mStateMap.constBegin(); it != d->mStateMap.constEnd(); ++it) { states.append(it.key()); } code += QLatin1String("enum State { ") + states.join(QLatin1String(", ")) + QLatin1String(" };"); code += QLatin1String("State state = ") + d->mInitialState + QLatin1Char(';'); return code; } Code StateMachine::transitionLogic() const { Code code; code += QLatin1String("switch( state ) {"); code.indent(); QMap::ConstIterator it; for (it = d->mStateMap.constBegin(); it != d->mStateMap.constEnd(); ++it) { code += QLatin1String("case ") + it.key() + QLatin1Char(':'); code.indent(); code.addBlock(it.value()); code += QLatin1String("break;"); code.unindent(); } code += QLatin1String("default:"); code.indent(); code += QLatin1String("break;"); code.unindent(); code.unindent(); code += QLatin1String("}"); return code; } libkode-master/code_generation/statemachine.h000066400000000000000000000040331472623201100217210ustar00rootroot00000000000000/* This file is part of KDE. Copyright (c) 2004 Cornelius Schumacher This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KODE_STATEMACHINE_H #define KODE_STATEMACHINE_H #include "code.h" #include namespace KODE { /** * This class represents a state machine. * * It can be used to create complex state machines * in an easy way. */ class KODE_EXPORT StateMachine { public: /** * Creates a new state machine. */ StateMachine(); /** * Creates a new state machine from @param other. */ StateMachine(const StateMachine &other); /** * Destroys the state machine. */ ~StateMachine(); /** * Assignment operator. */ StateMachine &operator=(const StateMachine &other); /** * Sets the @param code for a special @param state. */ void setState(const QString &state, const Code &code); /** * Sets the initial @param state, which is used when the * machine is started. */ void setInitialState(const QString &state); /** * Returns the code for the state definitions. */ Code stateDefinition() const; /** * Returns the code for the transition logic. */ Code transitionLogic() const; private: class Private; Private *d; }; } #endif libkode-master/code_generation/style.cpp000066400000000000000000000046161472623201100207560ustar00rootroot00000000000000/* This file is part of kdepim. Copyright (c) 2004 Cornelius Schumacher This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "style.h" using namespace KODE; class Style::Private { public: }; Style::Style() : d(nullptr) {} Style::Style(const Style & /*other*/) : d(nullptr) { // *d = *other.d; } Style::~Style() { delete d; } // cppcheck-suppress operatorEqVarError Style &Style::operator=(const Style &other) { if (this == &other) return *this; // *d = *other,d; return *this; } QString Style::className(const QString &str) { Q_ASSERT(!str.isEmpty()); QString cl = upperFirst(str); cl.replace(QLatin1Char('-'), QLatin1Char('_')); cl.replace(QLatin1Char(';'), QLatin1Char('_')); cl.replace(QLatin1Char(':'), QLatin1Char('_')); cl.replace(QLatin1Char('.'), QLatin1Char('_')); return cl; } QString Style::upperFirst(const QString &str) { if (str.isEmpty()) return str; return str[0].toUpper() + str.mid(1); } QString Style::lowerFirst(const QString &str) { if (str.isEmpty()) return str; return str[0].toLower() + str.mid(1); } QString Style::makeIdentifier(const QString &str) { Q_ASSERT(!str.isEmpty()); QString identifier = str; identifier.replace("-", "_"); identifier.replace(".", "_"); identifier.replace("/", "_"); identifier.replace(":", "_"); // xsd:int -> xsd_int (testcase: salesforce-partner.wsdl) identifier.replace(" ", "_"); // Can't start with a number, either. const int firstNum = identifier.at(0).digitValue(); identifier = (firstNum != -1) ? QLatin1Char('_') + identifier : identifier; return identifier; } libkode-master/code_generation/style.h000066400000000000000000000043661472623201100204250ustar00rootroot00000000000000/* This file is part of kdepim. Copyright (c) 2004 Cornelius Schumacher This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KODE_STYLE_H #define KODE_STYLE_H #include #include namespace KODE { /** * This class encapsulates the style settings. * * You can reimplement it to give the generated code * a custom style. */ class KODE_EXPORT Style { public: /** * Creates a new style. */ Style(); /** * Creates a new style from @param other. */ Style(const Style &other); /** * Destroys the style. */ virtual ~Style(); /** * Assignment operator. */ Style &operator=(const Style &other); /** * Converts the class name. * * The default implementation upper cases the first * character of the name. */ /*virtual*/ Q_REQUIRED_RESULT static QString className(const QString &str); /** * Returns a new version of @param str with the first * character be uppercase. */ Q_REQUIRED_RESULT static QString upperFirst(const QString &str); /** * Returns a new version of @param str with the first * character be lowercase. */ Q_REQUIRED_RESULT static QString lowerFirst(const QString &str); /** * Returns a new version of @param str after making it suitable for usage * as a C++ identifier. */ Q_REQUIRED_RESULT static QString makeIdentifier(const QString &str); private: class Private; Private *d; }; } #endif libkode-master/code_generation/typedef.cpp000066400000000000000000000030751472623201100212540ustar00rootroot00000000000000/* This file is part of KDE. Copyright (c) 2004 Cornelius Schumacher This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "typedef.h" using namespace KODE; class Typedef::Private { public: QString mType; QString mAlias; }; Typedef::Typedef() : d(new Private) {} Typedef::Typedef(const Typedef &other) : d(new Private) { *d = *other.d; } Typedef::Typedef(const QString &type, const QString &alias) : d(new Private) { d->mType = type; d->mAlias = alias; } Typedef::~Typedef() { delete d; } Typedef &Typedef::operator=(const Typedef &other) { if (this == &other) return *this; *d = *other.d; return *this; } QString Typedef::declaration() const { return QLatin1String("typedef ") + d->mType + QLatin1Char(' ') + d->mAlias + QLatin1Char(';'); } libkode-master/code_generation/typedef.h000066400000000000000000000033621472623201100207200ustar00rootroot00000000000000/* This file is part of KDE. Copyright (c) 2004 Cornelius Schumacher This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KODE_TYPEDEF_H #define KODE_TYPEDEF_H #include #include #include namespace KODE { /** * This is an abstract class for typedefs. */ class KODE_EXPORT Typedef { public: typedef QList List; /** * Creates a new typedef. */ Typedef(); /** * Creates a new typedef from @param other. */ Typedef(const Typedef &other); /** * Creates a new typedef with the given @param type and * @param alias. */ Typedef(const QString &type, const QString &alias); /** * Destroys the typedef. */ ~Typedef(); /** * Assignment operator. */ Typedef &operator=(const Typedef &other); /** * Returns the textual presentation of the typedef. */ QString declaration() const; private: class Private; Private *d; }; } #endif libkode-master/code_generation/variable.cpp000066400000000000000000000043631472623201100214020ustar00rootroot00000000000000/* This file is part of kdepim. Copyright (c) 2004 Cornelius Schumacher This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "membervariable.h" using namespace KODE; class Variable::Private { public: Private() : mIsStatic(false) {} QString mType; QString mName; bool mIsStatic; QString mInitializer; }; Variable::Variable() : d(new Private) {} Variable::Variable(const Variable &other) : d(new Private) { *d = *other.d; } Variable::Variable(const QString &name, const QString &type, bool isStatic) : d(new Private) { d->mType = type; d->mIsStatic = isStatic; Q_ASSERT(!name.isEmpty()); if (name.isEmpty()) { d->mName = QLatin1String("mUndefined"); } else { d->mName = name; } } Variable::~Variable() { delete d; } Variable &Variable::operator=(const Variable &other) { if (this == &other) return *this; *d = *other.d; return *this; } void Variable::setName(const QString &name) { d->mName = name; } QString Variable::name() const { return d->mName; } void Variable::setType(const QString &type) { d->mType = type; } QString Variable::type() const { return d->mType; } void Variable::setStatic(bool isStatic) { d->mIsStatic = isStatic; } bool Variable::isStatic() const { return d->mIsStatic; } void Variable::setInitializer(const QString &initializer) { d->mInitializer = initializer; } QString Variable::initializer() const { return d->mInitializer; } libkode-master/code_generation/variable.h000066400000000000000000000047641472623201100210540ustar00rootroot00000000000000/* This file is part of kdepim. Copyright (c) 2004 Cornelius Schumacher This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KODE_VARIABLE_H #define KODE_VARIABLE_H #include #include namespace KODE { /** * This class represents a variable. */ class KODE_EXPORT Variable { public: typedef QList List; /** * Creates a new variable. */ Variable(); /** * Creates a new variable from @param other. */ Variable(const Variable &other); /** * Creates a new variable of the given @param type and with the * given @param name. * * @param isStatic If true the variable is marked as static. */ Variable(const QString &name, const QString &type, bool isStatic = false); /** * Destroys the variable. */ virtual ~Variable(); /** * Assignment operator. */ Variable &operator=(const Variable &other); /** * Sets the @param type of the variable. */ void setType(const QString &type); /** * Returns the type of the variable. */ QString type() const; /** * Sets the @param name of the variable. */ void setName(const QString &name); /** * Returns the name of the variable. */ QString name() const; /** * Sets whether the variable is static. */ void setStatic(bool isStatic); /** * Returns whether the variable is static. */ bool isStatic() const; /** * Sets the initializer of the variable. */ void setInitializer(const QString &initializer); /** * Returns the initializer of the variable. */ QString initializer() const; private: class Private; Private *d; }; } #endif libkode-master/common/000077500000000000000000000000001472623201100152465ustar00rootroot00000000000000libkode-master/common/CMakeLists.txt000066400000000000000000000010551472623201100200070ustar00rootroot00000000000000set(COMMON_SOURCES fileprovider.cpp messagehandler.cpp nsmanager.cpp parsercontext.cpp qname.cpp ) set(COMMON_HEADERS fileprovider.h messagehandler.h nsmanager.h parsercontext.h qname.h ) add_library(xmlcommon STATIC ${COMMON_SOURCES} ${COMMON_HEADERS} ) target_link_libraries(xmlcommon Qt${QT_MAJOR_VERSION}::Network Qt${QT_MAJOR_VERSION}::Xml ) target_include_directories(xmlcommon PUBLIC "$" ) set_target_properties(xmlcommon PROPERTIES OUTPUT_NAME "xmlcommon${kode_LIBRARY_QTID}") libkode-master/common/common.pri000066400000000000000000000004341472623201100172530ustar00rootroot00000000000000QT += network HEADERS += \ $$PWD/fileprovider.h \ $$PWD/messagehandler.h \ $$PWD/nsmanager.h \ $$PWD/parsercontext.h \ $$PWD/qname.h SOURCES += \ $$PWD/fileprovider.cpp \ $$PWD/messagehandler.cpp \ $$PWD/nsmanager.cpp \ $$PWD/parsercontext.cpp \ $$PWD/qname.cpp libkode-master/common/common.pro000066400000000000000000000004411472623201100172570ustar00rootroot00000000000000TEMPLATE = lib TARGET = xmlcommon CONFIG += staticlib include(common.pri) QT -= gui QT += xml network INCLUDEPATH += $${PWD}/.. $${PWD}/../code_generation include ($${PWD}/../variables.pri) DEFINES -= QT_NO_CAST_TO_ASCII QBA_NO_CAST_TO_VOID QBA_NO_CAST_TO_ASCII QT_NO_CAST_FROM_ASCII libkode-master/common/fileprovider.cpp000066400000000000000000000105151472623201100204460ustar00rootroot00000000000000/* This file is part of KDE Schema Parser Copyright (c) 2005 Tobias Koenig This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "fileprovider.h" #include #include #include #include #include #include #include #include #include #include #ifndef Q_OS_WIN # include #endif static QHash fileProviderCache; FileProvider::FileProvider(bool useLocalFilesOnly, const QStringList &importPathList, const QMap &localSchemas) : mUseLocalFilesOnly(useLocalFilesOnly), mImportPathList(importPathList), mLocalSchemas(localSchemas) { } FileProvider::~FileProvider() { cleanUp(); } void FileProvider::cleanUp() { if (!mFileName.isEmpty()) { QFile::remove(mFileName); mFileName = QString(); } } bool FileProvider::get(const QUrl &url, QString &target) { if (!mFileName.isEmpty()) { cleanUp(); } if (url.isLocalFile()) { target = url.toLocalFile(); return true; } if (url.scheme() == QLatin1String("qrc")) { target = QLatin1String(":") + url.path(); return true; } const auto localSchemaIt = mLocalSchemas.constFind(url); if (localSchemaIt != mLocalSchemas.constEnd()) { target = localSchemaIt.value(); return true; } Q_FOREACH (const QString &importPath, mImportPathList) { QDir importDir(importPath); QString path = importDir.absoluteFilePath(url.host() + QDir::separator() + url.path()); if (QFile::exists(path)) { qDebug("Using import path '%s'", qPrintable(path)); target = path; return true; } } if (mUseLocalFilesOnly) { qCritical("ERROR: Could not find the local file for '%s'", qPrintable(url.toEncoded())); qCritical("ERROR: Try to download the file using:"); qCritical("ERROR: $ cd %s", qPrintable(mImportPathList.first())); qCritical("ERROR: $ wget -r %s", qPrintable(url.toEncoded())); qCritical("ERROR: Or use the -import-path argument to set the correct search path"); QCoreApplication::exit(12); return false; } if (target.isEmpty()) { QTemporaryFile tmpFile; tmpFile.setAutoRemove(false); tmpFile.open(); target = tmpFile.fileName(); mFileName = target; } QByteArray data; const QHash::const_iterator it = fileProviderCache.constFind(url); if (it != fileProviderCache.constEnd()) { data = it.value(); } else { qDebug("Downloading '%s'", url.toEncoded().constData()); QNetworkAccessManager manager; manager.setRedirectPolicy(QNetworkRequest::NoLessSafeRedirectPolicy); QNetworkRequest request(url); QNetworkReply *job = manager.get(request); QEventLoop loop; QObject::connect(job, &QNetworkReply::finished, &loop, &QEventLoop::quit); loop.exec(); if (job->error()) { qWarning("Error downloading '%s': %s", url.toEncoded().constData(), qPrintable(job->errorString())); return false; } qDebug("Download successful"); data = job->readAll(); fileProviderCache[url] = data; } QFile file(mFileName); if (!file.open(QIODevice::WriteOnly)) { qWarning() << "Unable to create" << mFileName << ":" << file.errorString(); return false; } file.write(data); file.close(); return true; } libkode-master/common/fileprovider.h000066400000000000000000000027051472623201100201150ustar00rootroot00000000000000/* This file is part of KDE Copyright (c) 2005 Tobias Koenig This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef FILEPROVIDER_H #define FILEPROVIDER_H #include #include QT_BEGIN_NAMESPACE class QUrl; QT_END_NAMESPACE class KXMLCOMMON_EXPORT FileProvider { public: FileProvider(bool useLocalFilesOnly = false, const QStringList &importPathList = QStringList(), const QMap &localSchemas = {}); ~FileProvider(); bool get(const QUrl &url, QString &target); void cleanUp(); private: QString mFileName; bool mUseLocalFilesOnly = false; const QStringList mImportPathList; const QMap mLocalSchemas; }; #endif libkode-master/common/messagehandler.cpp000066400000000000000000000022441472623201100207360ustar00rootroot00000000000000/* This file is part of KDE. Copyright (c) 2005 Tobias Koenig This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "messagehandler.h" MessageHandler::MessageHandler() {} MessageHandler::~MessageHandler() {} void MessageHandler::warning(const QString &message) { qWarning("Warning: %s", qPrintable(message)); } void MessageHandler::error(const QString &message) { qWarning("Error: %s", qPrintable(message)); } libkode-master/common/messagehandler.h000066400000000000000000000031601472623201100204010ustar00rootroot00000000000000/* This file is part of KDE. Copyright (c) 2005 Tobias Koenig This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef MESSAGEHANDLER_H #define MESSAGEHANDLER_H #include #include /** This class is an interface for the xml parsing classes to output messages ( warnings, errors ). When you want to use a custom MessageHandler, just derivate and pass it to the ParserContext of the parsing classes. */ class KXMLCOMMON_EXPORT MessageHandler { public: /** Constructs a MessageHandler. */ MessageHandler(); /** Destroys the MessageHandler. */ virtual ~MessageHandler(); /** This method is called to indicate a warning. */ virtual void warning(const QString &message); /** This method is called to indicate an error. */ virtual void error(const QString &message); }; #endif libkode-master/common/nsmanager.cpp000066400000000000000000000134411472623201100177300ustar00rootroot00000000000000/* This file is part of KDE. Copyright (c) 2005 Tobias Koenig This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "nsmanager.h" #include "parsercontext.h" #include #include // maybe port to QXmlNamespaceSupport? NSManager::NSManager() : mContext(nullptr), mParentManager(nullptr) {} NSManager::NSManager(ParserContext *context, const QDomElement &child) { mContext = context; mParentManager = context->namespaceManager(); mMap = mParentManager->mMap; mCurrentNamespace = mParentManager->mCurrentNamespace; enterChild(child); mContext->setNamespaceManager(this); } NSManager::~NSManager() { // Restore parent namespaces if (mContext) { mContext->setNamespaceManager(mParentManager); // Remember the prefixes used for the namespaces, even afterwards // qDebug() << this << "adding prefixes into parent manager" << mParentManager; mParentManager->addPrefixes(mMap); } } void NSManager::setCurrentNamespace(const QString &uri) { mCurrentNamespace = uri; } void NSManager::setPrefix(const QString &prefix, const QString &uri) { mMap.insert(prefix, uri); } QString NSManager::prefix(const QString &uri) const { // Note that it's allowed to have two prefixes for the same namespace uri. // So we just pick one. QString pref = mMap.key(uri); // linear search if (pref.isEmpty() && uri != "http://schemas.xmlsoap.org/wsdl/") { qWarning() << "WARNING: No prefix found for" << uri; } return pref; } QString NSManager::uri(const QString &prefix) const { if (prefix.isEmpty()) return mCurrentNamespace; return mMap.value(prefix); } void NSManager::splitName(const QString &qname, QString &prefix, QString &localname) const { int pos = qname.indexOf(QLatin1Char(':')); if (pos != -1) { prefix = qname.left(pos); localname = qname.mid(pos + 1); } else { prefix = QString(); localname = qname; } } QString NSManager::fullName(const QString &nameSpace, const QString &localname) const { if (prefix(nameSpace).isEmpty()) return localname; else return prefix(nameSpace) + QLatin1Char(':') + localname; } QString NSManager::fullName(const QName &name) const { return fullName(name.nameSpace(), name.localName()); } QStringList NSManager::prefixes() const { return mMap.keys(); } QMap NSManager::prefixMap() const { return mMap; } void NSManager::addPrefixes(const QMap &prefixes) { for (QMap::const_iterator it = prefixes.constBegin(); it != prefixes.constEnd(); ++it) { const QString &prefix = it.key(); const QString &ns = it.value(); // Only write down this prefix if we don't have it yet // and if we don't have another prefix for this NS (this is mostly for backwards compat, // so that msexchange still uses TNS rather than 'M' or 'T'...) if (!mMap.contains(prefix) && mMap.key(ns).isEmpty()) mMap.insert(prefix, ns); } } QStringList NSManager::soapEncNamespaces() { return QStringList() << QLatin1String("http://schemas.xmlsoap.org/soap/encoding/") << QLatin1String("http://www.w3.org/2003/05/soap-encoding"); } QStringList NSManager::soapNamespaces() { return QStringList() << QLatin1String("http://schemas.xmlsoap.org/wsdl/soap/") << QLatin1String("http://schemas.xmlsoap.org/wsdl/soap12/"); } QString NSManager::xmlNamespace() { return QLatin1String("http://www.w3.org/XML/1998/namespace"); } void NSManager::reset() { mMap.clear(); } void NSManager::dump() const { QMap::ConstIterator it; for (it = mMap.begin(); it != mMap.end(); ++it) { qDebug("%s\t%s", qPrintable(it.key()), qPrintable(it.value())); } } QString NSManager::nameSpace(const QDomElement &element) const { if (!element.namespaceURI().isEmpty()) // namespace support was enabled in QDom: easy return element.namespaceURI(); QString prefix, localname; splitName(element.tagName(), prefix, localname); return uri(prefix); } QString NSManager::localName(const QDomElement &element) const { if (!element.namespaceURI().isEmpty()) // namespace support was enabled in QDom: easy return element.localName(); QString prefix, localname; splitName(element.tagName(), prefix, localname); return localname; } void NSManager::enterChild(const QDomElement &element) { const QDomNamedNodeMap attributes = element.attributes(); for (int i = 0; i < attributes.count(); ++i) { QDomAttr attribute = attributes.item(i).toAttr(); if (attribute.name().startsWith(QLatin1String("xmlns:"))) { QString prefix = attribute.name().mid(6); // if (prefix == "tns") // qDebug() << this << "enterChild: setting tns to" << attribute.value(); setPrefix(prefix, attribute.value()); } else if (attribute.name() == QLatin1String("xmlns")) { setCurrentNamespace(attribute.value()); } } } libkode-master/common/nsmanager.h000066400000000000000000000047531472623201100174030ustar00rootroot00000000000000/* This file is part of KDE. Copyright (c) 2005 Tobias Koenig This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef NSMANAGER_H #define NSMANAGER_H #include #include #include #include QT_BEGIN_NAMESPACE class QDomElement; QT_END_NAMESPACE class ParserContext; class KXMLCOMMON_EXPORT NSManager { public: NSManager(); // Called when entering a new XML element. We copy the current namespaces // from the context and add the ones defined by the new XML element. // Upon destruction, we restore the context. NSManager(ParserContext *context, const QDomElement &child); ~NSManager(); void enterChild(const QDomElement &element); void setCurrentNamespace(const QString &uri); void setPrefix(const QString &prefix, const QString &uri); QString prefix(const QString &uri) const; QString uri(const QString &prefix) const; QString fullName(const QString &nameSpace, const QString &localname) const; QString fullName(const QName &name) const; QString nameSpace(const QDomElement &element) const; QString localName(const QDomElement &element) const; QStringList prefixes() const; QMap prefixMap() const; void addPrefixes(const QMap &prefixes); void reset(); void dump() const; // Repository of namespaces static QStringList soapEncNamespaces(); static QStringList soapNamespaces(); static QString xmlNamespace(); private: void splitName(const QString &qname, QString &prefix, QString &localname) const; typedef QMap NSMap; // prefix -> URI NSMap mMap; QString mCurrentNamespace; ParserContext *mContext; NSManager *mParentManager; }; #endif libkode-master/common/parsercontext.cpp000066400000000000000000000037121472623201100206560ustar00rootroot00000000000000/* This file is part of KDE. Copyright (c) 2005 Tobias Koenig This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "parsercontext.h" #include "nsmanager.h" #include ParserContext::ParserContext() : mNamespaceManager(nullptr), mMessageHandler(nullptr) {} ParserContext::~ParserContext() {} void ParserContext::setNamespaceManager(NSManager *manager) { mNamespaceManager = manager; // qDebug() << "ParserContext now points to" << manager << "tns=" << manager->uri("tns"); } NSManager *ParserContext::namespaceManager() const { return mNamespaceManager; } void ParserContext::setMessageHandler(MessageHandler *handler) { mMessageHandler = handler; } MessageHandler *ParserContext::messageHandler() const { return mMessageHandler; } void ParserContext::setDocumentBaseUrl(const QUrl &url) { mDocumentBaseUrl = url; } void ParserContext::setDocumentBaseUrlFromFileUrl(const QUrl &url) { QString path = url.path(); path.truncate(path.lastIndexOf('/')); QUrl newBaseUrl = url; newBaseUrl.setPath(path); // qDebug() << "New document base URL" << newBaseUrl; setDocumentBaseUrl(newBaseUrl); } QUrl ParserContext::documentBaseUrl() const { return mDocumentBaseUrl; } libkode-master/common/parsercontext.h000066400000000000000000000043461472623201100203270ustar00rootroot00000000000000/* This file is part of KDE. Copyright (c) 2005 Tobias Koenig This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef PARSERCONTEXT_H #define PARSERCONTEXT_H #include #include class NSManager; class MessageHandler; /** A container class which is passed to XML parsing methods to provide additional contextual information. */ class KXMLCOMMON_EXPORT ParserContext { public: /** Constructs a ParserContext. */ ParserContext(); /** Destroys the ParserContext. */ virtual ~ParserContext(); /** Sets the namespace handler for this context. */ void setNamespaceManager(NSManager *manager); /** Returns the namespace handler of this context. */ NSManager *namespaceManager() const; /** Sets the message handler for this context. */ void setMessageHandler(MessageHandler *handler); /** Returns the message handler of this context. */ MessageHandler *messageHandler() const; /** Sets the base URL where the document is located. */ void setDocumentBaseUrl(const QUrl &url); /** Sets the base URL based on an actual document URL (i.e. set it to the parent directory) */ void setDocumentBaseUrlFromFileUrl(const QUrl &url); /** Returns the document base url. */ QUrl documentBaseUrl() const; private: NSManager *mNamespaceManager; MessageHandler *mMessageHandler; QUrl mDocumentBaseUrl; }; #endif libkode-master/common/qname.cpp000066400000000000000000000047211472623201100170570ustar00rootroot00000000000000/* This file is part of KDE Schema Parser Copyright (c) 2005 Tobias Koenig based on wsdlpull parser by Vivek Krishna This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "qname.h" #include QName::QName() {} QName::QName(const QString &name) { parse(name); } QName::QName(const QString &nameSpace, const QString &localName) : mNameSpace(nameSpace), mLocalName(localName) { Q_ASSERT(!localName.contains(QLatin1Char(':'))); } void QName::operator=(const QString &name) { parse(name); } QString QName::localName() const { return mLocalName; } QString QName::prefix() const { return mPrefix; } QString QName::qname() const { if (mPrefix.isEmpty()) return mLocalName; else return mPrefix + QLatin1Char(':') + mLocalName; } void QName::setNameSpace(const QString &nameSpace) { mNameSpace = nameSpace; } QString QName::nameSpace() const { return mNameSpace; } bool QName::operator==(const QName &qname) const { return (qname.nameSpace() == mNameSpace && qname.localName() == mLocalName); } bool QName::operator!=(const QName &qname) const { return !operator==(qname); } bool QName::isEmpty() const { return (mNameSpace.isEmpty() && mLocalName.isEmpty()); } void QName::parse(const QString &str) { int pos = str.indexOf(QLatin1Char(':')); if (pos != -1) { mPrefix = str.left(pos); mLocalName = str.mid(pos + 1); } else { mLocalName = str; } Q_ASSERT(!mLocalName.contains(QLatin1Char(':'))); } QDebug operator<<(QDebug dbg, const QName &qn) { if (qn.prefix().isEmpty()) dbg << "(" << qn.nameSpace() << "," << qn.localName() << ")"; else dbg << qn.qname(); return dbg; } libkode-master/common/qname.h000066400000000000000000000035751472623201100165320ustar00rootroot00000000000000/* This file is part of KDE. Copyright (c) 2005 Tobias Koenig based on wsdlpull parser by Vivek Krishna This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef QNAME_H #define QNAME_H #include #include #include #include class KXMLCOMMON_EXPORT QName { public: typedef QList List; QName(); // Create a QName with prefix+localname QName(const QString &name); // Create a QName with namespace+localname QName(const QString &nameSpace, const QString &localName); void operator=(const QString &name); QString localName() const; QString prefix() const; QString qname() const; void setNameSpace(const QString &nameSpace); QString nameSpace() const; bool operator==(const QName &) const; bool operator!=(const QName &) const; bool isEmpty() const; private: void parse(const QString &); QString mNameSpace; QString mLocalName; QString mPrefix; }; inline uint qHash(const QName &qn) { return qHash(qn.nameSpace()) ^ qHash(qn.localName()); } QDebug operator<<(QDebug dbg, const QName &qn); #endif libkode-master/libkode.pri000066400000000000000000000001431472623201100161010ustar00rootroot00000000000000include(code_generation/code_generation.pri) include(schema/schema.pri) include(common/common.pri) libkode-master/libkode.pro000066400000000000000000000010601472623201100161060ustar00rootroot00000000000000# This file is in the build directory (because "somecommand >> somefile" puts it there) QMAKE_CACHE = "$${OUT_PWD}/.qmake.cache" # Create a .qmake.cache file unix:MESSAGE = '\\'$$LITERAL_HASH\\' libkode qmake cache file: following lines autogenerated during qmake run' !unix:MESSAGE = $$LITERAL_HASH' libkode qmake cache file: following lines autogenerated during qmake run' system('echo $${MESSAGE} > $${QMAKE_CACHE}') system('echo TOP_BUILD_DIR=$${OUT_PWD} >> $${QMAKE_CACHE}') CONFIG += ordered TEMPLATE = subdirs SUBDIRS = common schema code_generation libkode-master/schema/000077500000000000000000000000001472623201100152165ustar00rootroot00000000000000libkode-master/schema/CMakeLists.txt000066400000000000000000000013441472623201100177600ustar00rootroot00000000000000set(SCHEMA_SOURCES annotation.cpp attribute.cpp attributegroup.cpp complextype.cpp compositor.cpp element.cpp group.cpp parser.cpp #schematest.cpp simpletype.cpp types.cpp xmlelement.cpp xsdtype.cpp ) set(SCHEMA_HEADERS annotation.h attribute.h attributegroup.h complextype.h compositor.h element.h group.h parser.h simpletype.h types.h xmlelement.h xsdtype.h ) add_library(xmlschema STATIC ${SCHEMA_SOURCES} ${SCHEMA_HEADERS} ) target_link_libraries(xmlschema PUBLIC Qt${QT_MAJOR_VERSION}::Xml xmlcommon ) target_include_directories(xmlschema PUBLIC "$" ) set_target_properties(xmlschema PROPERTIES OUTPUT_NAME "xmlschema${kode_LIBRARY_QTID}") libkode-master/schema/annotation.cpp000066400000000000000000000045401472623201100200770ustar00rootroot00000000000000/* This file is part of KDE Schema Parser Copyright (c) 2006 Cornelius Schumacher This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "annotation.h" #include namespace XSD { class Annotation::Private { public: QDomElement mDomElement; }; Annotation::Annotation() : d(new Private) {} Annotation::Annotation(const QDomElement &element) : d(new Private) { d->mDomElement = element; } Annotation::Annotation(const Annotation &other) : d(new Private) { *d = *other.d; } Annotation::Annotation(Annotation &&other) : d(std::move(other.d)) {} Annotation::~Annotation() = default; Annotation &Annotation::operator=(const Annotation &other) { if (this == &other) { return *this; } *d = *other.d; return *this; } Annotation &Annotation::operator=(Annotation &&other) noexcept = default; void Annotation::setDomElement(const QDomElement &element) { d->mDomElement = element; } QDomElement Annotation::domElement() const { return d->mDomElement; } bool Annotation::isDocumentation() const { return QName(d->mDomElement.tagName()).localName() == QLatin1String("documentation"); } bool Annotation::isAppinfo() const { return QName(d->mDomElement.tagName()).localName() == QLatin1String("appinfo"); } QString Annotation::documentation() const { QString result; if (isDocumentation()) { result = d->mDomElement.text().trimmed(); } return result; } QString Annotation::List::documentation() const { QString result; for (const Annotation &a : *this) { result.append(a.documentation()); } return result; } } libkode-master/schema/annotation.h000066400000000000000000000033011472623201100175360ustar00rootroot00000000000000/* This file is part of KDE Schema Parser Copyright (c) 2006 Cornelius Schumacher This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef ANNOTATION_H #define ANNOTATION_H #include #include #include #include namespace XSD { class SCHEMA_EXPORT Annotation { public: class List : public QList { public: QString documentation() const; }; Annotation(); explicit Annotation(const QDomElement &element); Annotation(const Annotation &other); Annotation(Annotation &&other); ~Annotation(); Annotation &operator=(const Annotation &other); Annotation &operator=(Annotation &&other) noexcept; void setDomElement(const QDomElement &element); QDomElement domElement() const; bool isDocumentation() const; bool isAppinfo() const; QString documentation() const; private: class Private; std::unique_ptr d; }; } #endif libkode-master/schema/attribute.cpp000066400000000000000000000077551472623201100177430ustar00rootroot00000000000000/* This file is part of KDE Schema Parser Copyright (c) 2005 Tobias Koenig based on wsdlpull parser by Vivek Krishna This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "attribute.h" namespace XSD { class Attribute::Private { public: Private() : mQualified(false), mUse(Optional) {} QName mType; QString mDocumentation; QString mDefaultValue; QString mFixedValue; bool mQualified; AttributeUse mUse; QName mReference; bool operator==(const Attribute::Private &other) const { return mType == other.mType && mDefaultValue == other.mDefaultValue && mFixedValue == other.mFixedValue && mQualified == other.mQualified && mUse == other.mUse && mReference == other.mReference; } inline bool operator!=(const Attribute::Private &other) const { return !(*this == other); } }; Attribute::Attribute() : XmlElement(), d(new Private) {} Attribute::Attribute(const QString &nameSpace) : XmlElement(nameSpace), d(new Private) {} Attribute::Attribute(const Attribute &other) : XmlElement(other), d(new Private) { *d = *other.d; } Attribute::Attribute(Attribute &&other) : XmlElement(other), d(std::move(other.d)) {} Attribute::~Attribute() = default; Attribute &Attribute::operator=(const Attribute &other) { if (this == &other) { return *this; } *d = *other.d; XmlElement::operator=(other); return *this; } Attribute &Attribute::operator=(Attribute &&other) noexcept = default; void Attribute::setType(const QName &type) { Q_ASSERT(!type.isEmpty()); d->mType = type; } QName Attribute::type() const { return d->mType; } void Attribute::setDocumentation(const QString &documentation) { d->mDocumentation = documentation; } QString Attribute::documentation() const { return d->mDocumentation; } void Attribute::setDefaultValue(const QString &defaultValue) { d->mDefaultValue = defaultValue; } QString Attribute::defaultValue() const { return d->mDefaultValue; } void Attribute::setFixedValue(const QString &fixedValue) { d->mFixedValue = fixedValue; } QString Attribute::fixedValue() const { return d->mFixedValue; } void Attribute::setIsQualified(bool isQualified) { d->mQualified = isQualified; } bool Attribute::isQualified() const { return d->mQualified; } bool Attribute::isRequired() const { return d->mUse == Required; } // https://www.w3.org/TR/xmlschema-0/#ref36 void Attribute::setAttributeUse(AttributeUse use) { d->mUse = use; } Attribute::AttributeUse Attribute::attributeUse() const { return d->mUse; } void Attribute::setReference(const QName &reference) { Q_ASSERT(!reference.isEmpty()); d->mReference = reference; } QName Attribute::reference() const { return d->mReference; } bool Attribute::isResolved() const { return !d->mType.isEmpty() || d->mReference.isEmpty(); } void Attribute::List::dump() { Q_FOREACH (const Attribute &attr, *this) { qDebug() << attr.nameSpace() << attr.name(); } } bool Attribute::operator==(const Attribute &other) const { return XmlElement::operator==(other) && *d == *other.d; } } // namespace XSD QDebug operator<<(QDebug dbg, const XSD::Attribute &attr) { dbg << attr.qualifiedName(); return dbg; } libkode-master/schema/attribute.h000066400000000000000000000047341472623201100174020ustar00rootroot00000000000000/* This file is part of KDE Schema Parser Copyright (c) 2005 Tobias Koenig based on wsdlpull parser by Vivek Krishna This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef SCHEMA_ATTRIBUTE_H #define SCHEMA_ATTRIBUTE_H #include #include #include #include "xmlelement.h" #include namespace XSD { class SCHEMA_EXPORT Attribute : public XmlElement { public: class SCHEMA_EXPORT List : public QList { public: void dump(); }; Attribute(); explicit Attribute(const QString &nameSpace); Attribute(const Attribute &other); Attribute(Attribute &&other); ~Attribute(); Attribute &operator=(const Attribute &other); Attribute &operator=(Attribute &&other) noexcept; void setType(const QName &type); QName type() const; void setDocumentation(const QString &documentation); QString documentation() const; void setDefaultValue(const QString &defaultValue); QString defaultValue() const; void setFixedValue(const QString &fixedValue); QString fixedValue() const; void setIsQualified(bool isQualified); bool isQualified() const; bool isRequired() const; enum AttributeUse { Optional, Required, Prohibited }; void setAttributeUse(AttributeUse use); AttributeUse attributeUse() const; void setReference(const QName &reference); QName reference() const; bool isResolved() const; bool operator==(const Attribute &other) const; inline bool operator!=(const Attribute &other) const { return !(*this == other); } private: class Private; std::unique_ptr d; }; } SCHEMA_EXPORT QDebug operator<<(QDebug dbg, const XSD::Attribute &attr); #endif libkode-master/schema/attributegroup.cpp000066400000000000000000000045221472623201100210050ustar00rootroot00000000000000/* This file is part of KDE Schema Parser. Copyright (c) 2006 Cornelius Schumacher This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "attributegroup.h" namespace XSD { class AttributeGroup::Private { public: QName mReference; Attribute::List mAttributes; bool operator==(const AttributeGroup::Private &other) const { return mReference == other.mReference && mAttributes == other.mAttributes; } inline bool operator!=(const AttributeGroup::Private &other) const { return !(*this == other); } }; AttributeGroup::AttributeGroup() : XmlElement(), d(new Private) {} AttributeGroup::AttributeGroup(const AttributeGroup &other) : XmlElement(other), d(new Private) { *d = *other.d; } AttributeGroup::AttributeGroup(AttributeGroup &&other) : XmlElement(other), d(std::move(other.d)) {} AttributeGroup::~AttributeGroup() = default; AttributeGroup &AttributeGroup::operator=(const AttributeGroup &other) { if (this == &other) { return *this; } *d = *other.d; XmlElement::operator=(other); return *this; } AttributeGroup &AttributeGroup::operator=(AttributeGroup &&other) noexcept = default; void AttributeGroup::setReference(const QName &reference) { d->mReference = reference; } QName AttributeGroup::reference() const { return d->mReference; } void AttributeGroup::setAttributes(const Attribute::List &attributes) { d->mAttributes = attributes; } Attribute::List AttributeGroup::attributes() const { return d->mAttributes; } bool AttributeGroup::operator==(const AttributeGroup &other) const { return XmlElement::operator==(other) && *d == *other.d; } } libkode-master/schema/attributegroup.h000066400000000000000000000034271472623201100204550ustar00rootroot00000000000000/* This file is part of KDE Schema Parser. Copyright (c) 2006 Cornelius Schumacher This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef ATTRIBUTEGROUP_H #define ATTRIBUTEGROUP_H #include #include #include #include namespace XSD { class SCHEMA_EXPORT AttributeGroup : public XmlElement { public: typedef QList List; AttributeGroup(); AttributeGroup(const AttributeGroup &other); AttributeGroup(AttributeGroup &&other); ~AttributeGroup(); AttributeGroup &operator=(const AttributeGroup &other); AttributeGroup &operator=(AttributeGroup &&other) noexcept; void setReference(const QName &reference); QName reference() const; void setAttributes(const Attribute::List &attributes); Attribute::List attributes() const; bool operator==(const AttributeGroup &other) const; inline bool operator!=(const AttributeGroup &other) const { return !(*this == other); } private: class Private; std::unique_ptr d; }; } #endif libkode-master/schema/complextype.cpp000066400000000000000000000151231472623201100202750ustar00rootroot00000000000000/* This file is part of KDE Schema Parser Copyright (c) 2005 Tobias Koenig based on wsdlpull parser by Vivek Krishna This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "complextype.h" #include namespace XSD { class ComplexType::Private { public: Private() : mAnonymous(false), mConflicting(false), mBaseDerivation(Restriction) {} QString mDocumentation; Element::List mElements; Attribute::List mAttributes; Group::List mGroups; AttributeGroup::List mAttributeGroups; bool mAnonymous; bool mConflicting; Derivation mBaseDerivation; QName mBaseTypeName; QName mArrayType; QList mDerivedTypes; bool operator==(const ComplexType::Private &other) const { return mElements == other.mElements && mAttributes == other.mAttributes && mGroups == other.mGroups && mAttributeGroups == other.mAttributeGroups && mBaseDerivation == other.mBaseDerivation && mBaseTypeName == other.mBaseTypeName && mArrayType == other.mArrayType; } inline bool operator!=(const ComplexType::Private &other) const { return !(*this == other); } }; ComplexType::ComplexType(const QString &nameSpace) : XSDType(nameSpace), d(new Private) {} ComplexType::ComplexType() : XSDType(), d(new Private) {} ComplexType::ComplexType(const ComplexType &other) : XSDType(other), d(new Private) { *d = *other.d; } ComplexType::ComplexType(ComplexType &&other) : XSDType(other), d(std::move(other.d)) {} ComplexType::~ComplexType() = default; ComplexType &ComplexType::operator=(const ComplexType &other) { if (this == &other) { return *this; } XSDType::operator=(other); *d = *other.d; return *this; } ComplexType &ComplexType::operator=(ComplexType &&other) noexcept = default; void ComplexType::setDocumentation(const QString &documentation) { d->mDocumentation = documentation; } QString ComplexType::documentation() const { return d->mDocumentation; } void ComplexType::setBaseTypeName(const QName &baseTypeName) { d->mBaseTypeName = baseTypeName; } QName ComplexType::baseTypeName() const { return d->mBaseTypeName; } void ComplexType::addDerivedType(const QName &derivedTypeName) { d->mDerivedTypes.append(derivedTypeName); } QList ComplexType::derivedTypes() const { return d->mDerivedTypes; } void ComplexType::setBaseDerivation(Derivation derivation) { d->mBaseDerivation = derivation; } ComplexType::Derivation ComplexType::baseDerivation() const { return d->mBaseDerivation; } bool ComplexType::isSimple() const { return false; } bool ComplexType::isPolymorphicBaseClass() const { return !isArray() && !d->mDerivedTypes.isEmpty() && d->mBaseTypeName.isEmpty(); } void ComplexType::setArrayType(const QName &arrayType) { d->mArrayType = arrayType; } QName ComplexType::arrayType() const { return d->mArrayType; } bool ComplexType::isArray() const { return !arrayType().isEmpty(); } void ComplexType::setAnonymous(bool anonymous) { d->mAnonymous = anonymous; } bool ComplexType::isAnonymous() const { return d->mAnonymous; } void ComplexType::setConflicting(bool conflicting) { d->mConflicting = conflicting; } bool ComplexType::isConflicting() const { return d->mConflicting; } void ComplexType::setElements(const Element::List &elements) { d->mElements = elements; } Element::List ComplexType::elements() const { return d->mElements; } void ComplexType::setGroups(const Group::List &groups) { d->mGroups = groups; } void ComplexType::addGroup(const Group &group) { d->mGroups.append(group); } Group::List ComplexType::groups() const { return d->mGroups; } void ComplexType::setAttributes(const Attribute::List &attributes) { d->mAttributes = attributes; } Attribute::List ComplexType::attributes() const { return d->mAttributes; } void ComplexType::addAttributeGroups(const AttributeGroup &attributeGroups) { d->mAttributeGroups.append(attributeGroups); } void ComplexType::setAttributeGroups(const AttributeGroup::List &attributeGroups) { d->mAttributeGroups = attributeGroups; } AttributeGroup::List ComplexType::attributeGroups() const { return d->mAttributeGroups; } void ComplexType::addAttribute(const Attribute &attribute) { d->mAttributes.append(attribute); } Attribute ComplexType::attribute(const QName &attrName) const { Q_FOREACH (const Attribute &attr, d->mAttributes) { if (attr.qualifiedName() == attrName) { return attr; } } return Attribute(); } void ComplexType::addElement(const Element &element) { d->mElements.append(element); } bool ComplexType::isEmpty() const { return d->mAttributeGroups.isEmpty() && d->mGroups.isEmpty() && d->mAttributes.isEmpty() && d->mElements.isEmpty() && d->mBaseTypeName.isEmpty() && d->mArrayType.isEmpty(); } bool ComplexType::operator==(const ComplexType &other) const { return XSDType::operator==(other) && *d == *other.d; } ComplexType ComplexTypeList::complexType(const QName &qualifiedName) const { // qDebug() << "looking for" << typeName << "ns=" << typeName.nameSpace(); for (const ComplexType &type : std::as_const(*this)) { // qDebug() << type.nameSpace() << "qualifiedName=" << type.qualifiedName(); if (qualifiedName == type.qualifiedName()) { return type; } } // qDebug() << "Complex type" << qualifiedName << "not found"; return ComplexType(); } ComplexTypeList::iterator ComplexTypeList::findComplexType(const QName &qualifiedName) { for (iterator it = begin(); it != end(); ++it) if ((*it).qualifiedName() == qualifiedName) { return it; } return end(); } } // namespace XSD QDebug operator<<(QDebug dbg, const XSD::ComplexType &type) { dbg << type.qualifiedName(); // dbg << type.attributes(); return dbg; } libkode-master/schema/complextype.h000066400000000000000000000075031472623201100177450ustar00rootroot00000000000000/* This file is part of KDE Schema Parser Copyright (c) 2005 Tobias Koenig based on wsdlpull parser by Vivek Krishna This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef SCHEMA_COMPLEXTYPE_H #define SCHEMA_COMPLEXTYPE_H #include #include #include #include #include #include #include #include namespace XSD { class ComplexTypeList; class SCHEMA_EXPORT ComplexType : public XSDType { public: typedef ComplexTypeList List; typedef enum { Restriction, Extension } Derivation; ComplexType(); explicit ComplexType(const QString &nameSpace); ComplexType(const ComplexType &other); ComplexType(ComplexType &&other); ~ComplexType(); ComplexType &operator=(const ComplexType &other); ComplexType &operator=(ComplexType &&other) noexcept; void setDocumentation(const QString &documentation); QString documentation() const; bool isSimple() const override; // True if this is the base class for other (derived) complex types bool isPolymorphicBaseClass() const; void setAnonymous(bool anonymous); bool isAnonymous() const; void setConflicting(bool c); bool isConflicting() const; void setBaseDerivation(Derivation derivation); Derivation baseDerivation() const; void setBaseTypeName(const QName &baseTypeName); QName baseTypeName() const; void addDerivedType(const QName &derivedTypeName); QList derivedTypes() const; void setElements(const Element::List &elements); Element::List elements() const; void setGroups(const Group::List &groups); void addGroup(const Group &group); Group::List groups() const; void setAttributes(const Attribute::List &attributes); Attribute::List attributes() const; Attribute attribute(const QName &attrName) const; void addAttributeGroups(const AttributeGroup &attributeGroups); void setAttributeGroups(const AttributeGroup::List &attributeGroups); AttributeGroup::List attributeGroups() const; void setArrayType(const QName &arrayType); QName arrayType() const; bool isArray() const; void addAttribute(const Attribute &attribute); void addElement(const Element &element); bool isEmpty() const; bool operator==(const ComplexType &other) const; inline bool operator!=(const ComplexType &other) const { return !(*this == other); } private: class Private; std::unique_ptr d; }; class SCHEMA_EXPORT ComplexTypeList : public QList { public: ComplexTypeList(const QList &arg) : QList(arg) {} ComplexTypeList() : QList() {} // Readonly lookup, returns null type if not found ComplexType complexType(const QName &qualifiedName) const; // Mutable lookup (for making changes), returns end() if not found iterator findComplexType(const QName &qualifiedName); }; } // namespace XSD SCHEMA_EXPORT QDebug operator<<(QDebug dbg, const XSD::ComplexType &type); #endif libkode-master/schema/compositor.cpp000066400000000000000000000050401472623201100201170ustar00rootroot00000000000000/* This file is part of KDE Schema Parser Copyright (c) 2006 Cornelius Schumacher This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "compositor.h" namespace XSD { class Compositor::Private { public: Private() : mType(Invalid), mMinOccurs(1), mMaxOccurs(1) {} Type mType; QName::List mChildren; int mMinOccurs; int mMaxOccurs; }; Compositor::Compositor() : d(new Private) {} Compositor::Compositor(Type type) : d(new Private) { d->mType = type; } Compositor::Compositor(const Compositor &other) : d(new Private) { *d = *other.d; } Compositor::Compositor(Compositor &&other) : d(std::move(other.d)) {} Compositor::~Compositor() = default; Compositor &Compositor::operator=(const Compositor &other) { if (this == &other) { return *this; } *d = *other.d; return *this; } Compositor &Compositor::operator=(Compositor &&other) noexcept = default; bool Compositor::isValid() const { return d->mType != Invalid; } void Compositor::setMinOccurs(int minOccurs) { d->mMinOccurs = minOccurs; } int Compositor::minOccurs() const { return d->mMinOccurs; } void Compositor::setMaxOccurs(int maxOccurs) { d->mMaxOccurs = maxOccurs; } int Compositor::maxOccurs() const { return d->mMaxOccurs; } void Compositor::setType(Type type) { d->mType = type; } Compositor::Type Compositor::type() const { return d->mType; } QString Compositor::typeName() const { QMetaEnum metaEnum = QMetaEnum::fromType(); return metaEnum.valueToKey(d->mType); } void Compositor::addChild(const QName &child) { d->mChildren.append(child); } void Compositor::setChildren(const QName::List &children) { d->mChildren = children; } QName::List Compositor::children() const { return d->mChildren; } } libkode-master/schema/compositor.h000066400000000000000000000036271472623201100175750ustar00rootroot00000000000000/* This file is part of KDE Schema Parser Copyright (c) 2006 Cornelius Schumacher This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef SCHEMA_COMPOSITOR_H #define SCHEMA_COMPOSITOR_H #include #include #include #include #include namespace XSD { class SCHEMA_EXPORT Compositor { Q_GADGET public: typedef QList List; enum Type { Invalid, Choice, Sequence, All }; Q_ENUM(Type) Compositor(); explicit Compositor(Type type); Compositor(const Compositor &other); Compositor(Compositor &&other); ~Compositor(); Compositor &operator=(const Compositor &other); Compositor &operator=(Compositor &&other) noexcept; bool isValid() const; void setMinOccurs(int minOccurs); int minOccurs() const; void setMaxOccurs(int maxOccurs); int maxOccurs() const; void setType(Type type); Type type() const; QString typeName() const; void addChild(const QName &childName); void setChildren(const QName::List &children); QName::List children() const; private: class Private; std::unique_ptr d; }; } #endif libkode-master/schema/element.cpp000066400000000000000000000147201472623201100173570ustar00rootroot00000000000000/* This file is part of KDE Schema Parser Copyright (c) 2005 Tobias Koenig based on wsdlpull parser by Vivek Krishna This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "element.h" #include namespace XSD { class Element::Private { public: Private() : mGroupId(0), mMinOccurs(1), mMaxOccurs(1), mQualified(false), mNillable(false), mHasSubstitutions(false), mOccurrence(0) { } QName mType; QString mDocumentation; int mGroupId; int mMinOccurs; int mMaxOccurs; bool mQualified; bool mNillable; bool mHasSubstitutions; QString mDefaultValue; QString mFixedValue; int mOccurrence; QName mReference; Compositor mCompositor; bool operator==(const Element::Private &other) const { return mType == other.mType && mGroupId == other.mGroupId && mMinOccurs == other.mMinOccurs && mMaxOccurs == other.mMaxOccurs && mQualified == other.mQualified && mNillable == other.mNillable && mHasSubstitutions == other.mHasSubstitutions && mDefaultValue == other.mDefaultValue && mFixedValue == other.mFixedValue && mOccurrence == other.mOccurrence && mReference == other.mReference && mCompositor.type() == other.mCompositor.type(); } inline bool operator!=(const Element::Private &other) const { return !(*this == other); } }; Element::Element() : XmlElement(), d(new Private) {} Element::Element(const QString &nameSpace) : XmlElement(nameSpace), d(new Private) {} Element::Element(const Element &other) : XmlElement(other), d(new Private) { *d = *other.d; } Element::Element(Element &&other) : XmlElement(other), d(std::move(other.d)) {} Element::~Element() = default; Element &Element::operator=(const Element &other) { if (this == &other) { return *this; } *d = *other.d; XmlElement::operator=(other); return *this; } Element &Element::operator=(Element &&other) noexcept = default; void Element::setType(const QName &type) { Q_ASSERT(!type.isEmpty()); d->mType = type; } QName Element::type() const { return d->mType; } void Element::setDocumentation(const QString &documentation) { d->mDocumentation = documentation; } QString Element::documentation() const { return d->mDocumentation; } // unused void Element::setGroupId(int group) { d->mGroupId = group; } // unused int Element::groupId() const { return d->mGroupId; } void Element::setMinOccurs(int minOccurs) { d->mMinOccurs = minOccurs; } int Element::minOccurs() const { return d->mMinOccurs; } void Element::setMaxOccurs(int maxOccurs) { d->mMaxOccurs = maxOccurs; } int Element::maxOccurs() const { return d->mMaxOccurs; } void Element::setDefaultValue(const QString &defaultValue) { d->mDefaultValue = defaultValue; } QString Element::defaultValue() const { return d->mDefaultValue; } void Element::setFixedValue(const QString &fixedValue) { d->mFixedValue = fixedValue; } QString Element::fixedValue() const { return d->mFixedValue; } void Element::setIsQualified(bool isQualified) { d->mQualified = isQualified; } bool Element::isQualified() const { return d->mQualified; } void Element::setNillable(bool nillable) { d->mNillable = nillable; } bool Element::nillable() const { return d->mNillable; } void Element::setOccurrence(int occurrence) { d->mOccurrence = occurrence; } int Element::occurrence() const { return d->mOccurrence; } void Element::setReference(const QName &reference) { Q_ASSERT(!reference.isEmpty()); d->mReference = reference; } QName Element::reference() const { return d->mReference; } bool Element::isResolved() const { return !d->mType.isEmpty() || d->mReference.isEmpty(); } void Element::setCompositor(const Compositor &c) { d->mCompositor = c; } Compositor Element::compositor() const { return d->mCompositor; } void Element::setHasSubstitutions(bool hasSub) { d->mHasSubstitutions = hasSub; } bool Element::hasSubstitutions() const { return d->mHasSubstitutions; } bool Element::operator==(const Element &other) const { return XmlElement::operator==(other) && *d == *other.d; } Element ElementList::element(const QName &qualifiedName) const { const_iterator it = constBegin(); for (; it != constEnd(); ++it) if ((*it).qualifiedName() == qualifiedName) { return *it; } // qDebug() << "Simple type" << qualifiedName << "not found"; return Element(); } ElementList::iterator ElementList::findElement(const QName &qualifiedName) { for (iterator it = begin(); it != end(); ++it) if ((*it).qualifiedName() == qualifiedName) { return it; } return end(); } void ElementList::dump() { Q_FOREACH (const Element &element, *this) { qDebug() << element.nameSpace() << element.name(); } } bool ElementList::operator==(const ElementList &other) const { if (count() != other.count()) return false; // Ordered vs. unordered composition should be specified for a whole composition, but // as the Compositor::Type is determined during parsing (per element) // comparing per element should be semantically identic: for (int i = 0; i < count(); i++) { const Element &e = at(i); // ordered if (e.compositor().type() == Compositor::Sequence && other.at(i) != e) return false; // unordered else if (e.compositor().type() != Compositor::Sequence && !other.contains(e)) return false; } return true; } } // namespace XSD QDebug operator<<(QDebug dbg, const XSD::Element &element) { dbg << element.name(); return dbg; } libkode-master/schema/element.h000066400000000000000000000071611472623201100170250ustar00rootroot00000000000000/* This file is part of KDE Schema Parser Copyright (c) 2005 Tobias Koenig based on wsdlpull parser by Vivek Krishna This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef SCHEMA_ELEMENT_H #define SCHEMA_ELEMENT_H #include #include #include "xmlelement.h" #include "compositor.h" #include namespace XSD { class ElementList; class SCHEMA_EXPORT Element : public XmlElement { public: typedef ElementList List; Element(); explicit Element(const QString &nameSpace); Element(const Element &other); Element(Element &&other); ~Element(); Element &operator=(const Element &other); Element &operator=(Element &&other) noexcept; void setType(const QName &type); QName type() const; void setDocumentation(const QString &documentation); QString documentation() const; void setGroupId(int group); int groupId() const; void setMinOccurs(int minOccurs); int minOccurs() const; void setMaxOccurs(int maxOccurs); int maxOccurs() const; void setDefaultValue(const QString &defaultValue); QString defaultValue() const; void setFixedValue(const QString &fixedValue); QString fixedValue() const; void setIsQualified(bool isQualified); bool isQualified() const; void setNillable(bool nillable); bool nillable() const; void setOccurrence(int occurrence); int occurrence() const; void setReference(const QName &reference); QName reference() const; bool isResolved() const; void setCompositor(const Compositor &); Compositor compositor() const; /** * Makes a note that this element has substitutions available. * * Example: * * * will note in the element "Path" that substitutions exist. */ void setHasSubstitutions(bool hasSub); /** * @return true if this element is the base element of a substitution group. */ bool hasSubstitutions() const; bool operator==(const Element &other) const; inline bool operator!=(const Element &other) const { return !(*this == other); } private: class Private; std::unique_ptr d; }; class SCHEMA_EXPORT ElementList : public QList { public: // Readonly lookup, returns null element if not found Element element(const QName &qualifiedName) const; // Mutable lookup (for making changes), returns end() if not found iterator findElement(const QName &qualifiedName); // For debugging void dump(); bool operator==(const ElementList &other) const; inline bool operator!=(const ElementList &other) const { return !(*this == other); } }; } SCHEMA_EXPORT QDebug operator<<(QDebug dbg, const XSD::Element &element); #endif libkode-master/schema/group.cpp000066400000000000000000000044321472623201100170610ustar00rootroot00000000000000/* This file is part of KDE Schema Parser. Copyright (c) 2013 David Faure This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "group.h" namespace XSD { class Group::Private { public: QName mReference; Element::List mElements; bool operator==(const Group::Private &other) const { return mReference == other.mReference && mElements == other.mElements; } inline bool operator!=(const Group::Private &other) const { return !(*this == other); } }; Group::Group() : XmlElement(), d(new Private) {} Group::Group(const Group &other) : XmlElement(other), d(new Private) { *d = *other.d; } Group::Group(Group &&other) : XmlElement(other), d(std::move(other.d)) {} Group::~Group() = default; Group &Group::operator=(const Group &other) { if (this == &other) { return *this; } *d = *other.d; XmlElement::operator=(other); return *this; } Group &Group::operator=(Group &&other) noexcept = default; void Group::setReference(const QName &reference) { d->mReference = reference; } QName Group::reference() const { return d->mReference; } void Group::setElements(const Element::List &elements) { d->mElements = elements; } Element::List Group::elements() const { return d->mElements; } bool Group::isResolved() const { return !d->mElements.isEmpty() || d->mReference.isEmpty(); } bool Group::operator==(const Group &other) const { return XmlElement::operator==(other) && *d == *other.d; } } QDebug operator<<(QDebug dbg, const XSD::Group &group) { dbg << group.qualifiedName(); return dbg; } libkode-master/schema/group.h000066400000000000000000000016521472623201100165270ustar00rootroot00000000000000#ifndef GROUP_H #define GROUP_H #include #include #include #include #include namespace XSD { class SCHEMA_EXPORT Group : public XmlElement { public: typedef QList List; Group(); Group(const Group &other); Group(Group &&other); ~Group() override; Group &operator=(const Group &other); Group &operator=(Group &&other) noexcept; void setReference(const QName &reference); QName reference() const; void setElements(const Element::List &elements); Element::List elements() const; bool isResolved() const; bool operator==(const Group &other) const; inline bool operator!=(const Group &other) const { return !(*this == other); } private: class Private; std::unique_ptr d; }; } SCHEMA_EXPORT QDebug operator<<(QDebug dbg, const XSD::Group &group); #endif // GROUP_H libkode-master/schema/parser.cpp000066400000000000000000001622521472623201100172260ustar00rootroot00000000000000/* This file is part of KDE Schema Parser Copyright (c) 2005 Tobias Koenig Copyright (c) 2006 MichaĆ«l Larouche based on wsdlpull parser by Vivek Krishna This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include #include #include #include #include #include #include #include "parser.h" static const QString XMLSchemaURI(QLatin1String("http://www.w3.org/2001/XMLSchema")); static const QString WSDLSchemaURI(QLatin1String("http://schemas.xmlsoap.org/wsdl/")); static const QString soapEncNs = QLatin1String("http://schemas.xmlsoap.org/soap/encoding/"); static const QString soap12EncNs = QLatin1String("http://www.w3.org/2003/05/soap-encoding"); Q_LOGGING_CATEGORY(parser, "libkode.parser", QtWarningMsg) namespace XSD { static bool stringToBoolean(const QString &str) { return str == QLatin1String("true") || str == QChar::fromLatin1('1'); } class Parser::Private { public: QString mNameSpace; SimpleType::List mSimpleTypes; ComplexType::List mComplexTypes; Element::List mElements; Attribute::List mAttributes; Group::List mGroups; AttributeGroup::List mAttributeGroups; Annotation::List mAnnotations; QStringList mImportedSchemas; QStringList mIncludedSchemas; QMap mLocalSchemas; bool mDefaultQualifiedElements = false; bool mDefaultQualifiedAttributes = false; bool mUseLocalFilesOnly = false; QStringList mImportPathList; }; Parser::Parser(ParserContext *context, const QString &nameSpace, bool useLocalFilesOnly, const QStringList &importPathList) : d(new Private) { d->mNameSpace = nameSpace; d->mUseLocalFilesOnly = useLocalFilesOnly; d->mImportPathList = importPathList; init(context); } Parser::Parser(const QString &nameSpace) : d(new Private) { d->mNameSpace = nameSpace; } Parser::Parser(const Parser &other) : d(new Private) { *d = *other.d; } Parser::Parser(Parser &&other) : d(std::move(other.d)) {} Parser::~Parser() { clear(); // why? } Parser &Parser::operator=(const Parser &other) { if (this == &other) { return *this; } *d = *other.d; return *this; } Parser &Parser::operator=(Parser &&other) noexcept = default; void Parser::setLocalSchemas(const QMap &localSchemas) { d->mLocalSchemas = localSchemas; } void Parser::clear() { d->mImportedSchemas.clear(); d->mComplexTypes.clear(); d->mSimpleTypes.clear(); d->mElements.clear(); d->mGroups.clear(); d->mAttributes.clear(); d->mAttributeGroups.clear(); } void Parser::init(ParserContext *context) { #if 0 if (!parseFile(context, ":/schema/XMLSchema.xsd")) { qWarning("Error parsing builtin file XMLSchema.xsd"); } #else Q_UNUSED(context); #endif // From the XML schema XSD { Element schema(XMLSchemaURI); schema.setName(QLatin1String("schema")); schema.setType(QName(XMLSchemaURI, QLatin1String("anyType"))); d->mElements.append(schema); } d->mImportedSchemas.append(XMLSchemaURI); d->mImportedSchemas.append(NSManager::xmlNamespace()); // Define xml:lang, since we don't parse xml.xsd { Attribute langAttr(NSManager::xmlNamespace()); langAttr.setName(QLatin1String("lang")); langAttr.setType(QName(XMLSchemaURI, QLatin1String("string"))); d->mAttributes.append(langAttr); } } bool Parser::parseSchemaTag(ParserContext *context, const QDomElement &root) { QName name(root.tagName()); if (name.localName() != QLatin1String("schema")) { qDebug() << "ERROR localName=" << name.localName(); return false; } // Already done by caller when coming from type.cpp, but doesn't hurt to do twice context->namespaceManager()->enterChild(root); // This method can call itself recursively, so save/restore the member attribute. const QString oldNamespace = d->mNameSpace; const bool oldDefaultQualifiedElements = d->mDefaultQualifiedElements; const bool oldDefaultQualifiedAttributes = d->mDefaultQualifiedAttributes; if (root.hasAttribute(QLatin1String("targetNamespace"))) { d->mNameSpace = root.attribute(QLatin1String("targetNamespace")); } if (root.attribute(QLatin1String("elementFormDefault")) == QLatin1String("qualified")) { d->mDefaultQualifiedElements = true; } if (root.attribute(QLatin1String("attributeFormDefault")) == QLatin1String("qualified")) { d->mDefaultQualifiedAttributes = true; } // mTypesTable.setTargetNamespace( mNameSpace ); QDomElement element = root.firstChildElement(); while (!element.isNull()) { NSManager namespaceManager(context, element); const QName name(element.tagName()); qCDebug(parser) << "Schema: parsing" << name.localName(); if (name.localName() == QLatin1String("import")) { parseImport(context, element); } else if (name.localName() == QLatin1String("element")) { addGlobalElement(parseElement(context, element, d->mNameSpace, element)); } else if (name.localName() == QLatin1String("complexType")) { ComplexType ct = parseComplexType(context, element); // add elements from parsed complexType into mElements too for (const auto &subelem : ct.elements()) { d->mElements.append(subelem); } d->mComplexTypes.append(ct); } else if (name.localName() == QLatin1String("simpleType")) { SimpleType st = parseSimpleType(context, element); d->mSimpleTypes.append(st); } else if (name.localName() == QLatin1String("attribute")) { addGlobalAttribute(parseAttribute(context, element, d->mNameSpace)); } else if (name.localName() == QLatin1String("attributeGroup")) { d->mAttributeGroups.append(parseAttributeGroup(context, element, d->mNameSpace)); } else if (name.localName() == QLatin1String("group")) { d->mGroups.append(parseGroup(context, element, d->mNameSpace)); } else if (name.localName() == QLatin1String("annotation")) { d->mAnnotations = parseAnnotation(context, element); } else if (name.localName() == QLatin1String("include")) { parseInclude(context, element); } else { qWarning() << "Unsupported schema element" << name.localName(); } element = element.nextSiblingElement(); } resolveForwardDeclarations(); d->mImportedSchemas.append(d->mNameSpace); d->mNameSpace = oldNamespace; d->mDefaultQualifiedElements = oldDefaultQualifiedElements; d->mDefaultQualifiedAttributes = oldDefaultQualifiedAttributes; return true; } void Parser::parseImport(ParserContext *context, const QDomElement &element) { // https://www.w3.org/TR/2004/REC-xmlschema-1-20041028/structures.html#layer2 // The actual value of its namespace [attribute] indicates that the containing schema document // may contain qualified references to schema components in that namespace (via one or more // prefixes declared with namespace declarations in the normal way). QString expectedNamespace = element.attribute(QLatin1String("namespace")); QString location = element.attribute(QLatin1String("schemaLocation")); if (location.isEmpty()) { // Testcase: in the WSDL at // https://www.elogbook.org/logbookws/logbookifv3.asmx // When no schemaLocation [attribute] is present, the schema author is leaving the // identification of that schema to the instance, application or user, via the mechanisms // described below in Layer 3: Schema Document Access and Web-interoperability (§4.3). 4.3.2 // is especially crazy in terms of "do whatever you can or want" Some implementations seem // to just use the namespace as a schema location, let's try that if (!expectedNamespace.isEmpty()) { location = expectedNamespace; } else { return; // means nothing to us } } // don't import a schema twice if (d->mImportedSchemas.contains(location)) { return; } else { d->mImportedSchemas.append(location); } importSchema(context, location); } void Parser::parseInclude(ParserContext *context, const QDomElement &element) { QString location = element.attribute(QLatin1String("schemaLocation")); if (!location.isEmpty()) { // don't include a schema twice if (d->mIncludedSchemas.contains(location)) { return; } else { d->mIncludedSchemas.append(location); } includeSchema(context, location); } else { context->messageHandler()->warning( QString::fromLatin1("include tag found at (%1, %2) contains no schemaLocation tag.") .arg(element.lineNumber(), element.columnNumber())); } } Annotation::List Parser::parseAnnotation(ParserContext *context, const QDomElement &element) { Annotation::List result; QDomElement child; for (child = element.firstChildElement(); !child.isNull(); child = child.nextSiblingElement()) { NSManager namespaceManager(context, child); const QName name(child.tagName()); if (name.localName() == QLatin1String("documentation")) { result.append(Annotation(child)); } else if (name.localName() == QLatin1String("appinfo")) { result.append(Annotation(child)); } } return result; } ComplexType Parser::parseComplexType(ParserContext *context, const QDomElement &element) { ComplexType newType(d->mNameSpace); newType.setName(element.attribute(QLatin1String("name"))); qCDebug(parser) << "complexType:" << d->mNameSpace << newType.name(); if (element.hasAttribute(QLatin1String("mixed"))) { newType.setContentModel(XSDType::MIXED); } QDomElement childElement = element.firstChildElement(); AttributeGroup::List attributeGroups; Group::List groups; while (!childElement.isNull()) { NSManager namespaceManager(context, childElement); const QName name(childElement.tagName()); if (name.localName() == QLatin1String("all")) { all(context, childElement, newType); } else if (name.localName() == QLatin1String("sequence") || name.localName() == QLatin1String("choice")) { Element::List elems; parseCompositor(context, childElement, newType.nameSpace(), &elems, &groups); for (const Element &elem : std::as_const(elems)) { newType.addElement(elem); } } else if (name.localName() == QLatin1String("attribute")) { newType.addAttribute(parseAttribute(context, childElement, d->mNameSpace)); } else if (name.localName() == QLatin1String("attributeGroup")) { attributeGroups.append(parseAttributeGroup(context, childElement, d->mNameSpace)); } else if (name.localName() == QLatin1String("group")) { groups.append(parseGroup(context, childElement, newType.nameSpace())); } else if (name.localName() == QLatin1String("anyAttribute")) { addAnyAttribute(context, childElement, newType); } else if (name.localName() == QLatin1String("complexContent")) { parseComplexContent(context, childElement, newType); } else if (name.localName() == QLatin1String("simpleContent")) { parseSimpleContent(context, childElement, newType); } else if (name.localName() == QLatin1String("annotation")) { Annotation::List annotations = parseAnnotation(context, childElement); newType.setDocumentation(annotations.documentation()); newType.setAnnotations(annotations); } else { qWarning() << "Unsupported complextype element" << name.localName(); } childElement = childElement.nextSiblingElement(); } newType.setAttributeGroups(attributeGroups); newType.setGroups(groups); return newType; } void Parser::all(ParserContext *context, const QDomElement &element, ComplexType &ct) { QDomElement childElement = element.firstChildElement(); while (!childElement.isNull()) { NSManager namespaceManager(context, childElement); const QName name(childElement.tagName()); if (name.localName() == QLatin1String("element")) { ct.addElement(parseElement(context, childElement, ct.nameSpace(), childElement)); } else if (name.localName() == QLatin1String("annotation")) { Annotation::List annotations = parseAnnotation(context, childElement); ct.setDocumentation(annotations.documentation()); ct.setAnnotations(annotations); } else { qWarning() << "Unsupported all element" << name.localName(); } childElement = childElement.nextSiblingElement(); } } static int readMaxOccurs(const QDomElement &element) { const QString value = element.attribute(QLatin1String("maxOccurs"), QLatin1String("1")); if (value == QLatin1String("unbounded")) { return Parser::UNBOUNDED; } else { return value.toInt(); } } void Parser::parseCompositor(ParserContext *context, const QDomElement &element, const QString &nameSpace, Element::List *elements, Group::List *groups) { const QName name(element.tagName()); bool isChoice = name.localName() == QLatin1String("choice"); bool isSequence = name.localName() == QLatin1String("sequence"); Compositor compositor; if (isChoice) { compositor.setType(Compositor::Choice); } else if (isSequence) { compositor.setType(Compositor::Sequence); } compositor.setMinOccurs( element.attribute(QLatin1String("minOccurs"), QLatin1String("1")).toInt()); compositor.setMaxOccurs(readMaxOccurs(element)); if (isChoice || isSequence) { QDomElement childElement = element.firstChildElement(); while (!childElement.isNull()) { NSManager namespaceManager(context, childElement); const QName csName(childElement.tagName()); const QString localName = csName.localName(); if (localName == QLatin1String("element")) { Element newElement; if (isChoice) { newElement = parseElement(context, childElement, nameSpace, element); } else { newElement = parseElement(context, childElement, nameSpace, childElement); } newElement.setCompositor(compositor); elements->append(newElement); compositor.addChild(csName); } else if (localName == QLatin1String("any")) { elements->append(parseAny(context, childElement, nameSpace)); } else if (localName == QLatin1String("choice") || localName == QLatin1String("sequence")) { parseCompositor(context, childElement, nameSpace, elements, groups); } else if (localName == QLatin1String("group")) { groups->append(parseGroup(context, childElement, nameSpace)); } else if (localName == QLatin1String("annotation")) { // Not implemented // Annotation::List annotations = parseAnnotation( context, childElement ); // compositor.setDocumentation( annotations.documentation() ); // compositor.setAnnotations( annotations ); } else { qDebug() << "Unsupported element in" << name << ":" << csName; } childElement = childElement.nextSiblingElement(); } } } Element Parser::parseElement(ParserContext *context, const QDomElement &element, const QString &nameSpace, const QDomElement &occurrenceElement) { Element newElement(nameSpace); newElement.setName(element.attribute(QLatin1String("name"))); qCDebug(parser) << "newElement namespace=" << nameSpace << "name=" << newElement.name() << "defaultQualified=" << d->mDefaultQualifiedElements; // https://www.w3.org/TR/xmlschema-0/#NS if (element.hasAttribute(QLatin1String("form"))) { newElement.setIsQualified(element.attribute(QLatin1String("form")) == QLatin1String("qualified")); } else { newElement.setIsQualified(d->mDefaultQualifiedElements); } if (element.hasAttribute(QLatin1String("ref"))) { QName reference(element.attribute(QLatin1String("ref"))); reference.setNameSpace(context->namespaceManager()->uri(reference.prefix())); newElement.setReference(reference); } setOccurrenceAttributes(newElement, occurrenceElement); newElement.setDefaultValue(element.attribute(QLatin1String("default"))); newElement.setFixedValue(element.attribute(QLatin1String("fixed"))); newElement.setNillable(stringToBoolean(element.attribute(QLatin1String("nillable")))); if (element.hasAttribute(QLatin1String("type"))) { QName typeName(element.attribute(QLatin1String("type")).trimmed()); typeName.setNameSpace(context->namespaceManager()->uri(typeName.prefix())); qCDebug(parser) << "typeName=" << typeName.qname() << "namespace=" << context->namespaceManager()->uri(typeName.prefix()); newElement.setType(typeName); if (element.hasAttribute(QLatin1String("substitutionGroup"))) { QName baseElementName(element.attribute(QLatin1String("substitutionGroup"))); baseElementName.setNameSpace( context->namespaceManager()->uri(baseElementName.prefix())); XSD::Element::List::iterator ctit_base = d->mElements.findElement(baseElementName); if (ctit_base != d->mElements.end()) { XSD::Element &baseElem = *ctit_base; // Record that the base element has substitutions baseElem.setHasSubstitutions(true); // Its type will need a virtual method _kd_substitutionElementName so fill in the // base type too. (OK, we do that for each derived type, but well) const QName baseType = baseElem.type(); setSubstitutionElementName(baseType, baseElem.qualifiedName()); } else { qWarning() << "Element" << newElement.qualifiedName() << "uses undefined element as substitutionGroup" << baseElementName; } setSubstitutionElementName(typeName, newElement.qualifiedName()); } } else { QDomElement childElement = element.firstChildElement(); while (!childElement.isNull()) { NSManager namespaceManager(context, childElement); const QName childName(childElement.tagName()); // qDebug() << "childName:" << childName.localName(); if (childName.localName() == QLatin1String("complexType")) { ComplexType ct = parseComplexType(context, childElement); ct.setAnonymous(true); ct.setName(newElement.name()); int i = 0; bool typeExists = false; ComplexType existingType = d->mComplexTypes.complexType(QName(ct.nameSpace(), ct.name())); while (!existingType.isNull()) { if (existingType == ct) { qCDebug(parser) << " Nested complexType of name" << ct.name() << "is structurally identical with existing complexType of " "the same name, skipping this instance..."; typeExists = true; break; } else { ct.setName(newElement.name() + QString::number(++i)); existingType = d->mComplexTypes.complexType(QName(ct.nameSpace(), ct.name())); } } if (!typeExists) { d->mComplexTypes.append(ct); if (newElement.name() != ct.name()) qCDebug(parser) << " Detected type collision for nested complexType, updated name" << newElement.name() << "to" << ct.name(); qCDebug(parser) << " found nested complexType element, type name is now " << "element name, i.e. " << ct.name() << "newElement.setType" << ct.qualifiedName(); } newElement.setType(ct.qualifiedName()); } else if (childName.localName() == QLatin1String("simpleType")) { SimpleType st = parseSimpleType(context, childElement); st.setName(newElement.name()); d->mSimpleTypes.append(st); newElement.setType(st.qualifiedName()); } else if (childName.localName() == QLatin1String("annotation")) { Annotation::List annotations = parseAnnotation(context, childElement); newElement.setDocumentation(annotations.documentation()); newElement.setAnnotations(annotations); } childElement = childElement.nextSiblingElement(); } } // Fixup elements without a type if (newElement.type().isEmpty() && newElement.reference().isEmpty()) { ComplexType ct; Q_ASSERT(!newElement.name().isEmpty()); ct.setNameSpace(newElement.nameSpace()); ct.setName(newElement.name()); ct.setAnonymous(true); d->mComplexTypes.append(ct); newElement.setType(ct.qualifiedName()); } return newElement; } void Parser::setSubstitutionElementName(const QName &typeName, const QName &elemName) { XSD::ComplexType::List::iterator ctit = d->mComplexTypes.findComplexType(typeName); if (ctit != d->mComplexTypes.end()) { // If this type already has an element name associated, they are aliases, any one will do. (*ctit).setSubstitutionElementName(elemName); } else { XSD::SimpleType::List::iterator stit = d->mSimpleTypes.findSimpleType(typeName); if (stit != d->mSimpleTypes.end()) { (*stit).setSubstitutionElementName(elemName); } else { qWarning() << "Element" << elemName << "uses undefined type" << typeName; } } } // Testcase: salesforce-partner.wsdl has Element Parser::parseAny(ParserContext *, const QDomElement &element, const QString &nameSpace) { Element newElement(nameSpace); newElement.setName(QLatin1String("any")); QName anyType(QLatin1String("http://www.w3.org/2001/XMLSchema"), QLatin1String("any")); newElement.setType(anyType); setOccurrenceAttributes(newElement, element); return newElement; } void Parser::setOccurrenceAttributes(Element &newElement, const QDomElement &element) { newElement.setMinOccurs( element.attribute(QLatin1String("minOccurs"), QLatin1String("1")).toInt()); newElement.setMaxOccurs(readMaxOccurs(element)); } void Parser::addAnyAttribute(ParserContext *, const QDomElement &element, ComplexType &complexType) { Attribute newAttribute; newAttribute.setName(QLatin1String("anyAttribute")); newAttribute.setNameSpace(element.attribute(QLatin1String("namespace"))); // ### Hmm, technically, this should be a list of anys, I think. newAttribute.setType(QName(XMLSchemaURI, QString::fromLatin1("anyType"))); complexType.addAttribute(newAttribute); } Attribute Parser::parseAttribute(ParserContext *context, const QDomElement &element, const QString &nameSpace) { Attribute newAttribute; newAttribute.setName(element.attribute(QLatin1String("name"))); newAttribute.setNameSpace(nameSpace); if (element.hasAttribute(QLatin1String("type"))) { // TODO pass nsmanager to QName so that it can resolve namespaces? QName typeName(element.attribute(QLatin1String("type"))); typeName.setNameSpace(context->namespaceManager()->uri(typeName.prefix())); newAttribute.setType(typeName); } // https://www.w3.org/TR/xmlschema-0/#NS if (element.hasAttribute(QLatin1String("form"))) { newAttribute.setIsQualified(element.attribute(QLatin1String("form")) == QLatin1String("qualified")); } else { newAttribute.setIsQualified(d->mDefaultQualifiedAttributes); } if (element.hasAttribute(QLatin1String("ref"))) { QName reference(element.attribute(QLatin1String("ref"))); reference.setNameSpace(context->namespaceManager()->uri(reference.prefix())); newAttribute.setReference(reference); } newAttribute.setDefaultValue(element.attribute(QLatin1String("default"))); newAttribute.setFixedValue(element.attribute(QLatin1String("fixed"))); if (element.hasAttribute(QLatin1String("use"))) { const QString use = element.attribute(QLatin1String("use")); if (use == QLatin1String("optional")) { newAttribute.setAttributeUse(Attribute::Optional); } else if (use == QLatin1String("required")) { newAttribute.setAttributeUse(Attribute::Required); } else if (use == QLatin1String("prohibited")) { qWarning("prohibited attributes are not supported"); // TODO skip parsing the attribute // altogether newAttribute.setAttributeUse(Attribute::Prohibited); } } QDomElement childElement = element.firstChildElement(); while (!childElement.isNull()) { NSManager namespaceManager(context, childElement); const QName childName(childElement.tagName()); if (childName.localName() == QLatin1String("simpleType")) { SimpleType st = parseSimpleType(context, childElement); st.setName(newAttribute.name()); d->mSimpleTypes.append(st); newAttribute.setType(st.qualifiedName()); } else if (childName.localName() == QLatin1String("annotation")) { Annotation::List annotations = parseAnnotation(context, childElement); newAttribute.setDocumentation(annotations.documentation()); newAttribute.setAnnotations(annotations); } childElement = childElement.nextSiblingElement(); } if (newAttribute.type().isEmpty() && !element.hasAttribute(QLatin1String("ref"))) { // https://www.w3.org/TR/2004/REC-xmlschema-1-20041028/structures.html#element-attribute // says "otherwise the simple ur-type definition", which is anySimpleType newAttribute.setType(QName(XMLSchemaURI, QLatin1String("anySimpleType"))); qDebug() << "found attribute" << newAttribute.name() << "without type and without ref, set to default" << newAttribute.type(); } return newAttribute; } SimpleType Parser::parseSimpleType(ParserContext *context, const QDomElement &element) { SimpleType st(d->mNameSpace); st.setName(element.attribute(QLatin1String("name"))); qCDebug(parser) << "simpleType:" << d->mNameSpace << st.name(); QDomElement childElement = element.firstChildElement(); while (!childElement.isNull()) { NSManager namespaceManager(context, childElement); const QName name(childElement.tagName()); if (name.localName() == QLatin1String("restriction")) { st.setSubType(SimpleType::TypeRestriction); QName typeName(childElement.attribute(QLatin1String("base"))); typeName.setNameSpace(context->namespaceManager()->uri(typeName.prefix())); st.setBaseTypeName(typeName); parseRestriction(context, childElement, st); } else if (name.localName() == QLatin1String("union")) { st.setSubType(SimpleType::TypeUnion); // It means "the contents can be either one of my child elements, or one of the types // listed in memberTypes". For now we'll just use QVariant. For more compile-time // checking we would need to actually parse and store the references to the possible // types. And then generate methods for each; but we won't have a good name for these // methods, just some type name... setSizebyno / setSizebystring reads weird. st.setBaseTypeName( QName(XMLSchemaURI, QString::fromLatin1("anyType"))); // to get QVariant } else if (name.localName() == QLatin1String("list")) { st.setSubType(SimpleType::TypeList); if (childElement.hasAttribute(QLatin1String("itemType"))) { QName typeName(childElement.attribute(QLatin1String("itemType"))); if (!typeName.prefix().isEmpty()) { typeName.setNameSpace(context->namespaceManager()->uri(typeName.prefix())); } else { typeName.setNameSpace(st.nameSpace()); } st.setListTypeName(typeName); } else { // Anonymous type QDomElement typeElement = childElement.firstChildElement(); for (; !typeElement.isNull(); typeElement = typeElement.nextSiblingElement()) { NSManager namespaceManager(context, typeElement); const QName typeName(typeElement.tagName()); // qDebug() << "childName:" << childName.localName(); if (typeName.localName() == QLatin1String("complexType")) { ComplexType ctItem = parseComplexType(context, typeElement); ctItem.setName( st.name() + QLatin1String("ListItem")); // need to make something up, so that // the classname looks good st.setListTypeName(ctItem.qualifiedName()); d->mComplexTypes.append(ctItem); } else if (typeName.localName() == QLatin1String("simpleType")) { SimpleType stItem = parseSimpleType(context, typeElement); stItem.setName( st.name() + QLatin1String("ListItem")); // need to make something up, so that // the classname looks good st.setListTypeName(stItem.qualifiedName()); d->mSimpleTypes.append(stItem); } else { qDebug() << "ERROR: parseSimpleType: unhandled: " << typeName.localName() << "in list" << d->mNameSpace << st.name(); } } } } else if (name.localName() == QLatin1String("annotation")) { Annotation::List annotations = parseAnnotation(context, childElement); st.setDocumentation(annotations.documentation()); st.setAnnotations(annotations); } childElement = childElement.nextSiblingElement(); } return st; } void Parser::parseRestriction(ParserContext *context, const QDomElement &element, SimpleType &st) { if (st.baseTypeName().isEmpty()) { qDebug(": unknown BaseType"); } QDomElement childElement = element.firstChildElement(); while (!childElement.isNull()) { NSManager namespaceManager(context, childElement); const QName tagName(childElement.tagName()); if (tagName.localName() == QLatin1String("annotation")) { // Skip annotations here. } else { SimpleType::FacetType ft = st.parseFacetId(tagName.localName()); if (ft == SimpleType::NONE) { qDebug(": %s is not a valid facet for the simple type '%s'", qPrintable(childElement.tagName()), qPrintable(st.name())); } else { st.setFacetValue(ft, childElement.attribute(QLatin1String("value"))); } } childElement = childElement.nextSiblingElement(); } } void Parser::parseComplexContent(ParserContext *context, const QDomElement &element, ComplexType &complexType) { QName typeName; complexType.setContentModel(XSDType::COMPLEX); QDomElement childElement = element.firstChildElement(); while (!childElement.isNull()) { NSManager namespaceManager(context, childElement); const QName name(childElement.tagName()); if (name.localName() == QLatin1String("restriction") || name.localName() == QLatin1String("extension")) { typeName = childElement.attribute(QLatin1String("base")); typeName.setNameSpace(context->namespaceManager()->uri(typeName.prefix())); // if the base soapenc:Array, then read the arrayType attribute, and possibly the // desired name for the child elements // TODO check namespace is really soap-encoding if (typeName.localName() == QLatin1String("Array")) { QString typeStr; QString arrayElementStr; QDomElement arrayElement = childElement.firstChildElement(); while (!arrayElement.isNull()) { NSManager namespaceManager(context, arrayElement); const QName tagName(arrayElement.tagName()); if (context->namespaceManager()->uri(tagName.prefix()) == XMLSchemaURI) { const QString localName = tagName.localName(); if (localName == QLatin1String("attribute")) { const QString prefix = context->namespaceManager()->prefix(WSDLSchemaURI); const QString attributeName = (prefix.isEmpty() ? QString::fromLatin1("arrayType") : prefix + QLatin1String(":arrayType")); typeStr = arrayElement.attribute(attributeName); if (typeStr.isEmpty()) { qWarning("ERROR: arrayType attribute missing in Array element."); } if (typeStr.endsWith(QLatin1String("[]"))) { typeStr.truncate(typeStr.length() - 2); } } else if (localName == QLatin1String("sequence")) { // detosagent-legacy.wsdl arrayElement = arrayElement.firstChildElement(); // go down } if (QName(arrayElement.tagName()).localName() == QLatin1String("element")) { arrayElementStr = arrayElement.attribute("name"); if (localName == QLatin1String("sequence")) { // go up again arrayElement = arrayElement.parentNode().toElement(); } } } arrayElement = arrayElement.nextSiblingElement(); } if (typeStr.isEmpty()) { qWarning("ERROR: element not found"); } else { if (arrayElementStr.isEmpty()) { arrayElementStr = QLatin1String("items"); // we have to call it something... } QName arrayType(typeStr); arrayType.setNameSpace(context->namespaceManager()->uri(arrayType.prefix())); complexType.setArrayType(arrayType); Element items(complexType.nameSpace()); items.setName(arrayElementStr); items.setType(arrayType); // items.setArrayType( arrayType ); complexType.addElement(items); // qDebug() << complexType.name() << "is array of" << arrayType; } } else { if (typeName != QName( XMLSchemaURI, QString::fromLatin1("anyType"))) { // don't do this for anyType or Array complexType.setBaseTypeName(typeName); } QDomElement ctElement = childElement.firstChildElement(); while (!ctElement.isNull()) { NSManager namespaceManager(context, ctElement); const QName name(ctElement.tagName()); if (name.localName() == QLatin1String("all")) { all(context, ctElement, complexType); } else if (name.localName() == QLatin1String("sequence") || name.localName() == QLatin1String("choice")) { Element::List elems; Group::List groups; parseCompositor(context, ctElement, complexType.nameSpace(), &elems, &groups); for (const Element &elem : std::as_const(elems)) { complexType.addElement(elem); } for (const Group &group : std::as_const(groups)) { complexType.addGroup(group); } } else if (name.localName() == QLatin1String("attribute")) { complexType.addAttribute( parseAttribute(context, ctElement, complexType.nameSpace())); } else if (name.localName() == QLatin1String("anyAttribute")) { addAnyAttribute(context, ctElement, complexType); } else if (name.localName() == QLatin1String("attributeGroup")) { complexType.addAttributeGroups( parseAttributeGroup(context, ctElement, complexType.nameSpace())); } else { qWarning() << "Unsupported content element" << name.localName(); } ctElement = ctElement.nextSiblingElement(); } } } childElement = childElement.nextSiblingElement(); } if (stringToBoolean(element.attribute(QLatin1String("mixed")))) { qDebug(": No support for mixed=true"); } } void Parser::parseSimpleContent(ParserContext *context, const QDomElement &element, ComplexType &complexType) { complexType.setContentModel(XSDType::SIMPLE); QDomElement childElement = element.firstChildElement(); while (!childElement.isNull()) { NSManager namespaceManager(context, childElement); const QName name(childElement.tagName()); if (name.localName() == QLatin1String("restriction")) { SimpleType st(d->mNameSpace); if (childElement.hasAttribute(QLatin1String("base"))) { QName typeName(childElement.attribute(QLatin1String("base"))); typeName.setNameSpace(context->namespaceManager()->uri(typeName.prefix())); st.setBaseTypeName(typeName); } parseRestriction(context, childElement, st); } else if (name.localName() == QLatin1String("extension")) { // This extension does not use the full model that can come in ComplexContent. // It uses the simple model. No particle allowed, only attributes if (childElement.hasAttribute(QLatin1String("base"))) { QName typeName(childElement.attribute(QLatin1String("base"))); typeName.setNameSpace(context->namespaceManager()->uri(typeName.prefix())); complexType.setBaseTypeName(typeName); QDomElement ctElement = childElement.firstChildElement(); while (!ctElement.isNull()) { NSManager namespaceManager(context, ctElement); const QName name(ctElement.tagName()); if (name.localName() == QLatin1String("attribute")) { complexType.addAttribute( parseAttribute(context, ctElement, complexType.nameSpace())); } ctElement = ctElement.nextSiblingElement(); } } } childElement = childElement.nextSiblingElement(); } } void Parser::addGlobalElement(const Element &newElement) { // qDebug() << "Adding global element" << newElement.qualifiedName(); // don't add elements twice bool found = false; for (int i = 0; i < d->mElements.count(); ++i) { if (d->mElements[i].qualifiedName() == newElement.qualifiedName()) { found = true; break; } } if (!found) { d->mElements.append(newElement); } } void Parser::addGlobalAttribute(const Attribute &newAttribute) { // don't add attributes twice bool found = false; for (int i = 0; i < d->mAttributes.count(); ++i) { if (d->mAttributes[i].qualifiedName() == newAttribute.qualifiedName()) { found = true; break; } } if (!found) { d->mAttributes.append(newAttribute); } } AttributeGroup Parser::parseAttributeGroup(ParserContext *context, const QDomElement &element, const QString &nameSpace) { Attribute::List attributes; AttributeGroup group; if (element.hasAttribute(QLatin1String("ref"))) { QName reference(element.attribute(QLatin1String("ref"))); reference.setNameSpace(context->namespaceManager()->uri(reference.prefix())); group.setReference(reference); return group; } for (QDomElement e = element.firstChildElement(); !e.isNull(); e = e.nextSiblingElement()) { QName childName = QName(e.tagName()); if (childName.localName() == QLatin1String("attribute")) { Attribute a = parseAttribute(context, e, nameSpace); addGlobalAttribute(a); attributes.append(a); } } if (!element.hasAttribute(QLatin1String("name"))) { qWarning() << "Attribute Group without reference nor name, invalid XML schema"; } group.setName(element.attribute(QLatin1String("name"))); group.setNameSpace(nameSpace); group.setAttributes(attributes); return group; } // https://www.w3.org/TR/xmlschema-0/#ref17 Group Parser::parseGroup(ParserContext *context, const QDomElement &element, const QString &nameSpace) { Element::List elements; Group group; if (element.hasAttribute(QLatin1String("ref"))) { QName reference(element.attribute(QLatin1String("ref"))); reference.setNameSpace(context->namespaceManager()->uri(reference.prefix())); group.setReference(reference); return group; } for (QDomElement e = element.firstChildElement(); !e.isNull(); e = e.nextSiblingElement()) { QName childName(e.tagName()); const QString localName = childName.localName(); // can contain all, choice or sequence if (localName == QLatin1String("sequence") || localName == QLatin1String("choice")) { parseCompositor(context, e, nameSpace, &elements, nullptr /*can't nest groups*/); } else if (localName == QLatin1String("all")) { qWarning() << "Unsupported element in group:" << localName; // TODO } else { qWarning() << "Unexpected element in group:" << localName; } } const QString name = element.attribute(QLatin1String("name")); Q_ASSERT(!name.isEmpty()); group.setName(name); group.setNameSpace(nameSpace); group.setElements(elements); return group; } QString Parser::targetNamespace() const { return d->mNameSpace; } static QUrl urlForLocation(ParserContext *context, const QString &location) { QUrl url(location); if (url.isRelative() || url.scheme() == QLatin1String("file")) { QDir dir(location); url = context->documentBaseUrl(); return QUrl::fromLocalFile(QDir(url.path()).filePath(location)); } return url; } // Note: https://www.w3.org/TR/xmlschema-0/#schemaLocation paragraph 3 (for ) says // "schemaLocation is only a hint" void Parser::importSchema(ParserContext *context, const QString &location) { // Ignore this one, we don't need it if (location == QLatin1String("http://schemas.xmlsoap.org/wsdl/")) { return; } if (location.startsWith(QLatin1String("urn:"))) { // Can't download that :-) return; } FileProvider provider(d->mUseLocalFilesOnly, d->mImportPathList, d->mLocalSchemas); QString fileName; const QUrl schemaLocation = urlForLocation(context, location); qDebug("importing schema at %s", schemaLocation.toEncoded().constData()); if (provider.get(schemaLocation, fileName)) { QFile file(fileName); if (!file.open(QIODevice::ReadOnly)) { qDebug("Unable to open file %s", qPrintable(file.fileName())); return; } QDomDocument doc(QLatin1String("kwsdl")); QString errorMsg; int errorLine, errorColumn; bool ok = doc.setContent(&file, false, &errorMsg, &errorLine, &errorColumn); if (!ok) { qDebug("Error[%d:%d] %s", errorLine, errorColumn, qPrintable(errorMsg)); return; } QDomElement node = doc.documentElement(); NSManager namespaceManager(context, node); const QName tagName(node.tagName()); if (tagName.localName() == QLatin1String("schema")) { importOrIncludeSchema(context, node, schemaLocation); } else { qDebug("No schema tag found in schema file %s", schemaLocation.toEncoded().constData()); } file.close(); } } // TODO: Try to merge import and include schema // The main difference is that can only // "pull in definitions and declarations from a schema whose // target namespace is the same as the including schema's target namespace" void Parser::includeSchema(ParserContext *context, const QString &location) { FileProvider provider(d->mUseLocalFilesOnly, d->mImportPathList, d->mLocalSchemas); QString fileName; const QUrl schemaLocation = urlForLocation(context, location); qDebug("including schema at %s", schemaLocation.toEncoded().constData()); if (provider.get(schemaLocation, fileName)) { QFile file(fileName); if (!file.open(QIODevice::ReadOnly)) { qDebug("Unable to open file %s", qPrintable(file.fileName())); return; } QDomDocument doc(QLatin1String("kwsdl")); QString errorMsg; int errorLine, errorColumn; bool ok = doc.setContent(&file, false, &errorMsg, &errorLine, &errorColumn); if (!ok) { qDebug("Error[%d:%d] %s", errorLine, errorColumn, qPrintable(errorMsg)); return; } QDomElement node = doc.documentElement(); NSManager namespaceManager(context, node); const QName tagName(node.tagName()); if (tagName.localName() == QLatin1String("schema")) { // For include, targetNamespace must be the same as the current document. if (node.hasAttribute(QLatin1String("targetNamespace"))) { if (node.attribute(QLatin1String("targetNamespace")) != d->mNameSpace) { context->messageHandler()->error( QLatin1String("Included schema must be in the same namespace of the " "resulting schema.")); return; } } importOrIncludeSchema(context, node, schemaLocation); } else { qDebug("No schema tag found in schema file %s", schemaLocation.toEncoded().constData()); } file.close(); } } bool Parser::importOrIncludeSchema(ParserContext *context, const QDomElement &element, const QUrl &schemaLocation) { const QUrl oldBaseUrl = context->documentBaseUrl(); context->setDocumentBaseUrlFromFileUrl(schemaLocation); const bool ret = parseSchemaTag(context, element); context->setDocumentBaseUrl(oldBaseUrl); return ret; } QString Parser::schemaUri() { return XMLSchemaURI; } Element Parser::findElement(const QName &name) const { for (const Element &e : std::as_const(d->mElements)) { if (e.nameSpace() == name.nameSpace() && e.name() == name.localName()) { return e; } } qDebug() << "Element not found:" << name.nameSpace() << name.localName(); return Element(); } Group Parser::findGroup(const QName &name) const { for (const Group &g : std::as_const(d->mGroups)) { if (g.nameSpace() == name.nameSpace() && g.name() == name.localName()) { return g; } } qDebug() << "Group not found:" << name.nameSpace() << name.localName(); return Group(); } Attribute Parser::findAttribute(const QName &name) const { for (const Attribute &attr : std::as_const(d->mAttributes)) { if (attr.nameSpace() == name.nameSpace() && attr.name() == name.localName()) { return attr; } } qDebug() << "Attribute not found:" << name.nameSpace() << name.localName(); return Attribute(); } AttributeGroup Parser::findAttributeGroup(const QName &name) const { for (const AttributeGroup &g : std::as_const(d->mAttributeGroups)) { if (g.nameSpace() == name.nameSpace() && g.name() == name.localName()) { return g; } } qDebug() << "Attribute Group not found:" << name.nameSpace() << name.localName(); return AttributeGroup(); } bool Parser::resolveForwardDeclarations() { const QName any(QLatin1String("http://www.w3.org/2001/XMLSchema"), QLatin1String("any")); // const QName anyType( "http://www.w3.org/2001/XMLSchema", "anyType" ); for (int i = 0; i < d->mComplexTypes.count(); ++i) { ComplexType &complexType = d->mComplexTypes[i]; Element::List elements = complexType.elements(); // qDebug() << i << "looking at" << complexType << " " << elements.count() << "elements"; Element::List finalElementList; for (int j = 0; j < elements.count(); ++j) { Element element = elements.at(j); // qDebug() << " " << element; if (!element.isResolved()) { Element resolvedElement = findElement(element.reference()); if (resolvedElement.qualifiedName().isEmpty()) { qWarning("ERROR in %s: resolving element ref to '%s': not found!", qPrintable(complexType.qualifiedName().qname()), qPrintable(element.reference().qname())); if (qEnvironmentVariableIsSet("LIBKODE_VERBOSE_ERRORS")) { d->mElements.dump(); } else { qWarning() << "Set the environment variable LIBKODE_VERBOSE_ERRORS to see " "the list of all available elements"; } return false; } else { resolvedElement.setMinOccurs(element.minOccurs()); resolvedElement.setMaxOccurs(element.maxOccurs()); resolvedElement.setCompositor(element.compositor()); element = resolvedElement; } } if (j > 0 && finalElementList.last().type() == any) { if (element.type() == any) { // Keep only one any. The alternative would be to implement namespace // "filtering"... // qWarning("ERROR: two 'any' values in the same type %s", // qPrintable(d->mComplexTypes[i].name())); return false; continue; } // Hack for deserialization: keep "any" last. Element lastElem = finalElementList.takeLast(); finalElementList.append(element); finalElementList.append(lastElem); } else { finalElementList.append(element); } } const auto groups = complexType.groups(); for (const Group &group : groups) { if (!group.isResolved()) { const Group refGroup = findGroup(group.reference()); if (!refGroup.isNull()) { // qDebug() << " resolved group" << group.reference() << "got these elements" // << refGroup.elements(); const auto elements = refGroup.elements(); for (const Element &elem : elements) { Q_ASSERT(!elem.type().isEmpty()); finalElementList.append(elem); } // qDebug() << " finalElementList" << finalElementList; } } } // groups were resolved, don't do it again if resolveForwardDeclarations() is called again complexType.setGroups(Group::List()); complexType.setElements(finalElementList); Attribute::List attributes = complexType.attributes(); for (int j = 0; j < attributes.count(); ++j) { const Attribute &attribute = attributes.at(j); if (!attribute.isResolved()) { Attribute refAttribute = findAttribute(attribute.reference()); if (refAttribute.qualifiedName().isEmpty()) { qWarning("ERROR in %s: resolving attribute ref to '%s': not found!", qPrintable(d->mComplexTypes[i].qualifiedName().qname()), qPrintable(attribute.reference().qname())); if (qEnvironmentVariableIsSet("LIBKODE_VERBOSE_ERRORS")) { d->mAttributes.dump(); } else { qWarning() << "Set the environment variable LIBKODE_VERBOSE_ERRORS to see " "the list of all available attributes"; } return false; } else { attributes[j] = refAttribute; } } } const auto attributeGroups = complexType.attributeGroups(); for (const AttributeGroup &group : attributeGroups) { Q_ASSERT(!group.reference().isEmpty()); AttributeGroup refAttributeGroup = findAttributeGroup(group.reference()); Attribute::List groupAttributes = refAttributeGroup.attributes(); for (const Attribute &ga : std::as_const(groupAttributes)) { attributes.append(ga); } } // groups were resolved, don't do it again if resolveForwardDeclarations() is called again complexType.setAttributeGroups(AttributeGroup::List()); complexType.setAttributes(attributes); } return true; } Types Parser::types() const { Types types; types.setSimpleTypes(d->mSimpleTypes); types.setComplexTypes(d->mComplexTypes); // qDebug() << "Parser::types: elements:"; // d->mElements.dump(); types.setElements(d->mElements); // types.setGroups( d->mGroups ); types.setAttributes(d->mAttributes); // types.setAttributeGroups( d->mAttributeGroups ); return types; } Annotation::List Parser::annotations() const { return d->mAnnotations; } bool Parser::parse(ParserContext *context, QIODevice *sourceDevice) { QDomDocument document(QLatin1String("KWSDL")); QString errorMsg; int errorLine, errorCol; QDomDocument doc; if (!doc.setContent(sourceDevice, false, &errorMsg, &errorLine, &errorCol)) { qDebug("%s at (%d,%d)", qPrintable(errorMsg), errorLine, errorCol); return false; } QDomElement element = doc.documentElement(); const QName name = element.tagName(); if (name.localName() != QLatin1String("schema")) { qDebug("document element is '%s'", qPrintable(element.tagName())); return false; } return parseSchemaTag(context, element); } bool Parser::parseFile(ParserContext *context, QFile &file) { return parse(context, &file); } bool Parser::parseString(ParserContext *context, const QByteArray &data) { QBuffer buffer; buffer.setData(data); return parse(context, &buffer); } } // end namespace XSD libkode-master/schema/parser.h000066400000000000000000000133111472623201100166620ustar00rootroot00000000000000/* This file is part of KDE Schema Parser Copyright (c) 2005 Tobias Koenig Copyright (c) 2006 MichaĆ«l Larouche based on wsdlpull parser by Vivek Krishna This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef SCHEMA_PARSER_H #define SCHEMA_PARSER_H #include #include #include #include #include "types.h" #include "annotation.h" #include QT_BEGIN_NAMESPACE class QUrl; QT_END_NAMESPACE class ParserContext; Q_DECLARE_LOGGING_CATEGORY(parser) namespace XSD { class SCHEMA_EXPORT Parser { public: enum { UNBOUNDED = 100000 }; explicit Parser(ParserContext *context, const QString &nameSpace = QString(), bool useLocalFilesOnly = false, const QStringList &includePathList = QStringList()); explicit Parser(const QString &nameSpace = QString()); Parser(const Parser &other); Parser(Parser &&other); ~Parser(); Parser &operator=(const Parser &other); Parser &operator=(Parser &&other) noexcept; /** * Configures the parser to use some local files instead of downloading specific schemas. * @param localSchemas a map where the key is the schema URI and the value is the local path * The local path can start with :/ to use the Qt resource system. */ void setLocalSchemas(const QMap &localSchemas); Types types() const; Annotation::List annotations() const; bool parseString(ParserContext *context, const QByteArray &data); bool parseFile(ParserContext *context, QFile &file); bool parseSchemaTag(ParserContext *context, const QDomElement &element); QString targetNamespace() const; /** * Resolve all references for elements and attributes * @return false if one of references has no declaration (error) */ bool resolveForwardDeclarations(); /** Returns the default schema URI. */ static QString schemaUri(); private: bool parse(ParserContext *context, QIODevice *sourceDevice); void parseImport(ParserContext *context, const QDomElement &); /** * @brief Parse include element. * The element must include a external schema within the same target namespace * of the current document. Use if you want to refer to a external namespace. * @param context Current parser context. * @param element DOM element to parse. */ void parseInclude(ParserContext *context, const QDomElement &element); void addGlobalElement(const Element &); void addGlobalAttribute(const Attribute &); AttributeGroup parseAttributeGroup(ParserContext *context, const QDomElement &, const QString &nameSpace); Group parseGroup(ParserContext *context, const QDomElement &, const QString &nameSpace); Annotation::List parseAnnotation(ParserContext *context, const QDomElement &); ComplexType parseComplexType(ParserContext *context, const QDomElement &); void all(ParserContext *context, const QDomElement &, ComplexType &); void parseCompositor(ParserContext *context, const QDomElement &element, const QString &nameSpace, Element::List *elements, Group::List *groups); void setOccurrenceAttributes(Element &newElement, const QDomElement &element); Element parseElement(ParserContext *context, const QDomElement &, const QString &nameSpace, const QDomElement &occurrenceElement); void setSubstitutionElementName(const QName &typeName, const QName &elemName); Attribute parseAttribute(ParserContext *context, const QDomElement &, const QString &nameSpace); Element parseAny(ParserContext *context, const QDomElement &, const QString &nameSpace); void addAnyAttribute(ParserContext *context, const QDomElement &, ComplexType &); SimpleType parseSimpleType(ParserContext *context, const QDomElement &); void parseRestriction(ParserContext *context, const QDomElement &, SimpleType &); void parseComplexContent(ParserContext *context, const QDomElement &, ComplexType &); void parseSimpleContent(ParserContext *context, const QDomElement &, ComplexType &); void importSchema(ParserContext *context, const QString &location); /** * @brief Read and include the given schema into the current schema. * @param context Current parser context. * @param location Schema location. */ void includeSchema(ParserContext *context, const QString &location); bool importOrIncludeSchema(ParserContext *context, const QDomElement &element, const QUrl &schemaLocation); Element findElement(const QName &name) const; Group findGroup(const QName &name) const; Attribute findAttribute(const QName &name) const; AttributeGroup findAttributeGroup(const QName &name) const; void init(ParserContext *context); void clear(); class Private; std::unique_ptr d; }; } #endif libkode-master/schema/schema.pri000066400000000000000000000011021472623201100171640ustar00rootroot00000000000000QT += xml HEADERS += \ $$PWD/annotation.h \ $$PWD/attribute.h \ $$PWD/attributegroup.h \ $$PWD/complextype.h \ $$PWD/compositor.h \ $$PWD/element.h \ $$PWD/group.h \ $$PWD/parser.h \ $$PWD/simpletype.h \ $$PWD/types.h \ $$PWD/xmlelement.h \ $$PWD/xsdtype.h SOURCES += \ $$PWD/annotation.cpp \ $$PWD/attribute.cpp \ $$PWD/attributegroup.cpp \ $$PWD/complextype.cpp \ $$PWD/compositor.cpp \ $$PWD/element.cpp \ $$PWD/group.cpp \ $$PWD/parser.cpp \ $$PWD/simpletype.cpp \ $$PWD/types.cpp \ $$PWD/xmlelement.cpp \ $$PWD/xsdtype.cpp libkode-master/schema/schema.pro000066400000000000000000000004271472623201100172030ustar00rootroot00000000000000TEMPLATE = lib TARGET = xmlschema CONFIG += staticlib include(schema.pri) QT -= gui QT += xml INCLUDEPATH += $${PWD}/.. $${PWD}/../code_generation include($${PWD}/../variables.pri) DEFINES -= QT_NO_CAST_TO_ASCII QBA_NO_CAST_TO_VOID QBA_NO_CAST_TO_ASCII QT_NO_CAST_FROM_ASCII libkode-master/schema/schematest.cpp000066400000000000000000000062301472623201100200630ustar00rootroot00000000000000#include #include #include #include #include #include int main(int argc, char **argv) { if (argc != 2) { qDebug("Missing argument: filename of schema"); return 1; } QString filename = argv[1]; QFile file(filename); if (!file.open(QIODevice::ReadOnly)) { qDebug("Can't open file %s", qPrintable(file.fileName())); return 1; } NSManager namespaceManager; MessageHandler messageHandler; ParserContext context; context.setNamespaceManager(&namespaceManager); context.setMessageHandler(&messageHandler); XSD::Parser parser; if (!parser.parseFile(&context, file)) { qDebug() << "Error parsing file " << filename; return 1; } XSD::Types types = parser.types(); const XSD::SimpleType::List simpleTypes = types.simpleTypes(); for (int i = 0; i < simpleTypes.count(); ++i) { XSD::SimpleType t = simpleTypes[i]; qDebug() << "SimpleType: " << t.name() << t.baseTypeName().qname() << t.subType(); qDebug() << "FacetType: " << t.facetType(); if (t.facetType() == XSD::SimpleType::ENUM) { qDebug() << " ENUMS " << t.facetEnums(); } } const XSD::ComplexType::List complexTypes = types.complexTypes(); for (int i = 0; i < complexTypes.count(); ++i) { qDebug("ComplexType: %s %s", qPrintable(complexTypes[i].name()), qPrintable(complexTypes[i].baseTypeName().qname())); const XSD::Element::List elements = complexTypes[i].elements(); for (int j = 0; j < elements.count(); ++j) { qDebug("\tElement: %s %s", qPrintable(elements[j].name()), qPrintable(elements[j].type().qname())); } const XSD::Attribute::List attributes = complexTypes[i].attributes(); for (int j = 0; j < attributes.count(); ++j) { qDebug("\tAttribute: %s %s", qPrintable(attributes[j].name()), qPrintable(attributes[j].type().qname())); } } const XSD::Element::List elements = types.elements(); for (int i = 0; i < elements.count(); ++i) { qDebug("Element: %s %s", qPrintable(elements[i].name()), qPrintable(elements[i].type().qname())); const auto annotations = elements[i].annotations(); for (const XSD::Annotation &a : annotations) { qDebug() << " Annotation:" << a.domElement().tagName(); } } const XSD::Attribute::List attributes = types.attributes(); for (int i = 0; i < attributes.count(); ++i) { qDebug("Attribute: %s %s", qPrintable(attributes[i].name()), qPrintable(attributes[i].type().qname())); } const XSD::AttributeGroup::List attributeGroups = types.attributeGroups(); for (int i = 0; i < attributeGroups.count(); ++i) { qDebug("AttributeGroup: %s", qPrintable(attributeGroups[i].name())); } const auto parserAnnotations = parser.annotations(); for (const XSD::Annotation &a : parserAnnotations) { qDebug() << "Annotation:" << a.domElement().tagName(); } return 0; } libkode-master/schema/simpletype.cpp000066400000000000000000000200361472623201100201160ustar00rootroot00000000000000/* This file is part of KDE Schema Parser Copyright (c) 2005 Tobias Koenig based on wsdlpull parser by Vivek Krishna This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "simpletype.h" #include namespace XSD { class SimpleType::Private { public: Private() : mFacetId(NONE), mAnonymous(false), mSubType(TypeRestriction) {} QString mDocumentation; QName mBaseTypeName; int mFacetId; bool mAnonymous; QStringList mEnums; SubType mSubType; QName mListTypeName; struct FacetValueType { FacetValueType() : length(0), wsp(PRESERVE), tot(0), frac(0) {} int length; struct LenRange { LenRange() : minlen(-1), maxlen(-1) {} int minlen, maxlen; } lenRange; WhiteSpaceType wsp; struct ValueRange { ValueRange() : maxinc(-1), mininc(-1), maxex(-1), minex(-1) {} int maxinc, mininc, maxex, minex; } valRange; int tot; int frac; QString pattern; }; FacetValueType mFacetValue; QString mElementName; }; SimpleType::SimpleType() : XSDType(), d(new Private) {} SimpleType::SimpleType(const QString &nameSpace) : XSDType(nameSpace), d(new Private) {} SimpleType::SimpleType(const SimpleType &other) : XSDType(other), d(new Private) { *d = *other.d; } SimpleType::SimpleType(SimpleType &&other) : XSDType(other), d(std::move(other.d)) {} SimpleType::~SimpleType() = default; SimpleType &SimpleType::operator=(const SimpleType &other) { if (this == &other) { return *this; } *d = *other.d; XSDType::operator=(other); return *this; } SimpleType &SimpleType::operator=(SimpleType &&other) noexcept = default; void SimpleType::setDocumentation(const QString &documentation) { d->mDocumentation = documentation; } QString SimpleType::documentation() const { return d->mDocumentation; } void SimpleType::setBaseTypeName(const QName &baseTypeName) { d->mBaseTypeName = baseTypeName; } QName SimpleType::baseTypeName() const { return d->mBaseTypeName; } void SimpleType::setSubType(SubType subType) { d->mSubType = subType; } SimpleType::SubType SimpleType::subType() const { return d->mSubType; } void SimpleType::setListTypeName(const QName &name) { d->mListTypeName = name; } QName SimpleType::listTypeName() const { return d->mListTypeName; } void SimpleType::setAnonymous(bool anonymous) { d->mAnonymous = anonymous; } bool SimpleType::isAnonymous() const { return d->mAnonymous; } SimpleType::FacetType SimpleType::parseFacetId(const QString &facet) const { if (d->mBaseTypeName.isEmpty()) { qDebug("parseFacetId: Unknown base type"); return NONE; } if (facet == QLatin1String("length")) { return LENGTH; } else if (facet == QLatin1String("minLength")) { return MINLEN; } else if (facet == QLatin1String("maxLength")) { return MAXLEN; } else if (facet == QLatin1String("enumeration")) { return ENUM; } else if (facet == QLatin1String("whiteSpace")) { return WSP; } else if (facet == QLatin1String("pattern")) { return PATTERN; } else if (facet == QLatin1String("maxInclusive")) { return MAXINC; } else if (facet == QLatin1String("maxExclusive")) { return MAXEX; } else if (facet == QLatin1String("minInclusive")) { return MININC; } else if (facet == QLatin1String("minExclusive")) { return MINEX; } else if (facet == QLatin1String("totalDigits")) { return TOT; } else if (facet == QLatin1String("fractionDigits")) { return FRAC; } else { qDebug("Unknown facet: %s", qPrintable(facet)); return NONE; } } void SimpleType::setFacetValue(FacetType ft, const QString &value) { d->mFacetId |= ft; if (ft == ENUM) { d->mEnums.append(value); } else if (ft == PATTERN) { d->mFacetValue.pattern = value; } else if (ft == WSP) { if (value == QLatin1String("preserve")) { d->mFacetValue.wsp = PRESERVE; } else if (value == QLatin1String("collapse")) { d->mFacetValue.wsp = COLLAPSE; } else if (value == QLatin1String("replace")) { d->mFacetValue.wsp = REPLACE; } else { qDebug("Invalid facet value for whitespace"); return; } } else { const int number = value.toInt(); if (ft == MAXEX) { d->mFacetValue.valRange.maxex = number; } else if (ft == MAXINC) { d->mFacetValue.valRange.maxinc = number; } else if (ft == MININC) { d->mFacetValue.valRange.mininc = number; } else if (ft == MINEX) { d->mFacetValue.valRange.minex = number; } else if (ft == LENGTH) { d->mFacetValue.length = number; } else if (ft == MINLEN) { d->mFacetValue.lenRange.minlen = number; } else if (ft == MAXLEN) { d->mFacetValue.lenRange.maxlen = number; } else if (ft == TOT) { d->mFacetValue.tot = number; } else if (ft == FRAC) { d->mFacetValue.frac = number; } } } int SimpleType::facetType() const { return d->mFacetId; } int SimpleType::facetLength() const { return d->mFacetValue.length; } int SimpleType::facetMinimumLength() const { return d->mFacetValue.lenRange.minlen; } int SimpleType::facetMaximumLength() const { return d->mFacetValue.lenRange.maxlen; } QStringList SimpleType::facetEnums() const { return d->mEnums; } SimpleType::WhiteSpaceType SimpleType::facetWhiteSpace() const { return d->mFacetValue.wsp; } int SimpleType::facetMinimumInclusive() const { return d->mFacetValue.valRange.mininc; } int SimpleType::facetMaximumInclusive() const { return d->mFacetValue.valRange.maxinc; } int SimpleType::facetMinimumExclusive() const { return d->mFacetValue.valRange.minex; } int SimpleType::facetMaximumExclusive() const { return d->mFacetValue.valRange.maxex; } int SimpleType::facetTotalDigits() const { return d->mFacetValue.tot; } int SimpleType::facetFractionDigits() const { return d->mFacetValue.frac; } QString SimpleType::facetPattern() const { return d->mFacetValue.pattern; } bool SimpleType::isRestriction() const { static QName XmlAnyType(QLatin1String("http://www.w3.org/2001/XMLSchema"), QLatin1String("any")); return d->mSubType == TypeRestriction && d->mBaseTypeName != XmlAnyType && !d->mBaseTypeName.isEmpty() && !(d->mFacetId & ENUM); } SimpleType SimpleTypeList::simpleType(const QName &qualifiedName) const { const_iterator it = constBegin(); for (; it != constEnd(); ++it) if ((*it).qualifiedName() == qualifiedName) { return *it; } // qDebug() << "Simple type" << qualifiedName << "not found"; return SimpleType(); } SimpleTypeList::iterator SimpleTypeList::findSimpleType(const QName &qualifiedName) { for (iterator it = begin(); it != end(); ++it) if ((*it).qualifiedName() == qualifiedName) { return it; } return end(); } QString SimpleType::elementName() const { return d->mElementName; } void SimpleType::setElementName(const QString &elementName) { d->mElementName = elementName; } } // end namespace XSD libkode-master/schema/simpletype.h000066400000000000000000000067541472623201100175760ustar00rootroot00000000000000/* This file is part of KDE Schema Parser Copyright (c) 2005 Tobias Koenig based on wsdlpull parser by Vivek Krishna This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef SCHEMA_SIMPLETYPE_H #define SCHEMA_SIMPLETYPE_H #include #include #include "xsdtype.h" #include namespace XSD { class SimpleTypeList; class SCHEMA_EXPORT SimpleType : public XSDType { public: typedef SimpleTypeList List; enum FacetType { NONE = 0, LENGTH = 1, MINLEN = 2, MAXLEN = 4, ENUM = 8, WSP = 16, MAXINC = 32, MININC = 64, MAXEX = 128, MINEX = 256, TOT = 512, FRAC = 1024, PATTERN = 2048 }; enum WhiteSpaceType { PRESERVE, REPLACE, COLLAPSE }; enum SubType { TypeRestriction, TypeList, TypeUnion }; SimpleType(); explicit SimpleType(const QString &nameSpace); SimpleType(const SimpleType &other); SimpleType(SimpleType &&other); ~SimpleType(); SimpleType &operator=(const SimpleType &other); SimpleType &operator=(SimpleType &&other) noexcept; void setDocumentation(const QString &documentation); QString documentation() const; void setBaseTypeName(const QName &baseTypeName); QName baseTypeName() const; void setSubType(SubType subType); SubType subType() const; void setListTypeName(const QName &name); QName listTypeName() const; void setAnonymous(bool anonymous); bool isAnonymous() const; FacetType parseFacetId(const QString &facet) const; void setFacetValue(FacetType ft, const QString &value); int facetType() const; int facetLength() const; int facetMinimumLength() const; int facetMaximumLength() const; QStringList facetEnums() const; WhiteSpaceType facetWhiteSpace() const; int facetMinimumInclusive() const; int facetMaximumInclusive() const; int facetMinimumExclusive() const; int facetMaximumExclusive() const; int facetTotalDigits() const; int facetFractionDigits() const; QString facetPattern() const; /** * Return true if this type is just a restriction of another type. * False for enums, and false if the base type is any. */ bool isRestriction() const; QString elementName() const; void setElementName(const QString &elementName); private: class Private; std::unique_ptr d; }; class SCHEMA_EXPORT SimpleTypeList : public QList { public: // Readonly lookup, returns null type if not found SimpleType simpleType(const QName &qualifiedName) const; // Mutable lookup (for making changes), returns end() if not found iterator findSimpleType(const QName &qualifiedName); }; } #endif libkode-master/schema/types.cpp000066400000000000000000000077641472623201100171040ustar00rootroot00000000000000/* This file is part of KDE Schema Parser Copyright (c) 2005 Tobias Koenig This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "types.h" #include namespace XSD { class Types::Private { public: SimpleType::List mSimpleTypes; ComplexType::List mComplexTypes; Element::List mElements; Attribute::List mAttributes; #if 0 AttributeGroup::List mAttributeGroups; Group::List mGroups; #endif }; Types::Types() : d(new Private) {} Types::Types(const Types &other) : d(new Private) { *d = *other.d; } Types::Types(Types &&other) : d(std::move(other.d)) {} Types::~Types() = default; Types &Types::operator=(const Types &other) { if (this == &other) { return *this; } *d = *other.d; return *this; } Types &Types::operator=(Types &&other) noexcept = default; Types &Types::operator+=(const Types &other) { if (this == &other) { return *this; } d->mSimpleTypes += other.d->mSimpleTypes; d->mComplexTypes += other.d->mComplexTypes; d->mElements += other.d->mElements; d->mAttributes += other.d->mAttributes; // unused d->mAttributeGroups += other.d->mAttributeGroups; // unused d->mGroups += other.d->mGroups; return *this; } void Types::setSimpleTypes(const SimpleType::List &simpleTypes) { d->mSimpleTypes = simpleTypes; } SimpleType::List Types::simpleTypes() const { return d->mSimpleTypes; } void Types::setComplexTypes(const ComplexType::List &complexTypes) { d->mComplexTypes = complexTypes; } ComplexType::List Types::complexTypes() const { return d->mComplexTypes; } void Types::setElements(const Element::List &elements) { d->mElements = elements; } Element::List Types::elements() const { return d->mElements; } void Types::setAttributes(const Attribute::List &attributes) { d->mAttributes = attributes; } Attribute::List Types::attributes() const { return d->mAttributes; } #if 0 void Types::setAttributeGroups(const AttributeGroup::List &attributeGroups) { d->mAttributeGroups = attributeGroups; } AttributeGroup::List Types::attributeGroups() const { return d->mAttributeGroups; } void Types::setGroups(const Group::List &groups) { d->mGroups = groups; } Group::List Types::groups() const { return d->mGroups; } #endif ComplexType Types::complexType(const Element &element) const { return complexType(element.type()); } ComplexType Types::complexType(const QName &typeName) const { return d->mComplexTypes.complexType(typeName); } ComplexType Types::polymorphicBaseClass(const ComplexType &derivedType) const { if (derivedType.isPolymorphicBaseClass()) { return derivedType; } ComplexType base = complexType(derivedType.baseTypeName()); if (!base.isNull()) { return polymorphicBaseClass(base); // recurse } return ComplexType(); } SimpleType Types::simpleType(const QName &simpleTypeName, const QString &elementFilter) const { if (elementFilter.isEmpty()) return d->mSimpleTypes.simpleType(simpleTypeName); for (auto type : std::as_const(d->mSimpleTypes)) { if (type.qualifiedName() == simpleTypeName && elementFilter == type.elementName()) return type; } qDebug() << "Simple type not found"; return SimpleType(); } } // namespace XSD libkode-master/schema/types.h000066400000000000000000000046651472623201100165460ustar00rootroot00000000000000/* This file is part of KDE Schema Parser Copyright (c) 2005 Tobias Koenig This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef SCHEMA_TYPES_H #define SCHEMA_TYPES_H #include "complextype.h" #include "element.h" #include "simpletype.h" #include namespace XSD { class SCHEMA_EXPORT Types { public: Types(); Types(const Types &other); Types(Types &&other); ~Types(); Types &operator=(const Types &other); Types &operator=(Types &&other) noexcept; Types &operator+=(const Types &other); void setSimpleTypes(const SimpleType::List &simpleTypes); SimpleType::List simpleTypes() const; void setComplexTypes(const ComplexType::List &complexTypes); ComplexType::List complexTypes() const; void setElements(const Element::List &elements); Element::List elements() const; void setAttributes(const Attribute::List &attributes); Attribute::List attributes() const; // unused void setAttributeGroups( const AttributeGroup::List &attributeGroups ); // unused AttributeGroup::List attributeGroups() const; // unused void setGroups( const Group::List &groups ); // unused Group::List groups() const; ComplexType complexType(const Element &) const; ComplexType complexType(const QName &) const; // Call this with derived complex type, to find the root of the hierarchy, // i.e. the type for which isPolymorphicBaseClass() returns true ComplexType polymorphicBaseClass(const ComplexType &derivedType) const; SimpleType simpleType(const QName &simpleTypeName, const QString &elementFilter = QString()) const; private: class Private; std::unique_ptr d; }; } #endif libkode-master/schema/xmlelement.cpp000066400000000000000000000051501472623201100200750ustar00rootroot00000000000000/* This file is part of KDE Schema Parser Copyright (c) 2005 Tobias Koenig This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "xmlelement.h" namespace XSD { class XmlElement::Private { public: QString mName; QString mNameSpace; Annotation::List mAnnotations; bool operator==(const XmlElement::Private &other) const { return mName == other.mName && mNameSpace == other.mNameSpace; } inline bool operator!=(const XmlElement::Private &other) const { return !(*this == other); } }; XmlElement::XmlElement() : d(new Private) {} XmlElement::XmlElement(const QString &nameSpace) : d(new Private) { d->mNameSpace = nameSpace; } XmlElement::XmlElement(const XmlElement &other) : d(new Private) { *d = *other.d; } XmlElement::XmlElement(XmlElement &&other) : d(std::move(other.d)) {} XmlElement::~XmlElement() = default; XmlElement &XmlElement::operator=(const XmlElement &other) { if (this == &other) { return *this; } *d = *other.d; return *this; } XmlElement &XmlElement::operator=(XmlElement &&other) noexcept = default; bool XmlElement::isNull() const { return d->mName.isEmpty(); } void XmlElement::setName(const QString &name) { d->mName = name; } QString XmlElement::name() const { return d->mName; } void XmlElement::setNameSpace(const QString &nameSpace) { d->mNameSpace = nameSpace; } QString XmlElement::nameSpace() const { return d->mNameSpace; } QName XmlElement::qualifiedName() const { return QName(d->mNameSpace, d->mName); } void XmlElement::addAnnotation(const Annotation &a) { d->mAnnotations.append(a); } void XmlElement::setAnnotations(const Annotation::List &l) { d->mAnnotations = l; } Annotation::List XmlElement::annotations() const { return d->mAnnotations; } bool XmlElement::operator==(const XmlElement &other) const { return *d == *other.d; } } libkode-master/schema/xmlelement.h000066400000000000000000000036311472623201100175440ustar00rootroot00000000000000/* This file is part of KDE Schema Parser Copyright (c) 2005 Tobias Koenig This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef XMLELEMENT_H #define XMLELEMENT_H #include "annotation.h" #include #include #include #include namespace XSD { class SCHEMA_EXPORT XmlElement { public: XmlElement(); explicit XmlElement(const QString &nameSpace); XmlElement(const XmlElement &other); XmlElement(XmlElement &&other); virtual ~XmlElement(); XmlElement &operator=(const XmlElement &other); XmlElement &operator=(XmlElement &&other) noexcept; bool isNull() const; void setName(const QString &name); QString name() const; void setNameSpace(const QString &nameSpace); QString nameSpace() const; QName qualifiedName() const; void addAnnotation(const Annotation &); void setAnnotations(const Annotation::List &); Annotation::List annotations() const; bool operator==(const XmlElement &other) const; inline bool operator!=(const XmlElement &other) const { return !(*this == other); } private: class Private; std::unique_ptr d; }; } #endif libkode-master/schema/xsdtype.cpp000066400000000000000000000045231472623201100174260ustar00rootroot00000000000000/* This file is part of KDE Schema Parser Copyright (c) 2005 Tobias Koenig based on wsdlpull parser by Vivek Krishna This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "xsdtype.h" namespace XSD { class XSDType::Private { public: Private() : mContentModel(SIMPLE), mSubstitutionElementName() {} ContentModel mContentModel; QName mSubstitutionElementName; }; XSDType::XSDType() : XmlElement(), d(new Private) {} XSDType::XSDType(const QString &nameSpace) : XmlElement(nameSpace), d(new Private) {} XSDType::XSDType(const XSDType &other) : XmlElement(other), d(new Private) { *d = *other.d; } XSDType::XSDType(XSDType &&other) : XmlElement(other), d(std::move(other.d)) {} XSDType::~XSDType() = default; XSDType &XSDType::operator=(const XSDType &other) { if (this == &other) { return *this; } XmlElement::operator=(other); *d = *other.d; return *this; } XSDType &XSDType::operator=(XSDType &&other) noexcept = default; void XSDType::setContentModel(ContentModel contentModel) { d->mContentModel = contentModel; } XSDType::ContentModel XSDType::contentModel() const { return d->mContentModel; } void XSDType::setSubstitutionElementName(const QName &name) { d->mSubstitutionElementName = name; } QName XSDType::substitutionElementName() const { return d->mSubstitutionElementName; } bool XSDType::operator==(const XSDType &other) const { return (XmlElement::operator==(other) && contentModel() == other.contentModel() && substitutionElementName() == other.substitutionElementName()); } } // namespace XSD libkode-master/schema/xsdtype.h000066400000000000000000000056721472623201100171010ustar00rootroot00000000000000/* This file is part of KDE Schema Parser Copyright (c) 2005 Tobias Koenig based on wsdlpull parser by Vivek Krishna This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef SCHEMA_XSDTYPE_H #define SCHEMA_XSDTYPE_H #include #include #include #include #include #include "xmlelement.h" namespace XSD { class SCHEMA_EXPORT XSDType : public XmlElement { public: typedef QList List; enum ContentModel { SIMPLE = 0, COMPLEX, MIXED }; /* enum { INVALID = 0, STRING = 1, INTEGER, INT, BYTE, UBYTE, POSINT, UINT, LONG, ULONG, SHORT, USHORT, DECIMAL, FLOAT, DOUBLE, BOOLEAN, TIME, DATETIME, DATE, TOKEN, QNAME, NCNAME, NMTOKEN, NMTOKENS, BASE64BIN, HEXBIN, ANY, ANYTYPE, ANYURI }; */ XSDType(); explicit XSDType(const QString &); XSDType(const XSDType &other); XSDType(XSDType &&other); ~XSDType() override; XSDType &operator=(XSDType &&other) noexcept; XSDType &operator=(const XSDType &other); void setContentModel(ContentModel contentModel); ContentModel contentModel() const; /** * Sets the name of the substitution element associated with this type. * * Example: will set the element name to "FieldURI" in the type * "PathToUnindexedFieldType". * * @param name element name */ void setSubstitutionElementName(const QName &name); /** * @return the substitution element name associated with this type, if any. */ QName substitutionElementName() const; virtual bool isSimple() const { return true; } bool operator==(const XSDType &other) const; inline bool operator!=(const XSDType &other) const { return !(*this == other); } private: class Private; std::unique_ptr d; }; } #endif libkode-master/variables.pri000066400000000000000000000020631472623201100164430ustar00rootroot00000000000000CONFIG += qt warn_on exists( g++.pri ):include( g++.pri ) DEFINES += USE_EXCEPTIONS QT_FATAL_ASSERT DEFINES += QT_NO_CAST_TO_ASCII QT_NO_CAST_FROM_ASCII QT_NO_CAST_FROM_BYTEARRAY solaris-cc:DEFINES += SUN7 # for C++11 support mac: QMAKE_CXXFLAGS += -stdlib=libc++ win32-msvc*:DEFINES += _SCL_SECURE_NO_WARNINGS win32-msvc*:QMAKE_CXXFLAGS += /GR /EHsc /wd4251 unix:!macx:QMAKE_LFLAGS += -Wl,-no-undefined macx:QMAKE_SONAME_PREFIX = @rpath CONFIG += depend_includepath QT += network contains(TEMPLATE, lib) { DESTDIR = $${TOP_BUILD_DIR}/lib } contains(TEMPLATE, app) { DESTDIR = $${TOP_BUILD_DIR}/bin } staticlib { } else { contains(TEMPLATE, lib) { win32 { DLLDESTDIR = $${TOP_BUILD_DIR}/bin CONFIG += dll #skip_target_version_ext was introduced in Qt5.3 so we can't use it for Qt4.8 builds #so fallback to setting the empty VERSION trick. VERSION= # CONFIG += skip_target_version_ext } } } unix:!symbian { MOC_DIR = .moc OBJECTS_DIR = .obj UI_DIR = .ui } else { MOC_DIR = _moc OBJECTS_DIR = _obj UI_DIR = _ui }